From a532f5010403f105535ee51ae9357029bd5d83e4 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 13:39:32 +0900 Subject: [PATCH 01/17] Added new events to fs module --- .../src/main/scala/io/scalajs/nodejs/fs/FSWatcher.scala | 7 +++++++ .../src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala | 7 +++++++ .../src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/fs/FSWatcher.scala b/app/current/src/main/scala/io/scalajs/nodejs/fs/FSWatcher.scala index 10c0797dd..23073e4be 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/fs/FSWatcher.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/fs/FSWatcher.scala @@ -45,6 +45,13 @@ object FSWatcher { @inline def onChange(listener: (String, js.Any) => Any): watcher.type = watcher.on("change", listener) + /** + * Added in Node.js v10.0.0 + * @see https://nodejs.org/api/fs.html#fs_event_close + */ + @inline + def onClose(listener: () => Any): watcher.type = watcher.on("close", listener) + /** * Emitted when an error occurs. * @param listener the event handler diff --git a/app/current/src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala b/app/current/src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala index 6a2a9e090..03e160298 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala @@ -76,6 +76,13 @@ object ReadStream { */ @inline def onOpen(listener: FileDescriptor => Any): stream.type = stream.on("open", listener) + + /** + * Added in Node.js v9.11.0 + * @see https://nodejs.org/api/fs.html#fs_event_ready + */ + @inline + def onReady(listener: () => Any): stream.type = stream.on("ready", listener) } /** diff --git a/app/current/src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala b/app/current/src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala index bfca6c673..1b5c6db11 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala @@ -72,6 +72,13 @@ object WriteStream { */ @inline def onOpen(listener: FileDescriptor => Any): stream.type = stream.on("open", listener) + + /** + * Added in Node.js v9.11.0 + * @see https://nodejs.org/api/fs.html#fs_event_ready_1 + */ + @inline + def onReady(listener: () => Any): stream.type = stream.on("ready", listener) } /** From 7283adb4c491c5476ccfa0f86e305d375c7b179e Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 14:15:10 +0900 Subject: [PATCH 02/17] Added new events child_process module --- .../io/scalajs/nodejs/child_process/package.scala | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/child_process/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/child_process/package.scala index 3605f6960..9eae73ce3 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/child_process/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/child_process/package.scala @@ -36,4 +36,19 @@ package object child_process { // TODO: spawn, fork } + + implicit final class ChildProcessClassExtension(private val cp: ChildProcess) extends AnyVal { + @inline + def onClose(listener: (Int, String) => Any): ChildProcess = cp.on("close", listener) + + @inline + def onDisconnect(listener: () => Any): ChildProcess = cp.on("disconnect", listener) + + @inline + def onError(listener: (js.Error) => Any): ChildProcess = cp.on("error", listener) + + @inline + def onMessage(listener: (js.Any, js.UndefOr[net.Socket | net.Server]) => Any): ChildProcess = + cp.on("message", listener) + } } From 9b5fbcbcc0ba6c1731b60a34a1c6496d1cdd71e4 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 14:19:24 +0900 Subject: [PATCH 03/17] Overhaul events in cluster module --- .../src/main/scala/io/scalajs/nodejs/cluster/package.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/cluster/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/cluster/package.scala index 002c3fa75..45be79804 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/cluster/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/cluster/package.scala @@ -148,7 +148,7 @@ package object cluster { * */ @inline - def onExit(callback: (Worker, Int, String) => Any): Worker = worker.on("exit", callback) + def onExit(callback: (Int, String) => Any): Worker = worker.on("exit", callback) /** * Similar to the cluster.on('listening') event, but specific to this worker. @@ -164,7 +164,7 @@ package object cluster { * @param callback the event handler */ @inline - def onMessage(callback: Message => Any): Worker = worker.on("message", callback) + def onMessage(callback: Message => Any, handle: js.UndefOr[js.Object]): Worker = worker.on("message", callback) /** * Similar to the cluster.on('online') event, but specific to this worker. From 7c600161d5f601328470f37ca709f2ad31d2d027 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 14:29:44 +0900 Subject: [PATCH 04/17] Add events in events module --- .../scala/io/scalajs/nodejs/events/package.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 app/current/src/main/scala/io/scalajs/nodejs/events/package.scala diff --git a/app/current/src/main/scala/io/scalajs/nodejs/events/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/events/package.scala new file mode 100644 index 000000000..b81433a9d --- /dev/null +++ b/app/current/src/main/scala/io/scalajs/nodejs/events/package.scala @@ -0,0 +1,16 @@ +package io.scalajs.nodejs + +import scala.scalajs.js +import scala.scalajs.js.| + +package object events { + + implicit final class EventEmitterExtensions(val instance: EventEmitter) extends AnyVal { + @inline def onNewListener(listener: (String | js.Symbol, js.Function) => Any): instance.type = + instance.on("newListener", listener) + + @inline def onRemoveListener(listener: (String | js.Symbol, js.Function) => Any): instance.type = + instance.on("removeListener", listener) + } + +} From 2fe9021e1bed2316b14dec63d54285197eebf3c5 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 15:01:48 +0900 Subject: [PATCH 05/17] Overhaul events in http module --- .../scalajs/nodejs/http/ClientRequest.scala | 29 +++++++++++++------ .../scalajs/nodejs/http/IncomingMessage.scala | 5 +++- .../scala/io/scalajs/nodejs/http/Server.scala | 23 ++++++++------- .../scalajs/nodejs/http/ServerResponse.scala | 5 +++- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http/ClientRequest.scala b/app/current/src/main/scala/io/scalajs/nodejs/http/ClientRequest.scala index 740b6e28d..c26a5e53d 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http/ClientRequest.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http/ClientRequest.scala @@ -3,6 +3,7 @@ package http import io.scalajs.nodejs.buffer.Buffer import io.scalajs.nodejs.net.Socket +import io.scalajs.nodejs.stream.Duplex import io.scalajs.util.PromiseHelper._ import scala.concurrent.Future @@ -117,21 +118,15 @@ object ClientRequest { @inline def onAbort(callback: () => Any): client.type = client.on("abort", callback) - /** - * Emitted when the request has been aborted by the server and the network socket has closed. - */ - @inline - def onAborted(callback: () => Any): client.type = client.on("aborted", callback) - /** * Emitted each time a server responds to a request with a CONNECT method. If this event is not being listened for, * clients receiving a CONNECT method will have their connections closed. * - response - * - socket + * - socket * - head */ @inline - def onConnect(callback: (IncomingMessage, Socket, Buffer) => Any): client.type = client.on("connect", callback) + def onConnect(callback: (IncomingMessage, Duplex, Buffer) => Any): client.type = client.on("connect", callback) /** * Emitted when the server sends a '100 Continue' HTTP response, usually because the request @@ -140,6 +135,9 @@ object ClientRequest { @inline def onContinue(callback: () => Any): client.type = client.on("continue", callback) + @inline + def onInformation(callback: Information => Any): client.type = client.on("information", callback) + /** * Emitted when a response is received to this request. This event is emitted only once. * The response argument will be an instance of http.IncomingMessage. @@ -153,7 +151,10 @@ object ClientRequest { * - socket */ @inline - def onSocket(callback: Socket => Any): client.type = client.on("socket", callback) + def onSocket(callback: Duplex => Any): client.type = client.on("socket", callback) + + @inline + def onTimeout(callback: () => Any): client.type = client.on("timeout", callback) /** * Emitted each time a server responds to a request with an upgrade. If this event isn't being listened for, @@ -186,3 +187,13 @@ object ClientRequest { } } } + +trait Information extends js.Object { + val httpVersion: String + val httpVersionMajor: Int + val httpVersionMinor: Int + val statusCode: Int + val statusMessage: String + val headers: js.Object + val rawHeaders: js.Array[String] +} diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http/IncomingMessage.scala b/app/current/src/main/scala/io/scalajs/nodejs/http/IncomingMessage.scala index f818268c0..5dd45fc76 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http/IncomingMessage.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http/IncomingMessage.scala @@ -103,7 +103,10 @@ object IncomingMessage { */ implicit final class IncomingMessageExtensions(val message: IncomingMessage) extends AnyVal { @inline - def onClose(callback: js.Function): message.type = message.on("close", callback) + def onAborted(callback: () => Any): message.type = message.on("aborted", callback) + + @inline + def onClose(callback: () => Any): message.type = message.on("close", callback) @inline def setTimeout(duration: FiniteDuration, callback: js.Function): Unit = diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http/Server.scala b/app/current/src/main/scala/io/scalajs/nodejs/http/Server.scala index 212650a70..e9b4496ed 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http/Server.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http/Server.scala @@ -3,7 +3,7 @@ package http import io.scalajs.nodejs import io.scalajs.nodejs.buffer.Buffer -import io.scalajs.nodejs.net.Socket +import io.scalajs.nodejs.stream.Duplex import scala.scalajs.js import scala.scalajs.js.annotation.JSImport @@ -44,6 +44,7 @@ object Server { * - request * - response */ + @inline def onCheckContinue(callback: (IncomingMessage, ServerResponse) => Any): server.type = { server.on("checkContinue", callback) } @@ -52,11 +53,11 @@ object Server { * Emitted each time a request with an http Expect header is received, where the value is not 100-continue. * If this event isn't listened for, the server will automatically respond with a 417 Expectation Failed as appropriate. * Note that when this event is emitted and handled, the request event will not be emitted. - * - request + * - request * - response */ @inline - def onCheckExpectation(callback: (ClientRequest, ServerResponse) => Any): server.type = { + def onCheckExpectation(callback: (IncomingMessage, ServerResponse) => Any): server.type = { server.on("checkExpectation", callback) } @@ -67,10 +68,10 @@ object Server { * * Default behavior is to destroy the socket immediately on malformed request. * - exception - * - socket + * - socket */ @inline - def onClientError(callback: (nodejs.Error, Socket) => Any): server.type = server.on("clientError", callback) + def onClientError(callback: (nodejs.Error, Duplex) => Any): server.type = server.on("clientError", callback) /** * Emitted when the server closes. @@ -85,20 +86,20 @@ object Server { * After this event is emitted, the request's socket will not have a 'data' event listener, meaning you will need * to bind to it in order to handle data sent to the server on that socket. * - request Arguments for the HTTP request, as it is in the 'request' event - * - socket Network socket between the server and client + * - socket Network socket between the server and client * - head The first packet of the tunneling stream (may be empty) */ @inline - def onConnect(handler: (IncomingMessage, Socket, Buffer) => Any): server.type = server.on("connect", handler) + def onConnect(handler: (IncomingMessage, Duplex, Buffer) => Any): server.type = server.on("connect", handler) /** * When a new TCP stream is established. socket is an object of type net.Socket. Usually users will not want * to access this event. In particular, the socket will not emit 'readable' events because of how the protocol * parser attaches to the socket. The socket can also be accessed at request.connection. - * - socket + * - socket */ @inline - def onConnection(handler: Socket => Any): server.type = server.on("connection", handler) + def onConnection(handler: Duplex => Any): server.type = server.on("connection", handler) /** * Emitted each time there is a request. Note that there may be multiple requests per connection (in the case @@ -116,10 +117,10 @@ object Server { * After this event is emitted, the request's socket will not have a 'data' event listener, meaning you will * need to bind to it in order to handle data sent to the server on that socket. * - request Arguments for the HTTP request, as it is in the 'request' event - * - socket Network socket between the server and client + * - socket Network socket between the server and client * - head The first packet of the upgraded stream (may be empty) */ @inline - def onUpgrade(handler: (IncomingMessage, Socket, Buffer) => Any): server.type = server.on("upgrade", handler) + def onUpgrade(handler: (IncomingMessage, Duplex, Buffer) => Any): server.type = server.on("upgrade", handler) } } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http/ServerResponse.scala b/app/current/src/main/scala/io/scalajs/nodejs/http/ServerResponse.scala index 09c1f917e..af9371443 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http/ServerResponse.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http/ServerResponse.scala @@ -149,7 +149,10 @@ object ServerResponse { def onData(handler: Buffer => Any): response.type = response.on("data", handler) @inline - def onFinish(handler: js.Function): response.type = response.on("finish", handler) + def onClose(handler: () => Any): response.type = response.on("close", handler) + + @inline + def onFinish(handler: () => Any): response.type = response.on("finish", handler) /** * Sets the content-type for the response From f9d8d3568f5c942b9894c8f1311c71801bdfe4b3 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 15:41:00 +0900 Subject: [PATCH 06/17] Overhaul events in http2 module --- .../nodejs/http2/Http2ServerRequest.scala | 4 +- .../nodejs/http2/Http2ServerResponse.scala | 14 +--- .../io/scalajs/nodejs/http2/package.scala | 73 +++++++++++++++++++ 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerRequest.scala b/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerRequest.scala index 8e8136d2c..376dffb7f 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerRequest.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerRequest.scala @@ -1,7 +1,7 @@ package io.scalajs.nodejs.http2 import com.thoughtworks.enableIf -import io.scalajs.nodejs.{net, tls} +import io.scalajs.nodejs.{net, tls, stream} import scala.scalajs.js import scala.scalajs.js.annotation.JSImport @@ -9,7 +9,7 @@ import scala.scalajs.js.| @js.native @JSImport("http2", "Http2ServerRequest") -class Http2ServerRequest extends Http2TimeoutOps { +class Http2ServerRequest extends stream.Readable with Http2TimeoutOps { def authority: String = js.native /** diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerResponse.scala b/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerResponse.scala index 2ab8a7960..2588ae811 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerResponse.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerResponse.scala @@ -2,7 +2,7 @@ package io.scalajs.nodejs.http2 import com.thoughtworks.enableIf import io.scalajs.nodejs.buffer.Buffer -import io.scalajs.nodejs.{net, tls} +import io.scalajs.nodejs.{net, tls, stream} import scala.scalajs.js import scala.scalajs.js.annotation.JSImport @@ -10,7 +10,7 @@ import scala.scalajs.js.| @js.native @JSImport("http2", "Http2ServerResponse") -class Http2ServerResponse extends Http2TimeoutOps { +class Http2ServerResponse extends stream.Writable with Http2TimeoutOps { def addTrailers(headers: Http2Headers): Unit = js.native /** @@ -25,18 +25,10 @@ class Http2ServerResponse extends Http2TimeoutOps { def socket: net.Socket | tls.TLSSocket = js.native def stream: Http2Stream = js.native - // TODO: Return type can be this.type when Node.js v8 dropped - def end(chunk: String | Buffer, callback: js.Function1[Error, Any]): js.UndefOr[this.type] = js.native - def end(chunk: String | Buffer): js.UndefOr[this.type] = js.native - def end(callback: js.Function1[Error, Any]): js.UndefOr[this.type] = js.native - def end(chunk: String, encoding: String, callback: js.Function1[Error, Any]): js.UndefOr[this.type] = js.native - def end(chunk: String, encoding: String): js.UndefOr[this.type] = js.native - def end(): js.UndefOr[this.type] = js.native + def end(): js.UndefOr[this.type] = js.native - def write(chunk: String | Buffer, callback: js.Function1[Error, Any]): Boolean = js.native def write(chunk: String | Buffer): Boolean = js.native def write(chunk: String, encoding: String, callback: js.Function1[Error, Any]): Boolean = js.native - def write(chunk: String, encoding: String): Boolean = js.native def writeHead(statusCode: Int, statusMessage: String, http2Headers: Http2Headers): Unit = js.native def writeHead(statusCode: Int, http2Headers: Http2Headers): Unit = js.native diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http2/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/http2/package.scala index 51a8c4eac..25f9eed2c 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http2/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http2/package.scala @@ -3,9 +3,82 @@ package io.scalajs.nodejs import io.scalajs.nodejs.buffer.Buffer import io.scalajs.nodejs.url.URL +import scala.scalajs.js import scala.scalajs.js.| package object http2 { type Origin = String | URL | HasOrigin type Path = String | Buffer | URL + + implicit final class Http2SessionExtension(val instance: Http2Session) extends AnyVal { + @inline def onClose(handler: () => Any): instance.type = instance.on("close", handler) + @inline def onConnect(handler: (Http2Session, net.Socket) => Any): instance.type = instance.on("connect", handler) + @inline def onError(handler: (Error) => Any): instance.type = instance.on("error", handler) + @inline def onFrameError(handler: (Int, Int, Int) => Any): instance.type = instance.on("frameError", handler) + @inline def onGoaway(handler: (Int, Int, Buffer) => Any): instance.type = instance.on("goaway", handler) + @inline def onLocalSettings(handler: Http2Settings => Any): instance.type = instance.on("localSettings", handler) + @inline def onPing(handler: (Buffer) => Any): instance.type = instance.on("ping", handler) + @inline def onRemoteSettings(handler: (Http2Settings) => Any): instance.type = + instance.on("remoteSettings", handler) + @inline def onStream(handler: (Http2Stream, Http2Headers, Int, js.Array[String]) => Any): instance.type = + instance.on("stream", handler) + @inline def onTimeout(handler: () => Any): instance.type = instance.on("timeout", handler) + } + + implicit final class ClientHttp2SessionExtension(val instance: ClientHttp2Session) extends AnyVal { + @inline def onAltsvc(handler: (String, String, Int) => Any): instance.type = instance.on("altsvc", handler) + @inline def onOrigin(handler: (js.Array[String]) => Any): instance.type = instance.on("origin", handler) + } + + implicit final class Http2StreamExtension(val instance: Http2Stream) extends AnyVal { + @inline def onAborted(handler: () => Any): instance.type = instance.on("aborted", handler) + @inline def onClose(handler: () => Any): instance.type = instance.on("close", handler) + @inline def onError(handler: (Error) => Any): instance.type = instance.on("error", handler) + @inline def onFrameError(handler: (Int, Int, Int) => Any): instance.type = instance.on("frameError", handler) + @inline def onTimeout(handler: () => Any): instance.type = instance.on("timeout", handler) + @inline def onTrailers(handler: (Http2Headers, Int) => Any): instance.type = instance.on("trailers", handler) + @inline def onWantTrailers(handler: () => Any): instance.type = instance.on("wantTrailers", handler) + } + + implicit final class ClientHttp2StreamExtension(val instance: ClientHttp2Stream) extends AnyVal { + @inline def onContinue(handler: () => Any): instance.type = instance.on("continue", handler) + @inline def onHeaders(handler: (Http2Headers, Int) => Any): instance.type = instance.on("headers", handler) + @inline def onPush(handler: (Http2Headers, Int) => Any): instance.type = instance.on("push", handler) + @inline def onResponse(handler: (Http2Headers, Int) => Any): instance.type = instance.on("response", handler) + } + + implicit final class Http2SeverExtension(val instance: Http2Server) extends AnyVal { + @inline def onCheckContinue(handler: (Http2ServerRequest, Http2ServerResponse) => Any): instance.type = + instance.on("checkContinue", handler) + @inline def onRequest(handler: (Http2ServerRequest, Http2ServerResponse) => Any): instance.type = + instance.on("request", handler) + @inline def onSession(handler: () => Any): instance.type = instance.on("session", handler) + @inline def onSessionError(handler: () => Any): instance.type = instance.on("sessionError", handler) + @inline def onStream(handler: (Http2Stream, Http2Headers, Int) => Any): instance.type = + instance.on("stream", handler) + @inline def onTimeout(handler: () => Any): instance.type = instance.on("timeout", handler) + } + + implicit final class Http2SecureSeverExtension(val instance: Http2SecureServer) extends AnyVal { + @inline def onCheckContinue(handler: (Http2ServerRequest, Http2ServerResponse) => Any): instance.type = + instance.on("checkContinue", handler) + @inline def onRequest(handler: (Http2ServerRequest, Http2ServerResponse) => Any): instance.type = + instance.on("request", handler) + @inline def onSession(handler: () => Any): instance.type = instance.on("session", handler) + @inline def onSessionError(handler: () => Any): instance.type = instance.on("sessionError", handler) + @inline def onStream(handler: (Http2Stream, Http2Headers, Int) => Any): instance.type = + instance.on("stream", handler) + @inline def onTimeout(handler: () => Any): instance.type = instance.on("timeout", handler) + @inline def onUnknownProtocol(handler: () => Any): instance.type = instance.on("unknownProtocol", handler) + } + + implicit final class Http2ServerRequestExtension(val instance: Http2ServerRequest) extends AnyVal { + @inline def onAborted(handler: (stream.IReadable) => Any): instance.type = instance.on("aborted", handler) + @inline def onClose(handler: () => Any): instance.type = instance.on("close", handler) + } + + implicit final class Http2ServerResponseExtension(val instance: Http2ServerResponse) extends AnyVal { + @inline def onClose(handler: () => Any): instance.type = instance.on("close", handler) + @inline def onAborted(handler: (stream.IReadable) => Any): instance.type = instance.on("aborted", handler) + } } From 8eb3a75460b9952561e655af9f0971d08346764d Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 15:58:14 +0900 Subject: [PATCH 07/17] Remove overload --- .../io/scalajs/nodejs/http2/Http2ServerResponse.scala | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerResponse.scala b/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerResponse.scala index 2588ae811..abf453608 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerResponse.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http2/Http2ServerResponse.scala @@ -1,6 +1,5 @@ package io.scalajs.nodejs.http2 -import com.thoughtworks.enableIf import io.scalajs.nodejs.buffer.Buffer import io.scalajs.nodejs.{net, tls, stream} @@ -13,13 +12,6 @@ import scala.scalajs.js.| class Http2ServerResponse extends stream.Writable with Http2TimeoutOps { def addTrailers(headers: Http2Headers): Unit = js.native - /** - * Added in Node.js v12.9.0 - * @see v12.9.0 - */ - @enableIf(io.scalajs.nodejs.internal.CompilerSwitches.gteNodeJs12) - def writableEnded: Boolean = js.native - @deprecated("Use response.socket", "Node.js v13.0.0") def connection: net.Socket | tls.TLSSocket = js.native def socket: net.Socket | tls.TLSSocket = js.native From 169f3466545126ab75ddfbf04d1d62b4eb9a62cd Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 16:04:42 +0900 Subject: [PATCH 08/17] Overhaul events in net module --- .../main/scala/io/scalajs/nodejs/net/package.scala | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/net/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/net/package.scala index b861a3c4a..389986056 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/net/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/net/package.scala @@ -5,6 +5,7 @@ import io.scalajs.util.PromiseHelper._ import scala.concurrent.Future import scala.scalajs.js +import scala.scalajs.js.| /** * net package object @@ -90,7 +91,7 @@ package object net { * @param callback the callback * @example socket.on("connect", function() { ... }) */ - @inline def onConnect(callback: js.Function): socket.type = socket.on("connect", callback) + @inline def onConnect(callback: () => Any): socket.type = socket.on("connect", callback) /** * Emitted when data is received. The argument data will be a Buffer or String. Encoding of data is set by @@ -100,7 +101,7 @@ package object net { * @param callback - * @example socket.on("data", function(buffer) { ... }) */ - @inline def onData(callback: Buffer => Any): socket.type = socket.on("data", callback) + @inline def onData(callback: Buffer | String => Any): socket.type = socket.on("data", callback) /** * Emitted when the write buffer becomes empty. Can be used to throttle uploads. @@ -109,7 +110,7 @@ package object net { * @param callback the callback * @example socket.on("drain", function(???) { ... }) */ - @inline def onDrain(callback: js.Function): socket.type = socket.on("drain", callback) + @inline def onDrain(callback: () => Any): socket.type = socket.on("drain", callback) /** * Emitted when the other end of the socket sends a FIN packet. @@ -121,7 +122,9 @@ package object net { * @param callback the callback * @example socket.on("end", function(???) { ... }) */ - @inline def onEnd(callback: js.Function): socket.type = socket.on("end", callback) + @inline def onEnd(callback: () => Any): socket.type = socket.on("end", callback) + + @inline def onError(callback: (Error) => Any): socket.type = socket.on("error", callback) /** * Emitted after resolving the hostname but before connecting. Not applicable to UNIX sockets. @@ -136,6 +139,8 @@ package object net { */ @inline def onLookup(callback: (Error, String, String, String) => Any): socket.type = socket.on("lookup", callback) + @inline def onReady(callback: () => Any): socket.type = socket.on("ready", callback) + /** * Emitted if the socket times out from inactivity. This is only to notify that the socket has been idle. The user * must manually close the connection. From d3eb7fc55bf6113647b9d64261fd4ea218e7b184 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 16:10:40 +0900 Subject: [PATCH 09/17] Warning is just an alias of Error --- .../io/scalajs/nodejs/process/Process.scala | 22 ------------------- .../io/scalajs/nodejs/process/package.scala | 3 +++ 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/process/Process.scala b/app/current/src/main/scala/io/scalajs/nodejs/process/Process.scala index 372f3132d..456e6803c 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/process/Process.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/process/Process.scala @@ -443,28 +443,6 @@ trait ComponentVersion extends js.Object { var tz: String = js.native } -/** - * Warning - */ -@js.native -trait Warning extends js.Object { - - /** - * The name of the warning (currently Warning by default). - */ - var name: String = js.native - - /** - * A system-provided description of the warning. - */ - var message: String = js.native - - /** - * A stack trace to the location in the code where the warning was issued. - */ - var stack: js.Any = js.native -} - @js.native trait CpuUsage extends js.Object { val user: Int = js.native diff --git a/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala index 3323615be..3f0113fda 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala @@ -13,6 +13,9 @@ package object process { type ExitCode = Int type SendHandle = net.Socket | net.Server + @deprecated("Use io.scalajs.nodejs.Error", "v0.10.0") + type Warning = Error + /** * Process Object Extensions * @param process the given [[Process process]] From a78200ec0ed99d1cc7168de34652279ea71a0d5a Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 16:10:58 +0900 Subject: [PATCH 10/17] Overhaul events in process module --- .../io/scalajs/nodejs/process/package.scala | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala index 3f0113fda..37ab74a50 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/process/package.scala @@ -51,7 +51,7 @@ package object process { * @param listener the event listener function * @since 0.11.12 */ - def onBeforeExit(listener: ExitCode => Any): Process = process.on("beforeExit", listener) + @inline def onBeforeExit(listener: ExitCode => Any): Process = process.on("beforeExit", listener) /** * If process is spawned with an IPC channel, 'disconnect' will be emitted when IPC channel is closed. @@ -59,7 +59,7 @@ package object process { * @param listener the event listener function * @since 0.7.7 */ - def onDisconnect(listener: () => Any): Process = process.on("disconnect", listener) + @inline def onDisconnect(listener: () => Any): Process = process.on("disconnect", listener) /** * Emitted when the process is about to exit. There is no way to prevent the exiting of the event loop at this point, @@ -70,7 +70,7 @@ package object process { * @example process.on('exit', (code) => { ... }) * @since 0.1.7 */ - def onExit(listener: ExitCode => Any): Process = process.on("exit", listener) + @inline def onExit(listener: ExitCode => Any): Process = process.on("exit", listener) /** * Messages sent by ChildProcess.send() are obtained using the 'message' event on the child's process object. @@ -81,10 +81,10 @@ package object process { * * @since 0.5.10 */ - def onMessage(listener: (js.Any, js.UndefOr[net.Server | net.Socket]) => Any): Process = + @inline def onMessage(listener: (js.Any, js.UndefOr[net.Server | net.Socket]) => Any): Process = process.on("message", listener) - def onMultipleResolves[T](listener: (String, js.Promise[T], js.Any) => Any): Process = + @inline def onMultipleResolves[T](listener: (String, js.Promise[T], js.Any) => Any): Process = process.on("multipleResolves", listener) /** @@ -92,7 +92,8 @@ package object process { * later than after an event loop turn. * @param listener the event listener function */ - def onRejectionHandled[T](listener: js.Promise[T] => Any): Process = process.on("rejectionHandled", listener) + @inline def onRejectionHandled[T](listener: js.Promise[T] => Any): Process = + process.on("rejectionHandled", listener) /** * The 'uncaughtException' event is emitted when an exception bubbles all the way back to the event loop. By default, @@ -100,10 +101,11 @@ package object process { * 'uncaughtException' event overrides this default behavior. * @param listener the event listener function */ - def onUncaughtException(listener: Error => Any): Process = process.on("uncaughtException", listener) + @inline def onUncaughtException(listener: Error => Any): Process = process.on("uncaughtException", listener) @enableIf(io.scalajs.nodejs.internal.CompilerSwitches.gteNodeJs12) - def onUncaughtException(listener: (Error, String) => Any): Process = process.on("uncaughtException", listener) + @inline def onUncaughtException(listener: (Error, String) => Any): Process = + process.on("uncaughtException", listener) /** * Emitted whenever a Promise is rejected and no error handler is attached to the promise within a turn of the event @@ -112,7 +114,7 @@ package object process { * detecting and keeping track of promises that were rejected whose rejections were not handled yet. * @param listener the event listener function */ - def onUnhandledRejection[T](listener: (js.Any, js.Promise[T]) => Any): Process = + @inline def onUnhandledRejection[T](listener: (js.Any, js.Promise[T]) => Any): Process = process.on("unhandledRejection", listener) /** @@ -124,7 +126,7 @@ package object process { * The event handler for 'warning' events is called with a single warning argument whose value is an Error object. * @param listener the event listener function */ - def onWarning(listener: Warning => Any): Process = process.on("warning", listener) + @inline def onWarning(listener: Error => Any): Process = process.on("warning", listener) ///////////////////////////////////////////////////////////////////////////////// // Signal Events - Emitted when the processes receives a signal. @@ -136,22 +138,22 @@ package object process { * An easy way to send the SIGINT signal is with Control-C in most terminal programs. * @param listener the event listener function */ - def onSIGINT(listener: () => Any): Process = process.on("SIGINT", listener) + @inline def onSIGINT(listener: () => Any): Process = process.on("SIGINT", listener) /** * SIGUSR1 is reserved by Node.js to start the debugger. It's possible to install a listener but that won't stop * the debugger from starting. * @param listener the event listener function */ - def onSIGUSR1(listener: () => Any): Process = process.on("SIGUSR1", listener) - - def onSIGTERM(listener: () => Any): Process = process.on("SIGTERM", listener) - def onSIGHUP(listener: () => Any): Process = process.on("SIGHUP", listener) - def onSIGBREAK(listener: () => Any): Process = process.on("SIGBREAK", listener) - def onSIGWINCH(listener: () => Any): Process = process.on("SIGWINCH", listener) - def onSIGBUS(listener: () => Any): Process = process.on("SIGBUS", listener) - def onSIGFPE(listener: () => Any): Process = process.on("SIGFPE", listener) - def onSIGSEGV(listener: () => Any): Process = process.on("SIGSEGV", listener) - def onSIGILL(listener: () => Any): Process = process.on("SIGILL", listener) + @inline def onSIGUSR1(listener: () => Any): Process = process.on("SIGUSR1", listener) + + @inline def onSIGTERM(listener: () => Any): Process = process.on("SIGTERM", listener) + @inline def onSIGHUP(listener: () => Any): Process = process.on("SIGHUP", listener) + @inline def onSIGBREAK(listener: () => Any): Process = process.on("SIGBREAK", listener) + @inline def onSIGWINCH(listener: () => Any): Process = process.on("SIGWINCH", listener) + @inline def onSIGBUS(listener: () => Any): Process = process.on("SIGBUS", listener) + @inline def onSIGFPE(listener: () => Any): Process = process.on("SIGFPE", listener) + @inline def onSIGSEGV(listener: () => Any): Process = process.on("SIGSEGV", listener) + @inline def onSIGILL(listener: () => Any): Process = process.on("SIGILL", listener) } } From 979546a64d625a49d014ec11efd9e07eb448ccca Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 16:13:01 +0900 Subject: [PATCH 11/17] Overhaul events in readline module --- .../scala/io/scalajs/nodejs/readline/Interface.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala b/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala index 655d6944e..803199f69 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala @@ -122,13 +122,13 @@ object Interface { * and receives the SIGCONT event. (See events SIGTSTP and SIGCONT) */ @inline - def onPause(callback: js.Function) = readline.on("pause", callback) + def onPause(callback: () => Any) = readline.on("pause", callback) /** * Emitted whenever the input stream is resumed. */ @inline - def onResume(callback: js.Function) = readline.on("resume", callback) + def onResume(callback: () => Any) = readline.on("resume", callback) /** * Emitted whenever the input stream is sent to the background with {{{ ^Z }}}, respectively known as SIGTSTP, @@ -136,14 +136,14 @@ object Interface { * program to the background. */ @inline - def onSIGCONT(callback: js.Function) = readline.on("SIGCONT", callback) + def onSIGCONT(callback: () => Any) = readline.on("SIGCONT", callback) /** * Emitted whenever the input stream receives a {{{ ^C }}}, respectively known as SIGINT. If there is no * SIGINT event listener present when the input stream receives a SIGINT, pause will be triggered. */ @inline - def onSIGINT(callback: js.Function) = readline.on("SIGINT", callback) + def onSIGINT(callback: () => Any) = readline.on("SIGINT", callback) /** * Emitted whenever the input stream receives a {{{ ^Z }}}, respectively known as SIGTSTP. If there is no @@ -153,6 +153,6 @@ object Interface { * stream was paused before the program was sent to the background. */ @inline - def onSIGTSTP(callback: js.Function) = readline.on("SIGTSTP", callback) + def onSIGTSTP(callback: () => Any) = readline.on("SIGTSTP", callback) } } From d3d77b9fb08f0ab95c2e845eb7f5f2b24b1afa49 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 16:19:23 +0900 Subject: [PATCH 12/17] Overhaul events in repl module --- .../io/scalajs/nodejs/repl/REPLServer.scala | 27 ------------------- .../io/scalajs/nodejs/repl/package.scala | 6 ++--- 2 files changed, 3 insertions(+), 30 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/repl/REPLServer.scala b/app/current/src/main/scala/io/scalajs/nodejs/repl/REPLServer.scala index 59a9d9f2e..c098d8fb0 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/repl/REPLServer.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/repl/REPLServer.scala @@ -65,30 +65,3 @@ class DefinedCommand( var action: js.Function1[String, Any], var help: js.UndefOr[String] = js.undefined ) extends js.Object - -/** - * REPL Server Companion - */ -object REPLServer { - - /** - * REPL Server Extensions - * @param server the given [[REPLServer REPL Server]] - */ - implicit final class REPLServerExtensions[T <: REPLServer](val server: T) extends AnyVal { - - /** - * Emitted when the user exits the REPL in any of the defined ways. Namely, typing .exit at the repl, - * pressing Ctrl+C twice to signal SIGINT, or pressing Ctrl+D to signal 'end' on the input stream. - */ - @inline - def onExit(callback: js.Function): server.type = server.on("exit", callback) - - /** - * Emitted when the REPL's context is reset. This happens when you type .clear. If you start the repl - * with { useGlobal: true } then this event will never be emitted. - */ - @inline - def onReset(callback: js.Function): server.type = server.on("reset", callback) - } -} diff --git a/app/current/src/main/scala/io/scalajs/nodejs/repl/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/repl/package.scala index 3e4d57800..e1c89f904 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/repl/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/repl/package.scala @@ -12,7 +12,7 @@ package object repl { * REPL Server events * @param server the given [[REPLServer instance]] */ - implicit final class REPLServerEvents(val server: REPLServer) extends AnyVal { + implicit final class REPLServerExtensions[X <: REPLServer](private val server: X) extends AnyVal { @inline def contextAs[T]: T = server.context.asInstanceOf[T] @@ -23,7 +23,7 @@ package object repl { * @param listener The listener callback */ @inline - def onExit(listener: () => Any): REPLServer = server.on("exit", listener) + def onExit(listener: () => Any): X = server.on("exit", listener) /** * The 'reset' event is emitted when the REPL's context is reset. This occurs whenever the .clear command @@ -33,7 +33,7 @@ package object repl { * @param listener The listener callback */ @inline - def onReset(listener: REPLContext => Any): REPLServer = server.on("reset", listener) + def onReset(listener: REPLContext => Any): X = server.on("reset", listener) } /** From d867e5881b6c5bc6fd5a3253e33cc340327dd086 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 16:25:31 +0900 Subject: [PATCH 13/17] Overhaul events in stream module --- .../io/scalajs/nodejs/stream/Stream.scala | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/stream/Stream.scala b/app/current/src/main/scala/io/scalajs/nodejs/stream/Stream.scala index 6241a3df6..ac3e75492 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/stream/Stream.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/stream/Stream.scala @@ -233,21 +233,21 @@ object IReadable { /** * Readable Events */ - implicit final class ReadableExtesions(val readable: IReadable) extends AnyVal { + implicit final class ReadableExtesions[R <: IReadable](private val readable: R) extends AnyVal { /** * Emitted when the stream and any of its underlying resources (a file descriptor, for example) have been closed. * The event indicates that no more events will be emitted, and no further computation will occur. */ @inline - def onClose(listener: () => Any): readable.type = readable.on("close", listener) + def onClose(listener: () => Any): R = readable.on("close", listener) /** * Attaching a 'data' event listener to a stream that has not been explicitly paused will switch the stream into * flowing mode. Data will then be passed as soon as it is available. */ @inline - def onData[A](listener: A => Any): readable.type = readable.on("data", listener) + def onData[A](listener: A => Any): R = readable.on("data", listener) /** * This event fires when there will be no more data to read. Note that the 'end' event will not fire unless the @@ -255,13 +255,13 @@ object IReadable { * repeatedly until you get to the end. */ @inline - def onEnd(listener: () => Any): readable.type = readable.on("end", listener) + def onEnd(listener: () => Any): R = readable.on("end", listener) /** * Emitted if there was an error when writing or piping data. */ @inline - def onError(listener: Error => Any): readable.type = readable.on("error", listener) + def onError(listener: Error => Any): R = readable.on("error", listener) /** * When a chunk of data can be read from the stream, it will emit a 'readable' event. In some cases, listening @@ -269,7 +269,10 @@ object IReadable { * if it hadn't already. */ @inline - def onReadable(listener: () => Any): readable.type = readable.on("readable", listener) + def onReadable(listener: () => Any): R = readable.on("readable", listener) + + @inline def onPause(listener: () => Any): R = readable.on("pause", listener) + @inline def onResume(listener: () => Any): R = readable.on("resume", listener) @inline def iteratorAsString: scala.Iterator[String] = new scala.Iterator[String] { @@ -414,48 +417,48 @@ object IWritable { /** * Writable Events */ - implicit final class WritableExtension(val writable: IWritable) extends AnyVal { + implicit final class WritableExtension[W <: IWritable](private val writable: W) extends AnyVal { /** * Emitted when the stream and any of its underlying resources (a file descriptor, for example) have been closed. * The event indicates that no more events will be emitted, and no further computation will occur. */ @inline - def onClose(listener: () => Any): writable.type = writable.on("close", listener) + def onClose(listener: () => Any): W = writable.on("close", listener) /** * If a stream.write(chunk) call returns false, then the 'drain' event will indicate when it is appropriate * to begin writing more data to the stream. */ @inline - def onDrain(listener: () => Any): writable.type = writable.on("drain", listener) + def onDrain(listener: () => Any): W = writable.on("drain", listener) /** * Emitted if there was an error when writing or piping data. */ @inline - def onError(listener: Error => Any): writable.type = writable.on("error", listener) + def onError(listener: Error => Any): W = writable.on("error", listener) /** * When the stream.end() method has been called, and all data has been flushed to the underlying system, * this event is emitted. */ @inline - def onFinish(listener: () => Any): writable.type = writable.on("finish", listener) + def onFinish(listener: () => Any): W = writable.on("finish", listener) /** * This is emitted whenever the stream.pipe() method is called on a readable stream, adding this writable to * its set of destinations. */ @inline - def onPipe(listener: IReadable => Any): writable.type = writable.on("pipe", listener) + def onPipe[R <: IReadable](listener: R => Any): W = writable.on("pipe", listener) /** * This is emitted whenever the stream.unpipe() method is called on a readable stream, removing this writable * from its set of destinations. */ @inline - def onUnpipe(listener: IReadable => Any): writable.type = writable.on("unpipe", listener) + def onUnpipe[R <: IReadable](listener: R => Any): W = writable.on("unpipe", listener) @inline def endFuture(chunk: Buffer): Future[Unit] = promiseWithError0[Error](writable.end(chunk, _)) From cc9ff4996708e7f5d64d0161830be931d6b8c1db Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 16:35:08 +0900 Subject: [PATCH 14/17] Overhaul events in tls module --- .../scala/io/scalajs/nodejs/tls/package.scala | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/tls/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/tls/package.scala index b6e6edc33..f43a7c079 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/tls/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/tls/package.scala @@ -1,5 +1,6 @@ package io.scalajs.nodejs +import com.thoughtworks.enableIf import io.scalajs.nodejs.buffer.Buffer import scala.scalajs.js @@ -15,4 +16,27 @@ package object tls { type ALPNProtocols = Buffer | TypedArray[_, _] | DataView | js.Array[String] | js.Array[TypedArray[_, _]] | js.Array[DataView] + + implicit final class ServerExtension[T <: Server](private val instance: T) extends AnyVal { + @enableIf(io.scalajs.nodejs.internal.CompilerSwitches.gteNodeJs12) + @inline def onKeylog(handler: (Buffer, TLSSocket) => Any): T = instance.on("keylog", handler) + + @inline def onNewSession(handler: (Buffer, Buffer, js.Function0[Unit]) => Any): T = + instance.on("newSession", handler) + @inline def onOCSPRequest(handler: (Buffer, Buffer, js.Function2[Error, js.Any, Unit]) => Any): T = + instance.on("OCSPRequest", handler) + @inline def onResumeSession(handler: (Buffer, js.Function2[Error, Buffer, Unit]) => Any): T = + instance.on("resumeSession", handler) + @inline def onSecureConnection(handler: (tls.TLSSocket => Any)): T = instance.on("secureConnection", handler) + @inline def onTlsClientError(handler: (Error, tls.TLSSocket) => Any): T = instance.on("tlsClientError", handler) + } + + implicit final class TLSSocketExtension[T <: TLSSocket](private val instance: T) extends AnyVal { + @enableIf(io.scalajs.nodejs.internal.CompilerSwitches.gteNodeJs12) + @inline def onKeylog(handler: (Buffer, TLSSocket) => Any): T = instance.on("keylog", handler) + + @inline def onOCSPResponse(handler: (Buffer) => Any): T = instance.on("OCSPResponse", handler) + @inline def onSecureConnect(handler: () => Any): T = instance.on("secureConnect", handler) + @inline def onSession(handler: (Buffer) => Any): T = instance.on("session", handler) + } } From 1587678df2155ebc059f85a4c01d63114a0d7db6 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 16:36:21 +0900 Subject: [PATCH 15/17] Overhaul events in tty module --- .../src/main/scala/io/scalajs/nodejs/tty/package.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/tty/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/tty/package.scala index 60471b45a..f57e4afaa 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/tty/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/tty/package.scala @@ -9,7 +9,7 @@ package object tty { * Write Stream Events * @param stream the given [[WriteStream stream]] */ - implicit final class WriteStreamEvents(val stream: WriteStream) extends AnyVal { + implicit final class WriteStreamEvents[W <: WriteStream](private val stream: W) extends AnyVal { /** * The 'resize' event is emitted whenever either of the writeStream.columns or writeStream.rows properties have @@ -17,6 +17,6 @@ package object tty { * @param listener the given event handler * @since 0.7.7 */ - def onResize(listener: () => Any): stream.type = stream.on("resize", listener) + @inline def onResize(listener: () => Any): W = stream.on("resize", listener) } } From e7b8ac67b70632f5aab3f92cd3262be9d9225518 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 16:41:16 +0900 Subject: [PATCH 16/17] Overhaul events in dgram module --- .../main/scala/io/scalajs/nodejs/dgram/Socket.scala | 8 ++++++++ .../scala/io/scalajs/nodejs/dgram/package.scala | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/dgram/Socket.scala b/app/current/src/main/scala/io/scalajs/nodejs/dgram/Socket.scala index bd225c452..34112e40d 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/dgram/Socket.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/dgram/Socket.scala @@ -131,3 +131,11 @@ trait RemoteAddress extends js.Object { var family: String = js.native var port: Int = js.native } + +@js.native +trait RemoteAddressInfo extends js.Object { + var address: String = js.native + var family: String = js.native + var port: Int = js.native + var size: Int = js.native +} diff --git a/app/current/src/main/scala/io/scalajs/nodejs/dgram/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/dgram/package.scala index ed72cf800..66ca91a59 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/dgram/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/dgram/package.scala @@ -1,5 +1,8 @@ package io.scalajs.nodejs +import com.thoughtworks.enableIf +import io.scalajs.nodejs.buffer.Buffer + import scala.scalajs.js import scala.scalajs.js.typedarray.Uint8Array import scala.scalajs.js.| @@ -8,4 +11,14 @@ package object dgram { type StringMessage = String | js.Array[String] type Message = BufferMessage | StringMessage type BufferMessage = Uint8Array | js.Array[Uint8Array] + + implicit final class SocketExtension[T <: Socket](private val instance: T) extends AnyVal { + @enableIf(io.scalajs.nodejs.internal.CompilerSwitches.gteNodeJs12) + @inline def onConnect(handler: () => Any): T = instance.on("connect", handler) + + @inline def onClose(handler: () => Any): T = instance.on("close", handler) + @inline def onError(handler: (Error) => Any): T = instance.on("error", handler) + @inline def onListening(handler: () => Any): T = instance.on("listening", handler) + @inline def onMessage(handler: (Buffer, RemoteAddressInfo) => Any): T = instance.on("message", handler) + } } From 4c43362783724213ec68bd3ab6989c590446bff8 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 22 Feb 2020 17:01:48 +0900 Subject: [PATCH 17/17] Return the receiver type --- .../io/scalajs/nodejs/events/package.scala | 6 +- .../io/scalajs/nodejs/fs/FSWatcher.scala | 8 +- .../io/scalajs/nodejs/fs/ReadStream.scala | 13 +-- .../io/scalajs/nodejs/fs/WriteStream.scala | 13 +-- .../scala/io/scalajs/nodejs/http/Agent.scala | 4 +- .../scalajs/nodejs/http/ClientRequest.scala | 18 ++-- .../scalajs/nodejs/http/IncomingMessage.scala | 6 +- .../scala/io/scalajs/nodejs/http/Server.scala | 18 ++-- .../scalajs/nodejs/http/ServerResponse.scala | 8 +- .../io/scalajs/nodejs/http/package.scala | 12 +-- .../io/scalajs/nodejs/http2/package.scala | 96 +++++++++---------- .../scala/io/scalajs/nodejs/net/Server.scala | 41 -------- .../scala/io/scalajs/nodejs/net/package.scala | 30 +++--- .../scalajs/nodejs/readline/Interface.scala | 16 ++-- .../io/scalajs/nodejs/zlib/package.scala | 2 +- 15 files changed, 120 insertions(+), 171 deletions(-) diff --git a/app/current/src/main/scala/io/scalajs/nodejs/events/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/events/package.scala index b81433a9d..e274444be 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/events/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/events/package.scala @@ -5,11 +5,11 @@ import scala.scalajs.js.| package object events { - implicit final class EventEmitterExtensions(val instance: EventEmitter) extends AnyVal { - @inline def onNewListener(listener: (String | js.Symbol, js.Function) => Any): instance.type = + implicit final class EventEmitterExtensions[T <: EventEmitter](private val instance: T) extends AnyVal { + @inline def onNewListener(listener: (String | js.Symbol, js.Function) => Any): T = instance.on("newListener", listener) - @inline def onRemoveListener(listener: (String | js.Symbol, js.Function) => Any): instance.type = + @inline def onRemoveListener(listener: (String | js.Symbol, js.Function) => Any): T = instance.on("removeListener", listener) } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/fs/FSWatcher.scala b/app/current/src/main/scala/io/scalajs/nodejs/fs/FSWatcher.scala index 23073e4be..c63f1ea8b 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/fs/FSWatcher.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/fs/FSWatcher.scala @@ -27,7 +27,7 @@ object FSWatcher { /** * File System Watcher Extensions */ - implicit final class FSWatcherExtensions(val watcher: FSWatcher) extends AnyVal { + implicit final class FSWatcherExtensions[T <: FSWatcher](private val watcher: T) extends AnyVal { /** * Emitted when something changes in a watched directory or file. See more details in fs.watch(). @@ -43,14 +43,14 @@ object FSWatcher { * @since 0.5.8 */ @inline - def onChange(listener: (String, js.Any) => Any): watcher.type = watcher.on("change", listener) + def onChange(listener: (String, js.Any) => Any): T = watcher.on("change", listener) /** * Added in Node.js v10.0.0 * @see https://nodejs.org/api/fs.html#fs_event_close */ @inline - def onClose(listener: () => Any): watcher.type = watcher.on("close", listener) + def onClose(listener: () => Any): T = watcher.on("close", listener) /** * Emitted when an error occurs. @@ -58,7 +58,7 @@ object FSWatcher { * @since 0.5.8 */ @inline - def onError(listener: Error => Any): watcher.type = watcher.on("error", listener) + def onError(listener: Error => Any): T = watcher.on("error", listener) } } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala b/app/current/src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala index 03e160298..151752dc5 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala @@ -56,7 +56,7 @@ object ReadStream { /** * Read Stream Events */ - implicit final class ReadStreamEvents(val stream: ReadStream) extends AnyVal { + implicit final class ReadStreamExtension[R <: ReadStream](private val stream: R) extends AnyVal { /** * Emitted when the ReadStream's underlying file descriptor has been closed using the fs.close() method. @@ -64,7 +64,7 @@ object ReadStream { * @since 0.1.93 */ @inline - def onClose(listener: () => Any): stream.type = stream.on("close", listener) + def onClose(listener: () => Any): R = stream.on("close", listener) /** * Emitted when the ReadStream's file is opened. @@ -75,20 +75,15 @@ object ReadStream { * @since 0.1.93 */ @inline - def onOpen(listener: FileDescriptor => Any): stream.type = stream.on("open", listener) + def onOpen(listener: FileDescriptor => Any): R = stream.on("open", listener) /** * Added in Node.js v9.11.0 * @see https://nodejs.org/api/fs.html#fs_event_ready */ @inline - def onReady(listener: () => Any): stream.type = stream.on("ready", listener) - } + def onReady(listener: () => Any): R = stream.on("ready", listener) - /** - * Read Stream Extensions - */ - implicit final class ReadStreamExtensions(val stream: ReadStream) extends AnyVal { @inline def closeFuture: Future[Unit] = promiseCallback1[Unit](stream.close) } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala b/app/current/src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala index 1b5c6db11..3686c9fbd 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala @@ -52,7 +52,7 @@ object WriteStream { /** * Write Stream Events */ - implicit final class WriteStreamEvents(val stream: WriteStream) extends AnyVal { + implicit final class WriteStreamExtension[T <: WriteStream](private val stream: T) extends AnyVal { /** * Emitted when the WriteStream's underlying file descriptor has been closed using the fs.close() method. @@ -60,7 +60,7 @@ object WriteStream { * @since 0.1.93 */ @inline - def onClose(listener: () => Any): stream.type = stream.on("close", listener) + def onClose(listener: () => Any): T = stream.on("close", listener) /** * Emitted when the WriteStream's file is opened. @@ -71,20 +71,15 @@ object WriteStream { * @since 0.1.93 */ @inline - def onOpen(listener: FileDescriptor => Any): stream.type = stream.on("open", listener) + def onOpen(listener: FileDescriptor => Any): T = stream.on("open", listener) /** * Added in Node.js v9.11.0 * @see https://nodejs.org/api/fs.html#fs_event_ready_1 */ @inline - def onReady(listener: () => Any): stream.type = stream.on("ready", listener) - } + def onReady(listener: () => Any): T = stream.on("ready", listener) - /** - * Write Stream Extensions - */ - implicit final class WriteStreamExtensions(val stream: WriteStream) extends AnyVal { @inline def closeFuture: Future[Unit] = promiseCallback1[Unit](stream.close) } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http/Agent.scala b/app/current/src/main/scala/io/scalajs/nodejs/http/Agent.scala index 5b80cd15c..bd9650aa0 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http/Agent.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http/Agent.scala @@ -97,7 +97,7 @@ object Agent { /** * Agent Extensions */ - implicit final class AgentExtensions(val agent: Agent) extends AnyVal { + implicit final class AgentExtensions[T <: Agent](private val agent: T) extends AnyVal { /** * Produces a socket/stream to be used for HTTP requests. By default, this function is the same @@ -109,6 +109,6 @@ object Agent { promiseWithError1[Error, js.Any](agent.createConnection(options, _)) } - @inline def onKeylog(handler: () => Any): agent.type = agent.on("keylog", handler) + @inline def onKeylog(handler: () => Any): T = agent.on("keylog", handler) } } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http/ClientRequest.scala b/app/current/src/main/scala/io/scalajs/nodejs/http/ClientRequest.scala index c26a5e53d..084dc85e1 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http/ClientRequest.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http/ClientRequest.scala @@ -110,13 +110,13 @@ class ClientRequest extends stream.Writable { * Client Request Companion */ object ClientRequest { - implicit final class ClientRequestExtensions(val client: ClientRequest) extends AnyVal { + implicit final class ClientRequestExtensions[T <: ClientRequest](private val client: T) extends AnyVal { /** * Emitted when the request has been aborted by the client. This event is only emitted on the first call to abort(). */ @inline - def onAbort(callback: () => Any): client.type = client.on("abort", callback) + def onAbort(callback: () => Any): T = client.on("abort", callback) /** * Emitted each time a server responds to a request with a CONNECT method. If this event is not being listened for, @@ -126,17 +126,17 @@ object ClientRequest { * - head */ @inline - def onConnect(callback: (IncomingMessage, Duplex, Buffer) => Any): client.type = client.on("connect", callback) + def onConnect(callback: (IncomingMessage, Duplex, Buffer) => Any): T = client.on("connect", callback) /** * Emitted when the server sends a '100 Continue' HTTP response, usually because the request * contained 'Expect: 100-continue'. This is an instruction that the client should send the request body. */ @inline - def onContinue(callback: () => Any): client.type = client.on("continue", callback) + def onContinue(callback: () => Any): T = client.on("continue", callback) @inline - def onInformation(callback: Information => Any): client.type = client.on("information", callback) + def onInformation(callback: Information => Any): T = client.on("information", callback) /** * Emitted when a response is received to this request. This event is emitted only once. @@ -144,17 +144,17 @@ object ClientRequest { * - response */ @inline - def onResponse(callback: IncomingMessage => Any): client.type = client.on("response", callback) + def onResponse(callback: IncomingMessage => Any): T = client.on("response", callback) /** * Emitted after a socket is assigned to this request. * - socket */ @inline - def onSocket(callback: Duplex => Any): client.type = client.on("socket", callback) + def onSocket(callback: Duplex => Any): T = client.on("socket", callback) @inline - def onTimeout(callback: () => Any): client.type = client.on("timeout", callback) + def onTimeout(callback: () => Any): T = client.on("timeout", callback) /** * Emitted each time a server responds to a request with an upgrade. If this event isn't being listened for, @@ -164,7 +164,7 @@ object ClientRequest { * - head */ @inline - def onUpgrade(callback: (IncomingMessage, Socket, Buffer) => Any): client.type = client.on("upgrade", callback) + def onUpgrade(callback: (IncomingMessage, Socket, Buffer) => Any): T = client.on("upgrade", callback) @inline def endFuture(data: Uint8Array): Future[Unit] = { diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http/IncomingMessage.scala b/app/current/src/main/scala/io/scalajs/nodejs/http/IncomingMessage.scala index 5dd45fc76..b293644f0 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http/IncomingMessage.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http/IncomingMessage.scala @@ -101,12 +101,12 @@ object IncomingMessage { /** * Incoming Message Extensions */ - implicit final class IncomingMessageExtensions(val message: IncomingMessage) extends AnyVal { + implicit final class IncomingMessageExtension[T <: IncomingMessage](private val message: T) extends AnyVal { @inline - def onAborted(callback: () => Any): message.type = message.on("aborted", callback) + def onAborted(callback: () => Any): T = message.on("aborted", callback) @inline - def onClose(callback: () => Any): message.type = message.on("close", callback) + def onClose(callback: () => Any): T = message.on("close", callback) @inline def setTimeout(duration: FiniteDuration, callback: js.Function): Unit = diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http/Server.scala b/app/current/src/main/scala/io/scalajs/nodejs/http/Server.scala index e9b4496ed..28c4f4285 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http/Server.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http/Server.scala @@ -32,7 +32,7 @@ object Server { * Server Events * @param server the given [[Server]] */ - implicit final class ServerEvents(val server: Server) extends AnyVal { + implicit final class ServerEvents[T <: Server](private val server: T) extends AnyVal { /** * Emitted each time a request with an HTTP Expect: 100-continue is received. If this event is not listened for, @@ -45,7 +45,7 @@ object Server { * - response */ @inline - def onCheckContinue(callback: (IncomingMessage, ServerResponse) => Any): server.type = { + def onCheckContinue(callback: (IncomingMessage, ServerResponse) => Any): T = { server.on("checkContinue", callback) } @@ -57,7 +57,7 @@ object Server { * - response */ @inline - def onCheckExpectation(callback: (IncomingMessage, ServerResponse) => Any): server.type = { + def onCheckExpectation(callback: (IncomingMessage, ServerResponse) => Any): T = { server.on("checkExpectation", callback) } @@ -71,13 +71,13 @@ object Server { * - socket */ @inline - def onClientError(callback: (nodejs.Error, Duplex) => Any): server.type = server.on("clientError", callback) + def onClientError(callback: (nodejs.Error, Duplex) => Any): T = server.on("clientError", callback) /** * Emitted when the server closes. */ @inline - def onClose(handler: () => Any): server.type = server.on("close", handler) + def onClose(handler: () => Any): T = server.on("close", handler) /** * Emitted each time a client requests an HTTP CONNECT method. If this event is not listened for, then clients @@ -90,7 +90,7 @@ object Server { * - head The first packet of the tunneling stream (may be empty) */ @inline - def onConnect(handler: (IncomingMessage, Duplex, Buffer) => Any): server.type = server.on("connect", handler) + def onConnect(handler: (IncomingMessage, Duplex, Buffer) => Any): T = server.on("connect", handler) /** * When a new TCP stream is established. socket is an object of type net.Socket. Usually users will not want @@ -99,7 +99,7 @@ object Server { * - socket */ @inline - def onConnection(handler: Duplex => Any): server.type = server.on("connection", handler) + def onConnection(handler: Duplex => Any): T = server.on("connection", handler) /** * Emitted each time there is a request. Note that there may be multiple requests per connection (in the case @@ -108,7 +108,7 @@ object Server { * - response */ @inline - def onRequest(handler: (IncomingMessage, ServerResponse) => Any): server.type = server.on("request", handler) + def onRequest(handler: (IncomingMessage, ServerResponse) => Any): T = server.on("request", handler) /** * Emitted each time a client requests an HTTP upgrade. If this event is not listened for, then clients @@ -121,6 +121,6 @@ object Server { * - head The first packet of the upgraded stream (may be empty) */ @inline - def onUpgrade(handler: (IncomingMessage, Duplex, Buffer) => Any): server.type = server.on("upgrade", handler) + def onUpgrade(handler: (IncomingMessage, Duplex, Buffer) => Any): T = server.on("upgrade", handler) } } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http/ServerResponse.scala b/app/current/src/main/scala/io/scalajs/nodejs/http/ServerResponse.scala index af9371443..3076c4c6f 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http/ServerResponse.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http/ServerResponse.scala @@ -144,15 +144,15 @@ object ServerResponse { /** * Server Response Events */ - implicit final class ServerResponseExtensions(val response: ServerResponse) extends AnyVal { + implicit final class ServerResponseExtensions[T <: ServerResponse](private val response: T) extends AnyVal { @inline - def onData(handler: Buffer => Any): response.type = response.on("data", handler) + def onData(handler: Buffer => Any): T = response.on("data", handler) @inline - def onClose(handler: () => Any): response.type = response.on("close", handler) + def onClose(handler: () => Any): T = response.on("close", handler) @inline - def onFinish(handler: () => Any): response.type = response.on("finish", handler) + def onFinish(handler: () => Any): T = response.on("finish", handler) /** * Sets the content-type for the response diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/http/package.scala index df56c5b4e..5da73d233 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http/package.scala @@ -63,7 +63,7 @@ package object http { /** * Server Events */ - implicit final class ServerEvents(val server: Server) extends AnyVal { + implicit final class ServerExtensions[T <: Server](private val server: T) extends AnyVal { /** * Emitted each time a request with an http Expect: 100-continue is received. If this event isn't listened for, @@ -77,7 +77,7 @@ package object http { * @example server.on("checkContinue", function (request, response) { ... }) */ @inline - def onCheckContinue(callback: (ClientRequest, ServerResponse) => Any): server.type = + def onCheckContinue(callback: (ClientRequest, ServerResponse) => Any): T = server.on("checkContinue", callback) /** @@ -91,10 +91,10 @@ package object http { * @example server.on("clientError", function (exception, socket) { ... }) */ @inline - def onClientError(callback: (SystemError, Socket) => Any): server.type = server.on("clientError", callback) + def onClientError(callback: (SystemError, Socket) => Any): T = server.on("clientError", callback) @inline - def onConnect(callback: js.Function): server.type = server.on("connect", callback) + def onConnect(callback: js.Function): T = server.on("connect", callback) @inline def closeFuture(): Future[Unit] = promiseWithError0[SystemError](server.close) @@ -106,9 +106,9 @@ package object http { def listenFuture(options: ListenerOptions): Future[Unit] = promiseWithError0[SystemError](server.listen(options, _)) @inline - def onRequest(callback: js.Function): server.type = server.on("request", callback) + def onRequest(callback: js.Function): T = server.on("request", callback) @inline - def onUpgrade(callback: js.Function): server.type = server.on("upgrade", callback) + def onUpgrade(callback: js.Function): T = server.on("upgrade", callback) } } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/http2/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/http2/package.scala index 25f9eed2c..8427612b6 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/http2/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/http2/package.scala @@ -10,75 +10,75 @@ package object http2 { type Origin = String | URL | HasOrigin type Path = String | Buffer | URL - implicit final class Http2SessionExtension(val instance: Http2Session) extends AnyVal { - @inline def onClose(handler: () => Any): instance.type = instance.on("close", handler) - @inline def onConnect(handler: (Http2Session, net.Socket) => Any): instance.type = instance.on("connect", handler) - @inline def onError(handler: (Error) => Any): instance.type = instance.on("error", handler) - @inline def onFrameError(handler: (Int, Int, Int) => Any): instance.type = instance.on("frameError", handler) - @inline def onGoaway(handler: (Int, Int, Buffer) => Any): instance.type = instance.on("goaway", handler) - @inline def onLocalSettings(handler: Http2Settings => Any): instance.type = instance.on("localSettings", handler) - @inline def onPing(handler: (Buffer) => Any): instance.type = instance.on("ping", handler) - @inline def onRemoteSettings(handler: (Http2Settings) => Any): instance.type = + implicit final class Http2SessionExtension[T <: Http2Session](private val instance: T) extends AnyVal { + @inline def onClose(handler: () => Any): T = instance.on("close", handler) + @inline def onConnect(handler: (Http2Session, net.Socket) => Any): T = instance.on("connect", handler) + @inline def onError(handler: (Error) => Any): T = instance.on("error", handler) + @inline def onFrameError(handler: (Int, Int, Int) => Any): T = instance.on("frameError", handler) + @inline def onGoaway(handler: (Int, Int, Buffer) => Any): T = instance.on("goaway", handler) + @inline def onLocalSettings(handler: Http2Settings => Any): T = instance.on("localSettings", handler) + @inline def onPing(handler: (Buffer) => Any): T = instance.on("ping", handler) + @inline def onRemoteSettings(handler: (Http2Settings) => Any): T = instance.on("remoteSettings", handler) - @inline def onStream(handler: (Http2Stream, Http2Headers, Int, js.Array[String]) => Any): instance.type = + @inline def onStream(handler: (Http2Stream, Http2Headers, Int, js.Array[String]) => Any): T = instance.on("stream", handler) - @inline def onTimeout(handler: () => Any): instance.type = instance.on("timeout", handler) + @inline def onTimeout(handler: () => Any): T = instance.on("timeout", handler) } - implicit final class ClientHttp2SessionExtension(val instance: ClientHttp2Session) extends AnyVal { - @inline def onAltsvc(handler: (String, String, Int) => Any): instance.type = instance.on("altsvc", handler) - @inline def onOrigin(handler: (js.Array[String]) => Any): instance.type = instance.on("origin", handler) + implicit final class ClientHttp2SessionExtensions[T <: ClientHttp2Session](private val instance: T) extends AnyVal { + @inline def onAltsvc(handler: (String, String, Int) => Any): T = instance.on("altsvc", handler) + @inline def onOrigin(handler: (js.Array[String]) => Any): T = instance.on("origin", handler) } - implicit final class Http2StreamExtension(val instance: Http2Stream) extends AnyVal { - @inline def onAborted(handler: () => Any): instance.type = instance.on("aborted", handler) - @inline def onClose(handler: () => Any): instance.type = instance.on("close", handler) - @inline def onError(handler: (Error) => Any): instance.type = instance.on("error", handler) - @inline def onFrameError(handler: (Int, Int, Int) => Any): instance.type = instance.on("frameError", handler) - @inline def onTimeout(handler: () => Any): instance.type = instance.on("timeout", handler) - @inline def onTrailers(handler: (Http2Headers, Int) => Any): instance.type = instance.on("trailers", handler) - @inline def onWantTrailers(handler: () => Any): instance.type = instance.on("wantTrailers", handler) + implicit final class Http2StreamExtensions[T <: Http2Stream](private val instance: T) extends AnyVal { + @inline def onAborted(handler: () => Any): T = instance.on("aborted", handler) + @inline def onClose(handler: () => Any): T = instance.on("close", handler) + @inline def onError(handler: (Error) => Any): T = instance.on("error", handler) + @inline def onFrameError(handler: (Int, Int, Int) => Any): T = instance.on("frameError", handler) + @inline def onTimeout(handler: () => Any): T = instance.on("timeout", handler) + @inline def onTrailers(handler: (Http2Headers, Int) => Any): T = instance.on("trailers", handler) + @inline def onWantTrailers(handler: () => Any): T = instance.on("wantTrailers", handler) } - implicit final class ClientHttp2StreamExtension(val instance: ClientHttp2Stream) extends AnyVal { - @inline def onContinue(handler: () => Any): instance.type = instance.on("continue", handler) - @inline def onHeaders(handler: (Http2Headers, Int) => Any): instance.type = instance.on("headers", handler) - @inline def onPush(handler: (Http2Headers, Int) => Any): instance.type = instance.on("push", handler) - @inline def onResponse(handler: (Http2Headers, Int) => Any): instance.type = instance.on("response", handler) + implicit final class ClientHttp2StreamExtension[T <: ClientHttp2Stream](private val instance: T) extends AnyVal { + @inline def onContinue(handler: () => Any): T = instance.on("continue", handler) + @inline def onHeaders(handler: (Http2Headers, Int) => Any): T = instance.on("headers", handler) + @inline def onPush(handler: (Http2Headers, Int) => Any): T = instance.on("push", handler) + @inline def onResponse(handler: (Http2Headers, Int) => Any): T = instance.on("response", handler) } - implicit final class Http2SeverExtension(val instance: Http2Server) extends AnyVal { - @inline def onCheckContinue(handler: (Http2ServerRequest, Http2ServerResponse) => Any): instance.type = + implicit final class Http2SeverExtension[T <: Http2Server](private val instance: T) extends AnyVal { + @inline def onCheckContinue(handler: (Http2ServerRequest, Http2ServerResponse) => Any): T = instance.on("checkContinue", handler) - @inline def onRequest(handler: (Http2ServerRequest, Http2ServerResponse) => Any): instance.type = + @inline def onRequest(handler: (Http2ServerRequest, Http2ServerResponse) => Any): T = instance.on("request", handler) - @inline def onSession(handler: () => Any): instance.type = instance.on("session", handler) - @inline def onSessionError(handler: () => Any): instance.type = instance.on("sessionError", handler) - @inline def onStream(handler: (Http2Stream, Http2Headers, Int) => Any): instance.type = + @inline def onSession(handler: () => Any): T = instance.on("session", handler) + @inline def onSessionError(handler: () => Any): T = instance.on("sessionError", handler) + @inline def onStream(handler: (Http2Stream, Http2Headers, Int) => Any): T = instance.on("stream", handler) - @inline def onTimeout(handler: () => Any): instance.type = instance.on("timeout", handler) + @inline def onTimeout(handler: () => Any): T = instance.on("timeout", handler) } - implicit final class Http2SecureSeverExtension(val instance: Http2SecureServer) extends AnyVal { - @inline def onCheckContinue(handler: (Http2ServerRequest, Http2ServerResponse) => Any): instance.type = + implicit final class Http2SecureSeverExtension[T <: Http2SecureServer](private val instance: T) extends AnyVal { + @inline def onCheckContinue(handler: (Http2ServerRequest, Http2ServerResponse) => Any): T = instance.on("checkContinue", handler) - @inline def onRequest(handler: (Http2ServerRequest, Http2ServerResponse) => Any): instance.type = + @inline def onRequest(handler: (Http2ServerRequest, Http2ServerResponse) => Any): T = instance.on("request", handler) - @inline def onSession(handler: () => Any): instance.type = instance.on("session", handler) - @inline def onSessionError(handler: () => Any): instance.type = instance.on("sessionError", handler) - @inline def onStream(handler: (Http2Stream, Http2Headers, Int) => Any): instance.type = + @inline def onSession(handler: () => Any): T = instance.on("session", handler) + @inline def onSessionError(handler: () => Any): T = instance.on("sessionError", handler) + @inline def onStream(handler: (Http2Stream, Http2Headers, Int) => Any): T = instance.on("stream", handler) - @inline def onTimeout(handler: () => Any): instance.type = instance.on("timeout", handler) - @inline def onUnknownProtocol(handler: () => Any): instance.type = instance.on("unknownProtocol", handler) + @inline def onTimeout(handler: () => Any): T = instance.on("timeout", handler) + @inline def onUnknownProtocol(handler: () => Any): T = instance.on("unknownProtocol", handler) } - implicit final class Http2ServerRequestExtension(val instance: Http2ServerRequest) extends AnyVal { - @inline def onAborted(handler: (stream.IReadable) => Any): instance.type = instance.on("aborted", handler) - @inline def onClose(handler: () => Any): instance.type = instance.on("close", handler) + implicit final class Http2ServerRequestExtension[T <: Http2ServerRequest](private val instance: T) extends AnyVal { + @inline def onAborted(handler: (stream.IReadable) => Any): T = instance.on("aborted", handler) + @inline def onClose(handler: () => Any): T = instance.on("close", handler) } - implicit final class Http2ServerResponseExtension(val instance: Http2ServerResponse) extends AnyVal { - @inline def onClose(handler: () => Any): instance.type = instance.on("close", handler) - @inline def onAborted(handler: (stream.IReadable) => Any): instance.type = instance.on("aborted", handler) + implicit final class Http2ServerResponseExtension[T <: Http2ServerResponse](private val instance: T) extends AnyVal { + @inline def onClose(handler: () => Any): T = instance.on("close", handler) + @inline def onAborted(handler: (stream.IReadable) => Any): T = instance.on("aborted", handler) } } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/net/Server.scala b/app/current/src/main/scala/io/scalajs/nodejs/net/Server.scala index 5e6cad98d..aff2cbbbe 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/net/Server.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/net/Server.scala @@ -93,44 +93,3 @@ class Server(options: ServerOptions = js.native) extends IEventEmitter { */ def unref(): this.type = js.native } - -/** - * Server Companion - */ -object Server extends { - - /** - * Server Events - * @param server the given [[Server]] - */ - implicit final class ServerEvents(val server: Server) extends AnyVal { - - /** - * Emitted when the server closes. Note that if connections exist, this event is not emitted until all - * connections are ended. - */ - @inline - def onClose(handler: () => Any): server.type = server.on("close", handler) - - /** - * Emitted when a new connection is made. socket is an instance of net.Socket. - * - The connection object - */ - @inline - def onConnection(handler: Socket => Any): server.type = server.on("connection", handler) - - /** - * Emitted when an error occurs. The 'close' event will be called directly following this event. - * See example in discussion of server.listen. - * - - */ - @inline - def onError(handler: SystemError => Any): server.type = server.on("error", handler) - - /** - * Emitted when the server has been bound after calling server.listen. - */ - @inline - def onListening(handler: () => Any): server.type = server.on("listening", handler) - } -} diff --git a/app/current/src/main/scala/io/scalajs/nodejs/net/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/net/package.scala index 389986056..0539b3207 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/net/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/net/package.scala @@ -17,35 +17,35 @@ package object net { * net.Server Events * @param server the given [[Server server]] */ - implicit final class ServerEvents(val server: Server) extends AnyVal { + implicit final class ServerExtensions[T <: Server](private val server: T) extends AnyVal { /** * Emitted when a new connection is made. socket is an instance of net.Socket. * @example server.on("close", function () { ... }) */ - @inline def onClose(callback: () => Any): server.type = server.on("close", callback) + @inline def onClose(callback: () => Any): T = server.on("close", callback) /** * Emitted when a new connection is made. socket is an instance of net.Socket. */ - @inline def onConnection(callback: js.Function): server.type = server.on("connection", callback) + @inline def onConnection(callback: js.Function): T = server.on("connection", callback) /** * Emitted when an error occurs. The 'close' event will be called directly following this event. */ - @inline def onError(callback: Error => Any): server.type = server.on("error", callback) + @inline def onError(callback: Error => Any): T = server.on("error", callback) /** * Emitted when the server has been bound after calling server.listen. */ - @inline def onListening(callback: js.Function): server.type = server.on("listening", callback) + @inline def onListening(callback: js.Function): T = server.on("listening", callback) } /** * net.Socket Extensions * @param socket the given [[Socket socket]] */ - implicit final class SocketExtensions(val socket: Socket) extends AnyVal { + implicit final class SocketExtensions[T <: Socket](private val socket: T) extends AnyVal { ///////////////////////////////////////////////////////////////////////////////// // Futures ///////////////////////////////////////////////////////////////////////////////// @@ -84,14 +84,14 @@ package object net { * @param callback - had_error true if the socket had a transmission error. * @example socket.on("close", function(had_error) { ... }) */ - @inline def onClose(callback: Boolean => Any): socket.type = socket.on("close", callback) + @inline def onClose(callback: Boolean => Any): T = socket.on("close", callback) /** * Emitted when a socket connection is successfully established. See connect(). * @param callback the callback * @example socket.on("connect", function() { ... }) */ - @inline def onConnect(callback: () => Any): socket.type = socket.on("connect", callback) + @inline def onConnect(callback: () => Any): T = socket.on("connect", callback) /** * Emitted when data is received. The argument data will be a Buffer or String. Encoding of data is set by @@ -101,7 +101,7 @@ package object net { * @param callback - * @example socket.on("data", function(buffer) { ... }) */ - @inline def onData(callback: Buffer | String => Any): socket.type = socket.on("data", callback) + @inline def onData(callback: Buffer | String => Any): T = socket.on("data", callback) /** * Emitted when the write buffer becomes empty. Can be used to throttle uploads. @@ -110,7 +110,7 @@ package object net { * @param callback the callback * @example socket.on("drain", function(???) { ... }) */ - @inline def onDrain(callback: () => Any): socket.type = socket.on("drain", callback) + @inline def onDrain(callback: () => Any): T = socket.on("drain", callback) /** * Emitted when the other end of the socket sends a FIN packet. @@ -122,9 +122,9 @@ package object net { * @param callback the callback * @example socket.on("end", function(???) { ... }) */ - @inline def onEnd(callback: () => Any): socket.type = socket.on("end", callback) + @inline def onEnd(callback: () => Any): T = socket.on("end", callback) - @inline def onError(callback: (Error) => Any): socket.type = socket.on("error", callback) + @inline def onError(callback: (Error) => Any): T = socket.on("error", callback) /** * Emitted after resolving the hostname but before connecting. Not applicable to UNIX sockets. @@ -137,9 +137,9 @@ package object net { * * @example socket.on("lookup", function(err, address, family, host) { ... }) */ - @inline def onLookup(callback: (Error, String, String, String) => Any): socket.type = socket.on("lookup", callback) + @inline def onLookup(callback: (Error, String, String, String) => Any): T = socket.on("lookup", callback) - @inline def onReady(callback: () => Any): socket.type = socket.on("ready", callback) + @inline def onReady(callback: () => Any): T = socket.on("ready", callback) /** * Emitted if the socket times out from inactivity. This is only to notify that the socket has been idle. The user @@ -149,6 +149,6 @@ package object net { * @param callback the callback * @example socket.on("timeout", function(???) { ... }) */ - @inline def onTimeout(callback: js.Function): socket.type = socket.on("timeout", callback) + @inline def onTimeout(callback: js.Function): T = socket.on("timeout", callback) } } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala b/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala index 803199f69..24cff67f7 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/readline/Interface.scala @@ -100,7 +100,7 @@ object Interface { * Readline Interface Events * @param readline the given [[Interface Readline Interface]] */ - implicit final class ReadlineEvents(val readline: Interface) extends AnyVal { + implicit final class InterfaceEvents[T <: Interface](private val readline: T) extends AnyVal { /** * Emitted when close() is called. Also emitted when the input stream receives its 'end' event. @@ -108,27 +108,27 @@ object Interface { * the input stream receives {{{ ^D }}}, respectively known as EOT. */ @inline - def onClose(callback: () => Any) = readline.on("close", callback) + def onClose(callback: () => Any): T = readline.on("close", callback) /** * Emitted whenever the input stream receives an end of line (\n, \r, or \r\n), usually received when * the user hits enter, or return. This is a good hook to listen for user input. */ @inline - def onLine(callback: String => Any) = readline.on("line", callback) + def onLine(callback: String => Any): T = readline.on("line", callback) /** * Emitted whenever the input stream is paused. Also emitted whenever the input stream is not paused * and receives the SIGCONT event. (See events SIGTSTP and SIGCONT) */ @inline - def onPause(callback: () => Any) = readline.on("pause", callback) + def onPause(callback: () => Any): T = readline.on("pause", callback) /** * Emitted whenever the input stream is resumed. */ @inline - def onResume(callback: () => Any) = readline.on("resume", callback) + def onResume(callback: () => Any): T = readline.on("resume", callback) /** * Emitted whenever the input stream is sent to the background with {{{ ^Z }}}, respectively known as SIGTSTP, @@ -136,14 +136,14 @@ object Interface { * program to the background. */ @inline - def onSIGCONT(callback: () => Any) = readline.on("SIGCONT", callback) + def onSIGCONT(callback: () => Any): T = readline.on("SIGCONT", callback) /** * Emitted whenever the input stream receives a {{{ ^C }}}, respectively known as SIGINT. If there is no * SIGINT event listener present when the input stream receives a SIGINT, pause will be triggered. */ @inline - def onSIGINT(callback: () => Any) = readline.on("SIGINT", callback) + def onSIGINT(callback: () => Any): T = readline.on("SIGINT", callback) /** * Emitted whenever the input stream receives a {{{ ^Z }}}, respectively known as SIGTSTP. If there is no @@ -153,6 +153,6 @@ object Interface { * stream was paused before the program was sent to the background. */ @inline - def onSIGTSTP(callback: () => Any) = readline.on("SIGTSTP", callback) + def onSIGTSTP(callback: () => Any): T = readline.on("SIGTSTP", callback) } } diff --git a/app/current/src/main/scala/io/scalajs/nodejs/zlib/package.scala b/app/current/src/main/scala/io/scalajs/nodejs/zlib/package.scala index b9da12d42..0f3a999d6 100644 --- a/app/current/src/main/scala/io/scalajs/nodejs/zlib/package.scala +++ b/app/current/src/main/scala/io/scalajs/nodejs/zlib/package.scala @@ -23,7 +23,7 @@ package object zlib { /** * Zlib Extensions */ - implicit final class ZlibExtensions(val zlib: Zlib) extends AnyVal { + implicit final class ZlibExtensions[T <: Zlib](private val zlib: T) extends AnyVal { /** * Asynchronously compresses a Buffer or string with Deflate.