Node.EventEmitter
- Package
- purescript-node-event-emitter
- Repository
- purescript-node/purescript-node-event-emitter
Handling events emitted by an EventEmitter
One can add callbacks to an EventEmitter
on two major axes:
- whether listener is added to the end (i.e.
on
) or start (i.e.prependListener
) of the array - whether a listener is automatically removed after the first event (i.e.
once
orprependOnceListener
).
This module provides functions for each of the above 4 callback-adding functions
If <fn>
is either on
, once
, prependListener
, or prependOnceListener
, then this module exposes
<fn>
- returns a callback that removes the listener<fn>_
- does not return a callback that can remove the listener
Defining events emitted by an EventEmitter
Below, we'll provide an example for how to define an event handler for a type. Let's assume the following:
- There is a type
Foo
that exendsEventEmitter
Foo
values can handle "bar" events- a "bar" event takes the following callback:
EffectFn2 (Nullable Error) String Unit
- the
String
value is always either "red", "green", or "blue"
Then we would write
data Color
= Red
| Green
| Blue
-- Note: see docs on `EventHandle`
-- for the below naming convention justification
-- of suffixing an event name with `H`.
barH
:: EventHandle
Foo
(Maybe Error -> Color -> Effect Unit)
(EffectFn1 (Nullable Error) String Unit)
barH = EventHandle "bar" $ \psCb ->
mkEffectFn2 \nullableError str ->
psCb (toMaybe nullableError) case str of
"red" -> Red
"green" -> Green
"blue" -> Blue
_ ->
unsafeCrashWith $
"Impossible String value for event 'bar': " <> show str
Emitting events via an EventEmitter
Unfortunately, there isn't a good way to emit events safely in PureScript. If one wants to emit an event
in PureScript code that will be consumed by PureScript code, there are better abstractions to use than EventEmitter
.
If one wants to emit an event in PureScript code that will be consumed by JavaScript code, then
the unsafeEmitFn
function can be used to call n-ary functions. However, this is very unsafe. See its docs for more context.
#EventEmitter Source
data EventEmitter
#new Source
new :: Effect EventEmitter
Create a new event emitter
#SymbolOrStr Source
data SymbolOrStr
#eventNames Source
eventNames :: EventEmitter -> Array (Either JsSymbol String)
#getMaxListeners Source
getMaxListeners :: EventEmitter -> Effect Int
By default, an event emitter can only have a maximum of 10 listeners for a given event.
#listenerCount Source
listenerCount :: EventEmitter -> String -> Effect Int
#setMaxListeners Source
setMaxListeners :: Int -> EventEmitter -> Effect Unit
#unsafeEmitFn Source
unsafeEmitFn :: forall f. EventEmitter -> f Boolean
THIS IS UNSAFE! REALLY UNSAFE!
Gets the emit
function for a particular EventEmitter
, so that one can call n-ary functions.
Given http2session.goaway([code[, lastStreamID[, opaqueData]]])
as an example...
- https://nodejs.org/dist/latest-v18.x/docs/api/http2.html#event-goaway
- https://nodejs.org/dist/latest-v18.x/docs/api/http2.html#http2sessiongoawaycode-laststreamid-opaquedata
We can then write a single function that handles all four cases:
goAway
:: Http2Session
-> Maybe Code
-> Maybe LastStreamId
-> Maybe OpaqueData
-> Effect Unit
goAway h2s = case _, _, _ of
Just c, Just id, Just d ->
runEffectFn4 (unsafeEmitFn h2s :: EffectFn4 String Code LastStreamId OpaqueData Unit) "goaway" c id d
Just c, Just id, Nothing ->
-- If you're feeling lucky, omit the type annotations completely
runEffectFn3 (unsafeEmitFn h2s) "goaway" c id
Just c, Nothing, Nothing ->
runEffectFn2 (unsafeEmitFn h2s :: EffectFn2 String Code LastStreamId Unit) "goaway" c
_, _, _ ->
runEffectFn1 (unsafeEmitFn h2s :: EffectFn1 String Unit) "goaway"
Synchronously calls each of the listeners registered for the event named eventName
,
in the order they were registered, passing the supplied arguments to each.
Returns true
if the event had listeners, false
otherwise.
#EventHandle Source
data EventHandle emitterType pureScriptCallback javaScriptCallback
Packs all the type information we need to call on
/once
/prependListener
/prependOnceListener
with the correct callback function type.
Naming convention:
If the name of an event is foo
,
the corresponding PureScript EventHandle
value should be called fooH
.
The H
suffix is what prevent name conflicts in two situations:
- similarly-named methods (e.g. the
"close"
event and theclose
method) - PureScript keywords (e.g. the
"data"
event)
If an event, foo
, can have two different kinds of callbacks, (e.g. See Node.Stream
's data
event),
one of two things should happen:
- a suffix should follow the
H
to distinguish between the two (e.g.dataHString
/dataHBuffer
) - a prime character (i.e.
'
) should follow theH
to distinguish between the two (e.g.dataH
/dataH'
)
Constructors
EventHandle String (pureScriptCallback -> javaScriptCallback)
#on Source
on :: forall emitter psCb jsCb. EventHandle emitter psCb jsCb -> psCb -> emitter -> Effect (Effect Unit)
Adds the listener to the end of the listeners
array.
Returns a callback that will remove the listener from the event emitter's listeners
array.
If the listener removal callback isn't needed, use on_
.
Intended usage:
removeLoggerCallback <- eventEmitter # on errorHandle \error -> do
log $ "Got error: " <> Exception.message error
log $ "This listener will now be removed."
-- sometime later...
removeLoggerCallback
#on_ Source
on_ :: forall emitter psCb jsCb. EventHandle emitter psCb jsCb -> psCb -> emitter -> Effect Unit
Adds the callback to the end of the listeners
array and provides no way to remove the listener in the future.
If you need a callback to remove the listener in the future, use on
.
Intended usage:
eventEmitter # on_ errorHandle \error -> do
log $ "Got error: " <> Exception.message error
#once Source
once :: forall emitter psCb jsCb. EventHandle emitter psCb jsCb -> psCb -> emitter -> Effect (Effect Unit)
Adds the listener to the end of the listeners
array. The listener will be removed after it is invoked once.
Returns a callback that will remove the listener from the event emitter's listeners array.
If the listener removal callback isn't needed, use once_
.
Intended usage:
removeLoggerCallback <- eventEmitter # once errorHandle \error -> do
log $ "Got error: " <> Exception.message error
log $ "This listener will now be removed."
-- sometime later...
removeLoggerCallback
#once_ Source
once_ :: forall emitter psCb jsCb. EventHandle emitter psCb jsCb -> psCb -> emitter -> Effect Unit
Adds the listener to the end of the listeners
array. The listener will be removed after it is invoked once.
Returns a callback that will remove the listener from the event emitter's listeners array.
If you need a callback to remove the listener in the future, use once
.
Intended usage:
eventEmitter # once_ errorHandle \error -> do
log $ "Got error: " <> Exception.message error
#prependListener Source
prependListener :: forall emitter psCb jsCb. EventHandle emitter psCb jsCb -> psCb -> emitter -> Effect (Effect Unit)
Adds the listener to the start of the listeners
array.
Returns a callback that will remove the listener from the event emitter's listeners array.
If the listener removal callback isn't needed, use prependListener_
.
Intended usage:
removeLoggerCallback <- eventEmitter # prependListener errorHandle \error -> do
log $ "Got error: " <> Exception.message error
log $ "This listener will now be removed."
-- sometime later...
removeLoggerCallback
#prependListener_ Source
prependListener_ :: forall emitter psCb jsCb. EventHandle emitter psCb jsCb -> psCb -> emitter -> Effect Unit
Adds the listener to the start of the listeners
array.
Returns a callback that will remove the listener from the event emitter's listeners array.
If the listener removal callback isn't needed, use prependListener
.
Intended usage:
eventEmitter # prependListener_ errorHandle \error -> do
log $ "Got error: " <> Exception.message error
#prependOnceListener Source
prependOnceListener :: forall emitter psCb jsCb. EventHandle emitter psCb jsCb -> psCb -> emitter -> Effect (Effect Unit)
Adds the listener to the start of the listeners
array. The listener will be removed after it is invoked once.
Returns a callback that will remove the listener from the event emitter's listeners array.
If the listener removal callback isn't needed, use prependOnceListener_
.
Intended usage:
removeLoggerCallback <- eventEmitter # prependOnceListener errorHandle \error -> do
log $ "Got error: " <> Exception.message error
log $ "This listener will now be removed."
-- sometime later...
removeLoggerCallback
#prependOnceListener_ Source
prependOnceListener_ :: forall emitter psCb jsCb. EventHandle emitter psCb jsCb -> psCb -> emitter -> Effect Unit
Adds the listener to the start of the listeners
array. The listener will be removed after it is invoked once.
Returns a callback that will remove the listener from the event emitter's listeners array.
If you need a callback to remove the listener in the future, use prependOnceListener
.
Intended usage:
eventEmitter # prependOnceListener_ errorHandle \error -> do
log $ "Got error: " <> Exception.message error