Skip to content
This repository was archived by the owner on Jul 30, 2024. It is now read-only.

Commit 70b640b

Browse files
authored
Merge pull request #176 from exoego/event-handler
Overhaul event handler exntensions
2 parents b716353 + 4c43362 commit 70b640b

28 files changed

+320
-235
lines changed

app/current/src/main/scala/io/scalajs/nodejs/child_process/package.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,19 @@ package object child_process {
3636

3737
// TODO: spawn, fork
3838
}
39+
40+
implicit final class ChildProcessClassExtension(private val cp: ChildProcess) extends AnyVal {
41+
@inline
42+
def onClose(listener: (Int, String) => Any): ChildProcess = cp.on("close", listener)
43+
44+
@inline
45+
def onDisconnect(listener: () => Any): ChildProcess = cp.on("disconnect", listener)
46+
47+
@inline
48+
def onError(listener: (js.Error) => Any): ChildProcess = cp.on("error", listener)
49+
50+
@inline
51+
def onMessage(listener: (js.Any, js.UndefOr[net.Socket | net.Server]) => Any): ChildProcess =
52+
cp.on("message", listener)
53+
}
3954
}

app/current/src/main/scala/io/scalajs/nodejs/cluster/package.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ package object cluster {
148148
* </ul>
149149
*/
150150
@inline
151-
def onExit(callback: (Worker, Int, String) => Any): Worker = worker.on("exit", callback)
151+
def onExit(callback: (Int, String) => Any): Worker = worker.on("exit", callback)
152152

153153
/**
154154
* Similar to the cluster.on('listening') event, but specific to this worker.
@@ -164,7 +164,7 @@ package object cluster {
164164
* @param callback the event handler
165165
*/
166166
@inline
167-
def onMessage(callback: Message => Any): Worker = worker.on("message", callback)
167+
def onMessage(callback: Message => Any, handle: js.UndefOr[js.Object]): Worker = worker.on("message", callback)
168168

169169
/**
170170
* Similar to the cluster.on('online') event, but specific to this worker.

app/current/src/main/scala/io/scalajs/nodejs/dgram/Socket.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,11 @@ trait RemoteAddress extends js.Object {
131131
var family: String = js.native
132132
var port: Int = js.native
133133
}
134+
135+
@js.native
136+
trait RemoteAddressInfo extends js.Object {
137+
var address: String = js.native
138+
var family: String = js.native
139+
var port: Int = js.native
140+
var size: Int = js.native
141+
}

app/current/src/main/scala/io/scalajs/nodejs/dgram/package.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package io.scalajs.nodejs
22

3+
import com.thoughtworks.enableIf
4+
import io.scalajs.nodejs.buffer.Buffer
5+
36
import scala.scalajs.js
47
import scala.scalajs.js.typedarray.Uint8Array
58
import scala.scalajs.js.|
@@ -8,4 +11,14 @@ package object dgram {
811
type StringMessage = String | js.Array[String]
912
type Message = BufferMessage | StringMessage
1013
type BufferMessage = Uint8Array | js.Array[Uint8Array]
14+
15+
implicit final class SocketExtension[T <: Socket](private val instance: T) extends AnyVal {
16+
@enableIf(io.scalajs.nodejs.internal.CompilerSwitches.gteNodeJs12)
17+
@inline def onConnect(handler: () => Any): T = instance.on("connect", handler)
18+
19+
@inline def onClose(handler: () => Any): T = instance.on("close", handler)
20+
@inline def onError(handler: (Error) => Any): T = instance.on("error", handler)
21+
@inline def onListening(handler: () => Any): T = instance.on("listening", handler)
22+
@inline def onMessage(handler: (Buffer, RemoteAddressInfo) => Any): T = instance.on("message", handler)
23+
}
1124
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.scalajs.nodejs
2+
3+
import scala.scalajs.js
4+
import scala.scalajs.js.|
5+
6+
package object events {
7+
8+
implicit final class EventEmitterExtensions[T <: EventEmitter](private val instance: T) extends AnyVal {
9+
@inline def onNewListener(listener: (String | js.Symbol, js.Function) => Any): T =
10+
instance.on("newListener", listener)
11+
12+
@inline def onRemoveListener(listener: (String | js.Symbol, js.Function) => Any): T =
13+
instance.on("removeListener", listener)
14+
}
15+
16+
}

app/current/src/main/scala/io/scalajs/nodejs/fs/FSWatcher.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ object FSWatcher {
2727
/**
2828
* File System Watcher Extensions
2929
*/
30-
implicit final class FSWatcherExtensions(val watcher: FSWatcher) extends AnyVal {
30+
implicit final class FSWatcherExtensions[T <: FSWatcher](private val watcher: T) extends AnyVal {
3131

3232
/**
3333
* Emitted when something changes in a watched directory or file. See more details in fs.watch().
@@ -43,15 +43,22 @@ object FSWatcher {
4343
* @since 0.5.8
4444
*/
4545
@inline
46-
def onChange(listener: (String, js.Any) => Any): watcher.type = watcher.on("change", listener)
46+
def onChange(listener: (String, js.Any) => Any): T = watcher.on("change", listener)
47+
48+
/**
49+
* Added in Node.js v10.0.0
50+
* @see https://nodejs.org/api/fs.html#fs_event_close
51+
*/
52+
@inline
53+
def onClose(listener: () => Any): T = watcher.on("close", listener)
4754

4855
/**
4956
* Emitted when an error occurs.
5057
* @param listener the event handler
5158
* @since 0.5.8
5259
*/
5360
@inline
54-
def onError(listener: Error => Any): watcher.type = watcher.on("error", listener)
61+
def onError(listener: Error => Any): T = watcher.on("error", listener)
5562
}
5663
}
5764

app/current/src/main/scala/io/scalajs/nodejs/fs/ReadStream.scala

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,15 @@ object ReadStream {
5656
/**
5757
* Read Stream Events
5858
*/
59-
implicit final class ReadStreamEvents(val stream: ReadStream) extends AnyVal {
59+
implicit final class ReadStreamExtension[R <: ReadStream](private val stream: R) extends AnyVal {
6060

6161
/**
6262
* Emitted when the ReadStream's underlying file descriptor has been closed using the fs.close() method.
6363
* @param listener the event handler
6464
* @since 0.1.93
6565
*/
6666
@inline
67-
def onClose(listener: () => Any): stream.type = stream.on("close", listener)
67+
def onClose(listener: () => Any): R = stream.on("close", listener)
6868

6969
/**
7070
* Emitted when the ReadStream's file is opened.
@@ -75,13 +75,15 @@ object ReadStream {
7575
* @since 0.1.93
7676
*/
7777
@inline
78-
def onOpen(listener: FileDescriptor => Any): stream.type = stream.on("open", listener)
79-
}
78+
def onOpen(listener: FileDescriptor => Any): R = stream.on("open", listener)
79+
80+
/**
81+
* Added in Node.js v9.11.0
82+
* @see https://nodejs.org/api/fs.html#fs_event_ready
83+
*/
84+
@inline
85+
def onReady(listener: () => Any): R = stream.on("ready", listener)
8086

81-
/**
82-
* Read Stream Extensions
83-
*/
84-
implicit final class ReadStreamExtensions(val stream: ReadStream) extends AnyVal {
8587
@inline
8688
def closeFuture: Future[Unit] = promiseCallback1[Unit](stream.close)
8789
}

app/current/src/main/scala/io/scalajs/nodejs/fs/WriteStream.scala

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ object WriteStream {
5252
/**
5353
* Write Stream Events
5454
*/
55-
implicit final class WriteStreamEvents(val stream: WriteStream) extends AnyVal {
55+
implicit final class WriteStreamExtension[T <: WriteStream](private val stream: T) extends AnyVal {
5656

5757
/**
5858
* Emitted when the WriteStream's underlying file descriptor has been closed using the fs.close() method.
5959
* @param listener the event handler
6060
* @since 0.1.93
6161
*/
6262
@inline
63-
def onClose(listener: () => Any): stream.type = stream.on("close", listener)
63+
def onClose(listener: () => Any): T = stream.on("close", listener)
6464

6565
/**
6666
* Emitted when the WriteStream's file is opened.
@@ -71,13 +71,15 @@ object WriteStream {
7171
* @since 0.1.93
7272
*/
7373
@inline
74-
def onOpen(listener: FileDescriptor => Any): stream.type = stream.on("open", listener)
75-
}
74+
def onOpen(listener: FileDescriptor => Any): T = stream.on("open", listener)
75+
76+
/**
77+
* Added in Node.js v9.11.0
78+
* @see https://nodejs.org/api/fs.html#fs_event_ready_1
79+
*/
80+
@inline
81+
def onReady(listener: () => Any): T = stream.on("ready", listener)
7682

77-
/**
78-
* Write Stream Extensions
79-
*/
80-
implicit final class WriteStreamExtensions(val stream: WriteStream) extends AnyVal {
8183
@inline
8284
def closeFuture: Future[Unit] = promiseCallback1[Unit](stream.close)
8385
}

app/current/src/main/scala/io/scalajs/nodejs/http/Agent.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ object Agent {
9797
/**
9898
* Agent Extensions
9999
*/
100-
implicit final class AgentExtensions(val agent: Agent) extends AnyVal {
100+
implicit final class AgentExtensions[T <: Agent](private val agent: T) extends AnyVal {
101101

102102
/**
103103
* Produces a socket/stream to be used for HTTP requests. By default, this function is the same
@@ -109,6 +109,6 @@ object Agent {
109109
promiseWithError1[Error, js.Any](agent.createConnection(options, _))
110110
}
111111

112-
@inline def onKeylog(handler: () => Any): agent.type = agent.on("keylog", handler)
112+
@inline def onKeylog(handler: () => Any): T = agent.on("keylog", handler)
113113
}
114114
}

app/current/src/main/scala/io/scalajs/nodejs/http/ClientRequest.scala

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package http
33

44
import io.scalajs.nodejs.buffer.Buffer
55
import io.scalajs.nodejs.net.Socket
6+
import io.scalajs.nodejs.stream.Duplex
67
import io.scalajs.util.PromiseHelper._
78

89
import scala.concurrent.Future
@@ -109,51 +110,51 @@ class ClientRequest extends stream.Writable {
109110
* Client Request Companion
110111
*/
111112
object ClientRequest {
112-
implicit final class ClientRequestExtensions(val client: ClientRequest) extends AnyVal {
113+
implicit final class ClientRequestExtensions[T <: ClientRequest](private val client: T) extends AnyVal {
113114

114115
/**
115116
* Emitted when the request has been aborted by the client. This event is only emitted on the first call to abort().
116117
*/
117118
@inline
118-
def onAbort(callback: () => Any): client.type = client.on("abort", callback)
119-
120-
/**
121-
* Emitted when the request has been aborted by the server and the network socket has closed.
122-
*/
123-
@inline
124-
def onAborted(callback: () => Any): client.type = client.on("aborted", callback)
119+
def onAbort(callback: () => Any): T = client.on("abort", callback)
125120

126121
/**
127122
* Emitted each time a server responds to a request with a CONNECT method. If this event is not being listened for,
128123
* clients receiving a CONNECT method will have their connections closed.
129124
* - response <http.IncomingMessage>
130-
* - socket <net.Socket>
125+
* - socket <stream.Duplex>
131126
* - head <Buffer>
132127
*/
133128
@inline
134-
def onConnect(callback: (IncomingMessage, Socket, Buffer) => Any): client.type = client.on("connect", callback)
129+
def onConnect(callback: (IncomingMessage, Duplex, Buffer) => Any): T = client.on("connect", callback)
135130

136131
/**
137132
* Emitted when the server sends a '100 Continue' HTTP response, usually because the request
138133
* contained 'Expect: 100-continue'. This is an instruction that the client should send the request body.
139134
*/
140135
@inline
141-
def onContinue(callback: () => Any): client.type = client.on("continue", callback)
136+
def onContinue(callback: () => Any): T = client.on("continue", callback)
137+
138+
@inline
139+
def onInformation(callback: Information => Any): T = client.on("information", callback)
142140

143141
/**
144142
* Emitted when a response is received to this request. This event is emitted only once.
145143
* The response argument will be an instance of http.IncomingMessage.
146144
* - response <http.IncomingMessage>
147145
*/
148146
@inline
149-
def onResponse(callback: IncomingMessage => Any): client.type = client.on("response", callback)
147+
def onResponse(callback: IncomingMessage => Any): T = client.on("response", callback)
150148

151149
/**
152150
* Emitted after a socket is assigned to this request.
153151
* - socket <net.Socket>
154152
*/
155153
@inline
156-
def onSocket(callback: Socket => Any): client.type = client.on("socket", callback)
154+
def onSocket(callback: Duplex => Any): T = client.on("socket", callback)
155+
156+
@inline
157+
def onTimeout(callback: () => Any): T = client.on("timeout", callback)
157158

158159
/**
159160
* Emitted each time a server responds to a request with an upgrade. If this event isn't being listened for,
@@ -163,7 +164,7 @@ object ClientRequest {
163164
* - head <Buffer>
164165
*/
165166
@inline
166-
def onUpgrade(callback: (IncomingMessage, Socket, Buffer) => Any): client.type = client.on("upgrade", callback)
167+
def onUpgrade(callback: (IncomingMessage, Socket, Buffer) => Any): T = client.on("upgrade", callback)
167168

168169
@inline
169170
def endFuture(data: Uint8Array): Future[Unit] = {
@@ -186,3 +187,13 @@ object ClientRequest {
186187
}
187188
}
188189
}
190+
191+
trait Information extends js.Object {
192+
val httpVersion: String
193+
val httpVersionMajor: Int
194+
val httpVersionMinor: Int
195+
val statusCode: Int
196+
val statusMessage: String
197+
val headers: js.Object
198+
val rawHeaders: js.Array[String]
199+
}

app/current/src/main/scala/io/scalajs/nodejs/http/IncomingMessage.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,12 @@ object IncomingMessage {
101101
/**
102102
* Incoming Message Extensions
103103
*/
104-
implicit final class IncomingMessageExtensions(val message: IncomingMessage) extends AnyVal {
104+
implicit final class IncomingMessageExtension[T <: IncomingMessage](private val message: T) extends AnyVal {
105105
@inline
106-
def onClose(callback: js.Function): message.type = message.on("close", callback)
106+
def onAborted(callback: () => Any): T = message.on("aborted", callback)
107+
108+
@inline
109+
def onClose(callback: () => Any): T = message.on("close", callback)
107110

108111
@inline
109112
def setTimeout(duration: FiniteDuration, callback: js.Function): Unit =

0 commit comments

Comments
 (0)