๐ nlon
Classes
- Correspondence
- CorrespondenceError
- InvalidMessageError
Error representing an invalid message.
- Message
Message class, holding all the data of a well-formed nlon message.
- MessageError
Message error.
- MessageHeader
Message header.
- Peer
Peer class.
- PeerDisconnectedError
- PeerError
- ReadableCorrespondence โ Correspondence
- Server
Server class.
- StreamingError
Error representing any kind of stream error.
- UnfinishedCorrespondenceError
Error thrown when the correspondence handler doesn't finish the correspondence.
- UnreadableCorrespondenceError
- UnwritableCorrespondenceError
- WritableCorrespondence โ Correspondence
Functions
- defaultExceptionHandler (_peer, correspondence, exception)
Default exception handler.
- unknownSubjectHandler (_peer, correspondence)
Default request handler.
Typedefs
- CorrespondenceExceptionHandler :
function
Correspondence exception handler callback.
- CorrespondenceHandler :
function
Correspondence handler.
- MessageType :
MessageType
Enum for message types.
- PeerOptions :
object
- ReadHandler :
function
Read handler callback.
Read handlers can be used to specify operations to apply to incoming data. For example they can be used to validate incoming messages.
They are also given access to a context object that is specific to that single message that the read handlers are called on. This can be used to extract useful data based on the message that can be accessed later down the line.
- ServerOptions :
object
External
Correspondence
Bidirectional correspondence
Kind: global class
constructor
Correspondence
Construct a correspondence.
Param | Type | Description |
---|---|---|
[options] | object | Correspondence options |
[options.stream] | stream.Duplex | Stream this correspondence belongs to |
[options.header] | MessageHeader | Correspondence header |
async
Correspondence#all (handlers) โ AsyncGenerator
Get all incoming data.
This method returns an async generator that will yield every incoming chunk of data. Once the correspondence is finished, the generator will finish.
Additional validations and other operations to apply on the incoming data can be specified in the form of ReadHandlers. Every handler will be called in order.
Note that the read handlers will not be called for the finish message if
it has no body. This differs from .next()
.
While consuming messages this way, the Correspondence won't emit events.
Kind: instance function
Param | Type | Description |
---|---|---|
handlers | ReadHandler | Read handlers |
Throws:
-
When receiving an error message
-
If Correspondence not readable
-
If any of the handlers throw
Correspondence#error (err)
Finish correspondence with an error.
This method will send am error message, signifying to the recipient that an error has occurred during processing, and to expect no more data on this correspondence. The error itself will be present as a dedicated field in the response, to convey information to the recipient.
After this call, the correspondence will no longer be writable.
Kind: instance function
Param | Type | Description |
---|---|---|
err | MessageError | Error |
Throws: <p>If Correspondence not writable</p>
Correspondence#finish ([data])
Finish correspondence.
This method will send a finish message, signifying to the recipient to no longer expect any data on this correspondence. A body may or may not be present in this message.
After this call, the correspondence will no longer be writable.
Kind: instance function
Param | Type | Description |
---|---|---|
[data] | any | Response data |
Throws: <p>If Correspondence not writable</p>
Correspondence#handle (message)
Handle message.
This method is called from the outside, typically by the Peer or Server, when a message belonging to this instance's correspondence is received. Based on the incoming message, the appropriate event is emitted.
If a
finish
message is received with data in it, first adata
event is emitted, thenfinish
. Thus, subscribing todata
only is enough to get noitified of every single incoming chunk.
Kind: instance function
Param | Type | Description |
---|---|---|
message | Message | Message received |
Fires:
async
Correspondence#next (handlers) โ Promise.<(any|Symbol)>
Get the next chunk of incoming data.
This method returns a promise that is resolved with the next piece of incoming data.
If the correspondence is finished during the wait, End will be returned. Otherwise, the data chunk is returned as-is.
Additional validations and other operations to apply on the incoming data can be specified in the form of ReadHandlers. Every handler will be called in order. Note that even if the Correspondence is finished, the handlers will be invoked - so if you're expecting a message body, make sure to either include an initial handler validating that, or explicitly check for a message body in your handlers that require it.
While consuming messages this way, the Correspondence won't emit events.
Kind: instance function
Param | Type | Description |
---|---|---|
handlers | ReadHandler | Read handlers |
Throws:
-
When receiving an error message
-
If Correspondence not readable
-
If any of the handlers throw
Correspondence#write (data)
Send data message.
This method will send a data message. This method can be called 0 or more times. Each call will send a separate message, making it suitable for streaming data, instead of trying to send all of it in one huge message.
Kind: instance function
Param | Type | Description |
---|---|---|
data | any | Data |
Throws: <p>If Correspondence not writable</p>
Correspondence.End : Symbol
Correspondence end symbol.
This symbol is returned during Correspondence reads. It is used to signify that the correspondence has just become unreadable during read.
If the correspondence was already unreadable due to a previous finish or error message, reads throw instead of returning
End
.
Kind: static member
Correspondence#context : object
Get context.
The correspondence context is an object shared between active ReadHandlers, each of which can freely modify it. This is useful for storing data that can be useful later down the line.
The context object is tied to the current read. You can access it after the
read, but it will be reset when the next read operation begins ( .next()
or
.all()
).
Kind: instance member
Correspondence#header : MessageHeader
Get correspondence header.
When reading with the correspondence, this field will contain the header of the last message received.
When writing, this field will contain the configured header, and will be used as the header of every message sent.
Kind: instance member
Correspondence#readable : boolean
Check if correspondence is readable.
A correspondence is readable as long as it has not received either a finish or an error message. Both of these messages signify that no more data should be expected on this correspondence.
Kind: instance member
Correspondence#writable : boolean
Check if correspondence is writable.
A correspondence is writable as long as it has not sent either a finish or an error message. Both of these messages signify that no more data should be expected on this correspondence.
Kind: instance member
Correspondence#event:close
Event emitted when the correspondence is closed.
The correspondence is considered closed when it becomes both unreadable and unwritable. In practice, this happens when peers on both ends of the correspondence close it, either by sending an error or a finish message.
Kind: instance event
Correspondence#event:data : any
Event emitted whenever a data
message is received on the correspondence.
Only the response body will be emitted ( which may be undefined
! ), as the
header can be queried from the correspondence itself, and shouldn't
influence processing after the initial message.
Kind: instance event
Correspondence#event:error : CorrespondenceError
Event emitted whenever an error
message is received on the correspondence.
This indicates that no more data is to be expected on this correspondence, since it has terminated with an error.
Kind: instance event
Correspondence#event:finish
Event emitted whenever a finish
message is received on the correspondence.
This indicates that no more data is to be expected on this correspondence, and that it has concluded successfully.
Kind: instance event
CorrespondenceError
Error thrown when an error message is received over a correspondence.
Kind: global class
constructor
CorrespondenceError
Construct an error.
Param | Type | Description |
---|---|---|
error | MessageError |
CorrespondenceError#type : string
A short string indicating the error type.
Kind: instance member
InvalidMessageError
Error representing an invalid message.
Invalid messages are JSON strings that can be parsed as such, but do not conform to nlon's protocol, for example missing header, correspondenceId or subject.
Kind: global class
constructor
InvalidMessageError
Construct an error.
Param | Type | Description |
---|---|---|
stream | stream.Duplex | Stream the invalid message was received on |
content | object | Parsed JSON content |
message | string | Error message |
InvalidMessageError#content : object
Parsed JSON content
Kind: instance member
InvalidMessageError#stream : stream.Duplex
Stream the invalid message was received on
Kind: instance member
Message
Message class, holding all the data of a well-formed nlon message.
Messages belong to correspondences, similar to how emails can
be organized into threads. Each correspondence begins with an initial message,
to which multiple data
responses may arrive, and finished with either an
error
or a finish
message.
Each correspondence has an ID so that messages can be easily grouped by correspondence. This is specified in the message header.
To determine how to process the message, the message header also contains a
subject
, similar to HTTP's path
.
Kind: global class
constructor
Message
Construct a message.
Param | Type | Description |
---|---|---|
options | Message | Options |
Message.validate (message)
Validate a message.
Kind: static function
Param | Type | Description |
---|---|---|
message | Message | Message to validate |
Throws: <p>On invalid messages</p>
Message#body : any
Message body
Kind: instance member
Message#error : MessageError
Message error
If present, the body should be missing and can be safely ignored.
Kind: instance member
Message#header : MessageHeader
Message header
Kind: instance member
Message#type : MessageType
Message type
Kind: instance member
MessageError
Message error.
Represents an error description in case the original message's processing failed.
It contains a short description of the issue, useful for programmatic use, and a longer description, to be used for any human-facing use cases.
Kind: global class
constructor
MessageError
Construct an error.
Param | Type | Description |
---|---|---|
options | MessageError | Options |
MessageError#message : string
An arbitrary string indicating the error message.
Kind: instance member
MessageError#type : string
A short string indicating the error type.
Kind: instance member
MessageHeader
Message header.
A message header all the information necessary to match the message to a correspondence, interpret the message body ( if any ) and decide how to process the message.
Kind: global class
constructor
MessageHeader
Construct a header.
Param | Type | Description |
---|---|---|
options | MessageHeader | Options |
MessageHeader.validate (header)
Validate a message header.
Kind: static function
Param | Type | Description |
---|---|---|
header | MessageHeader | Header to validate |
Throws: <p>On invalid headers</p>
MessageHeader#authorization : string
An optional authorization string. Its use is entirely dependent on the application.
Optional.
Kind: instance member
MessageHeader#correspondenceId : string
Correspondence ID, to track request-response pairs.
Always required.
Kind: instance member
MessageHeader#subject : string
Subject of the correspondence, letting the recipient know what action to perform.
Similar to HTTP's path
.
Always required.
Kind: instance member
Peer
Peer class.
The peer class attaches to a single connection and manages correspondences on it. This includes both initiating new correspondences by sending a message and reacting to incoming correspondences.
Each incoming message is picked up by the peer and associated with a known
Correspondence instance, if any exists. If it is an entirely new
correspondence, it is emitted as a correspondence
event.
Any and all errors both occurring during processing and coming from the
underlying stream will be propagated through the error
event.
Note that the Peer itself does not know about the particulars of its
underlying connection - as long as it can be used as a stream.Duplex
it will
function fine. This enables factory methods to create peers on TCP sockets,
WebSockets, or even adapt other types.
Kind: global class
constructor
Peer
Construct a peer.
Param | Type | Description |
---|---|---|
connection | stream.Duplex | Connection |
[options] | PeerOptions | Options |
Peer#correspond (header) โ Correspondence
Initiate a new correspondence, ready to send data.
A new Correspondence instance will be created, but no message will be sent over it. However, the header itself will be validated, to make sure that the Correspondence can actually be used to send messages.
This is the preferred method to start new correspondences.
The header gets a generated correspondenceId if not set, so you can do the following and get a valid correspondence:
peer.correspond({ subject: 'test' })
NOTE: No message will be sent, you'll need to call the Correspondence's methods ( e.g. write ) to actually send any data.
Kind: instance function
Param | Type | Description |
---|---|---|
header | MessageHeader | Header used for the correspondence |
Throws:
PeerDisconnectedError
<p>If disconnected</p>-
On invalid header
Peer#disconnect ()
Disconnect peer.
Afther this call, the peer won't listen to any more incoming messages and won't be able to send any traffic.
It is considered an error to send anything after the peer is disconnected.
Note that the underlying stream will not be closed.
Kind: instance function
Peer#receive () โ Promise.<Correspondence>
Get the next new correspondence.
Kind: instance function
Throws: PeerDisconnectedError
<p>If disconnected</p>
Peer#send (message) โ Correspondence
Initiate a new correspondence by sending a message.
The message is validated before sending and its corresponednce ID will be associated with the returned instance. Any incoming replies will be passed to the correspondence for processing.
Using this method to send multiple messages on the same correspondence is discouraged, as it will lead to pointlessly creating multiple correspondence instances for the same correspondence.
Kind: instance function
Param | Type | Description |
---|---|---|
message | Message | Message |
Throws:
PeerDisconnectedError
<p>If disconnected</p>-
On invalid messages
Peer#id : string
Peer ID, used primarily for logging.
Kind: instance member
Peer#isConnected : boolean
Whether the Peer is connected.
Kind: instance member
Peer#stream : stream.Duplex
Connection
Returns undefined if the Peer is disconnected
Kind: instance member
Peer#event:connect : stream.Duplex
Event emitted upon successful connection by the peer.
In practice this means that after this point the peer can send and receive messages. This may or may not correspond to a background operation, depending on the nature of the connection.
The stream itself is emitted upon which the peer will transfer messages.
Kind: instance event
Peer#event:correspondence : IncomingCorrespondence
Event emitted when the peer receives a new correspondence.
This happens whenever the peer receives a message with a correspondence ID that does not belong to an already existing IncomingCorrespondence, in which case a new instance is created and emitted as event data.
Kind: instance event
Peer#event:disconnect : stream.Duplex
Event emitted when the peer disconnects.
This might happen after a Peer#disconnect call, or when the peer's underlying stream is closed for whatever reason.
Consistently with the Server events, the stream is emitted as event data.
Kind: instance event
Peer#event:error : Error
Event emitted when the peer encounters an error.
This error may either come from the underlying stream itself or from the peer's own message processing logic.
Kind: instance event
PeerDisconnectedError
Error thrown when trying to send / receive on a peer that's already disconnected.
Kind: global class
PeerError
Error emitted when any of the Server's managed peers encounter an error.
Kind: global class
constructor
PeerError
Construct error.
Param | Type | Description |
---|---|---|
peer | Peer | Peer encountering error |
cause | Error | Encountered error |
[message] | string | Error message |
PeerError#peer : Peer
Peer that encountered the error.
Kind: instance member
ReadableCorrespondence โ Correspondence
Read-only correspondence
Kind: global class
Extends: Correspondence
constructor
ReadableCorrespondence
Param | Type | Description |
---|---|---|
options | object | |
options.header | MessageHeader |
ReadableCorrespondence.wrap (correspondence) โ ReadableCorrespondence
Wrap a correspondence as read-only
This method will return a read-only proxy to the target correspondence. This also means that if either the original or the proxy correspondence becomes unreadable, both of them become unwritable.
Kind: static function
Param | Type | Description |
---|---|---|
correspondence | Correspondence | Target correspondence |
async
ReadableCorrespondence#all (handlers) โ AsyncGenerator
Get all incoming data.
This method returns an async generator that will yield every incoming chunk of data. Once the correspondence is finished, the generator will finish.
Additional validations and other operations to apply on the incoming data can be specified in the form of ReadHandlers. Every handler will be called in order.
Note that the read handlers will not be called for the finish message if
it has no body. This differs from .next()
.
While consuming messages this way, the Correspondence won't emit events.
Kind: instance function
Param | Type | Description |
---|---|---|
handlers | ReadHandler | Read handlers |
Throws:
-
When receiving an error message
-
If Correspondence not readable
-
If any of the handlers throw
ReadableCorrespondence#handle (message)
Handle message.
This method is called from the outside, typically by the Peer or Server, when a message belonging to this instance's correspondence is received. Based on the incoming message, the appropriate event is emitted.
If a
finish
message is received with data in it, first adata
event is emitted, thenfinish
. Thus, subscribing todata
only is enough to get noitified of every single incoming chunk.
Kind: instance function
Param | Type | Description |
---|---|---|
message | Message | Message received |
Fires:
async
ReadableCorrespondence#next (handlers) โ Promise.<(any|Symbol)>
Get the next chunk of incoming data.
This method returns a promise that is resolved with the next piece of incoming data.
If the correspondence is finished during the wait, End will be returned. Otherwise, the data chunk is returned as-is.
Additional validations and other operations to apply on the incoming data can be specified in the form of ReadHandlers. Every handler will be called in order. Note that even if the Correspondence is finished, the handlers will be invoked - so if you're expecting a message body, make sure to either include an initial handler validating that, or explicitly check for a message body in your handlers that require it.
While consuming messages this way, the Correspondence won't emit events.
Kind: instance function
Param | Type | Description |
---|---|---|
handlers | ReadHandler | Read handlers |
Throws:
-
When receiving an error message
-
If Correspondence not readable
-
If any of the handlers throw
ReadableCorrespondence#context : object
Get context.
The correspondence context is an object shared between active ReadHandlers, each of which can freely modify it. This is useful for storing data that can be useful later down the line.
The context object is tied to the current read. You can access it after the
read, but it will be reset when the next read operation begins ( .next()
or
.all()
).
Kind: instance member
ReadableCorrespondence#event:close
Event emitted when the correspondence is closed.
The correspondence is considered closed when it becomes both unreadable and unwritable. In practice, this happens when peers on both ends of the correspondence close it, either by sending an error or a finish message.
Kind: instance event
ReadableCorrespondence#event:data : any
Event emitted whenever a data
message is received on the correspondence.
Only the response body will be emitted ( which may be undefined
! ), as the
header can be queried from the correspondence itself, and shouldn't
influence processing after the initial message.
Kind: instance event
ReadableCorrespondence#event:error : CorrespondenceError
Event emitted whenever an error
message is received on the correspondence.
This indicates that no more data is to be expected on this correspondence, since it has terminated with an error.
Kind: instance event
ReadableCorrespondence#event:finish
Event emitted whenever a finish
message is received on the correspondence.
This indicates that no more data is to be expected on this correspondence, and that it has concluded successfully.
Kind: instance event
Server
Server class.
The server class listens on a set of streams and for any incoming message:
- Parses it as JSON
- Validates it as a
Message
- Calls the appropriate handlers based on its
subject
In case no handler is registered for the incoming message's subject, the default handler will be called.
In case an exception occurred during processing, the exception handlers will be called. During this process, if the correspondence becomes finished at any point, the loop is broken and the message's processing will be finished.
Note that the Server itself is not aware of the type of stream - it can be a
file, a TCP Socket, a Websocket, or anything else that can function as a
Duplex. This also means that the Server cannot 'listen' on a socket. Instead,
any amount of streams can be added with the connect
method. In case any of
the streams become inactive, they can be removed with the disconnect
method.
This setup lends itself to a Server implementation that is not concerned with
the particulars of the underlying streams, and external factory methods that
adapt the specific Duplex
implementations to something the Server
can
manage.
Kind: global class
constructor
Server
Construct a server.
Param | Type | Description |
---|---|---|
[options] | ServerOptions | Options |
Server#configure (configurer)
Configure the server.
This method expects a method that can be called with the server as the only argument. This makes it possible to export "bundles" of handlers without depending on the actual server instance.
Kind: instance function
Param | Type | Description |
---|---|---|
configurer | function | Configuration function |
Examples:
// userHandlers.mjs
userHandlers (server) {
server.handle('user/login', (correspondence, ctx) => { ... })
server.handle('user/logout', (correspondence, ctx) => { ... })
}
// index.mjs
import { userHandlers } from 'userHandlers.mjs'
const server = new Server(...)
server.configure(userHandlers)
Server#connect (stream)
Connect a stream to the server, listening to its incoming messages.
Internally, the stream will be piped before listening to its
'data' events. Any errors encountered on either the original or the piped
stream will result in an error
event on the Server instance.
After every connected stream, a 'connect' event will be emitted with the stream as event data.
In case the stream becomes closed, it will be disconnected automatically, emitting a 'disconnect' event.
Kind: instance function
Param | Type | Description |
---|---|---|
stream | stream.Duplex | Stream |
Fires: Server#event:connect
Server#defaultHandler (handler)
Set default handler.
The default handler is called in case no request handler is
registered for the incoming message's subject
.
By default, unknownSubjectHandler
is registered as the default handler.
Kind: instance function
Param | Type | Description |
---|---|---|
handler | CorrespondenceHandler | Default handler |
Server#disconnect (stream)
Disconnect the stream, no longer listening to messages coming from it.
Additionally, a 'disconnect' event is also emitted with the disconnected stream as event data.
Kind: instance function
Param | Type | Description |
---|---|---|
stream | stream.Duplex | Stream |
Fires: Server#event:disconnect
Server#handle (subject, handler)
Register a correspondence handler.
To process incoming messages, handlers are selected based on
the message's subject
.
If the given subject already has a handler, a warning message will be logged.
Kind: instance function
Param | Type | Description |
---|---|---|
subject | string | Subject |
handler | CorrespondenceHandler | Correspondence handler |
Server#handleException (handlers)
Register a request exception handler.
Exception handlers are called in case an exception is thrown during message processing. Multiple exception handlers may be registered, and will be called from most recently registered to least recently registered.
This reverse order is implemented because a catch-all exception handler is always registered, which must be run last.
Kind: instance function
Param | Type | Description |
---|---|---|
handlers | CorrespondenceExceptionHandler | Exception handlers |
Server#peers : Array.<Peer>
Get all peers connected to this server.
This always return a new copy.
Kind: instance member
Server#stream : any
Get main stream as set by constructor.
For instances that listen on an underlying connection ( e.g. sockets ), this can return that stream. In other cases, where the instance gets streams attached from external sources, this can be undefined.
The actual value depends on the adapter implementation or constructor parameters.
Kind: instance member
Server#event:connect
Event emitted when a new peer is connected to the server.
Kind: instance event
Param | Type | Description |
---|---|---|
stream | stream.Duplex | Stream connected |
peer | Peer | Peer |
Server#event:disconnect
Event emitted when a peer is disconnected.
Kind: instance event
Param | Type | Description |
---|---|---|
stream | stream.Duplex | Stream connected |
peer | Peer | Peer |
Server#event:error
Event emitted when an error is encountered by a connected peer or during message processing.
Kind: instance event
Param | Type | Description |
---|---|---|
error | any | Error |
StreamingError
Error representing any kind of stream error.
Stream errors are thrown when the incoming message cannot be parsed as JSON, or in case any other error is emitted by the stream.
Kind: global class
constructor
StreamingError
Construct an error.
Param | Type | Description |
---|---|---|
stream | stream.Duplex | Stream the error was received on |
cause | any | Error emitted by the stream |
StreamingError#cause : any
Error emitted by the stream
Kind: instance member
StreamingError#stream : stream.Duplex
Stream the error was received on
Kind: instance member
UnfinishedCorrespondenceError
Error thrown when the correspondence handler doesn't finish the correspondence.
Kind: global class
constructor
UnfinishedCorrespondenceError
Construct an error.
Param | Type | Description |
---|---|---|
correspondence | Correspondence | Unfinished correspondence |
UnfinishedCorrespondenceError#correspondence : Correspondence
The correspondence left unfinished
Kind: instance member
UnreadableCorrespondenceError
Error thrown when attempting to read from an unreadable correspondence.
Kind: global class
constructor
UnreadableCorrespondenceError
Construct an error.
Param | Type | Description |
---|---|---|
correspondence | Correspondence | Correspondence |
UnreadableCorrespondenceError#correspondence : Correspondence
Correspondence
Kind: instance member
UnwritableCorrespondenceError
Error thrown when attempting to write to an unwritable correspondence.
Kind: global class
constructor
UnwritableCorrespondenceError
Construct an error.
Param | Type | Description |
---|---|---|
correspondence | Correspondence | Correspondence |
UnwritableCorrespondenceError#correspondence : Correspondence
Correspondence
Kind: instance member
WritableCorrespondence โ Correspondence
Write-only correspondence
Kind: global class
Extends: Correspondence
constructor
WritableCorrespondence
WritableCorrespondence.wrap (correspondence) โ WritableCorrespondence
Wrap a correspondence as write-only
This method will return a write-only proxy to the target correspondence. This also means that if either the original or the proxy correspondence becomes unwritable, both of them become unwritable.
Kind: static function
Param | Type | Description |
---|---|---|
correspondence | Correspondence | Target correspondence |
WritableCorrespondence#error (err)
Finish correspondence with an error.
This method will send am error message, signifying to the recipient that an error has occurred during processing, and to expect no more data on this correspondence. The error itself will be present as a dedicated field in the response, to convey information to the recipient.
After this call, the correspondence will no longer be writable.
Kind: instance function
Param | Type | Description |
---|---|---|
err | MessageError | Error |
Throws: <p>If Correspondence not writable</p>
WritableCorrespondence#finish ([data])
Finish correspondence.
This method will send a finish message, signifying to the recipient to no longer expect any data on this correspondence. A body may or may not be present in this message.
After this call, the correspondence will no longer be writable.
Kind: instance function
Param | Type | Description |
---|---|---|
[data] | any | Response data |
Throws: <p>If Correspondence not writable</p>
WritableCorrespondence#write (data)
Send data message.
This method will send a data message. This method can be called 0 or more times. Each call will send a separate message, making it suitable for streaming data, instead of trying to send all of it in one huge message.
Kind: instance function
Param | Type | Description |
---|---|---|
data | any | Data |
Throws: <p>If Correspondence not writable</p>
WritableCorrespondence#event:close
Event emitted when the correspondence is closed.
The correspondence is considered closed when it becomes both unreadable and unwritable. In practice, this happens when peers on both ends of the correspondence close it, either by sending an error or a finish message.
Kind: instance event
WritableCorrespondence#event:data : any
Event emitted whenever a data
message is received on the correspondence.
Only the response body will be emitted ( which may be undefined
! ), as the
header can be queried from the correspondence itself, and shouldn't
influence processing after the initial message.
Kind: instance event
WritableCorrespondence#event:error : CorrespondenceError
Event emitted whenever an error
message is received on the correspondence.
This indicates that no more data is to be expected on this correspondence, since it has terminated with an error.
Kind: instance event
WritableCorrespondence#event:finish
Event emitted whenever a finish
message is received on the correspondence.
This indicates that no more data is to be expected on this correspondence, and that it has concluded successfully.
Kind: instance event
defaultExceptionHandler (_peer, correspondence, exception)
Default exception handler.
This exception handler is always registered and serves as a catch-all exception handler. It will try to extract the exception's name and message to be used as error type and message. Otherwise it will fall back to a generic 'UnknownError' without message.
Kind: global function
Param | Type | Description |
---|---|---|
_peer | Peer | Peer |
correspondence | Correspondence | Correspondence |
exception | any | Exception occurred |
unknownSubjectHandler (_peer, correspondence)
Default request handler.
This handler should be registered as a default handler, in cases where no handlers are registered for the message subject. The response will always be the following:
{
"header": {
// original header
},
"type": "err",
"error": {
"type": "UnknownSubject",
"message": "Unknown subject: <subject>"
}
}
Kind: global function
Param | Type | Description |
---|---|---|
_peer | Peer | Peer |
correspondence | Correspondence | Correspondence |
CorrespondenceExceptionHandler : function
Correspondence exception handler callback.
Exception handlers are called in cases when an exception is thrown during correspondence processing. When encountering an exception, all of the registered exception handlers are called, meaning that an exception might go through multiple exception handlers.
In turn, each exception handler may decide if they are applicable to the given correspondence ( e.g. based on subject ) and error, and if so, send a response on the correspondence.
If the correspondence is finished by any of the exception handlers, the rest of them will not be invoked.
Asynchronous exception handlers are supported. If an exception handler returns a promise, it will be awaited before moving on to the next exception handler.
NOTE: If a correpsondence is not finished ( either by calling .finish
or
.error
) even after all the applicable handlers have been called, an error
will be emitted. Leaving correspondences unfinished is bad practice.
Kind: global typedef
Param | Type | Description |
---|---|---|
peer | Peer | Peer on the other end of the correspondence |
correspondence | WritableCorrespondence | Correspondence being processed |
exception | any | Exception occurred |
CorrespondenceHandler : function
Correspondence handler.
Correspondence handlers are responsible for processing any new incoming correspondences. They are given access to the correspondence instance, which can then be used to iterate over the incoming data and send back any replies as necessary.
Async correspondence handlers are supported.
Any exception thrown during a correspondence handler's run will be caught and passed to the exception handlers.
Kind: global typedef
Param | Type | Description |
---|---|---|
peer | Peer | Peer on the other end of the correspondence |
correspondence | Correspondence | Received correspondence |
See: Correspondence
MessageType : MessageType
Enum for message types.
Every message must belong to one of the following message types:
- Data
- Carries a piece of data belonging to the correspondence.
- May occur 0 or more times in a correspondence.
- Error
- Signifies that an error occurred during message processing.
- No more messages should be expected in the correspondence.
- Finish
- Signifies that the correspondence has been closed, message has been processed successfully.
- No more messages should be expected in the correspondence.
Additionally, a special Request
type exists. A message is a request in case
its the first message belonging to a correspondence. In this case, the type
field is not specified.
Kind: global typedef
PeerOptions : object
Kind: global typedef
Property | Type | Description |
---|---|---|
[logger] | pino.Logger | Logger |
[logLevel] | string | Logging level |
[id] | string | Peer ID, used for logging |
ReadHandler : function
Read handler callback.
Read handlers can be used to specify operations to apply to incoming data. For example they can be used to validate incoming messages.
They are also given access to a context object that is specific to that single message that the read handlers are called on. This can be used to extract useful data based on the message that can be accessed later down the line.
Kind: global typedef
Param | Type | Description |
---|---|---|
body | any | Message body |
header | MessageHeader | Message header |
context | object | Message context |
Examples:
const data = await correspondence.next(
// Make sure there's an auth string in the header, otherwise throw
requireAuth(),
// Extract user object and store in context
requireValidUser()
)
// We can grab the user from the correspondence context, where
//`requireValidUser` saved it
const { user } = correspondence.context
// Then do whatever we need with the extracted data
sessionManager.login(user)
ServerOptions : object
Kind: global typedef
Property | Type | Description |
---|---|---|
[logger] | pino.Logger | Logger |
[logLevel] | string | Log level |
[stream] | any | Root connection stream |
stream.Duplex
Duplex stream.
Kind: global external