Security News
pnpm 10.0.0 Blocks Lifecycle Scripts by Default
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
feedme-server-core
Advanced tools
A low-level Feedme server library for Node.js created and maintained as a core part of the Feedme project.
This library Exposes a simple and flexible API for client conversation management that is compliant with the Feedme specification. Application developers may be more interested in Feedme Node.js Server.
A WebSocket transport is maintained as a core part of the project and is also supported by the Feedme Javascript Client.
Library contributors and transport developers should see the developer documentation.
Install the server:
npm install feedme-server-core
The library expects the application to provide a transport, through which it will accept client connections. To install the WebSocket transport:
npm install feedme-transport-ws
To initialize a server using the WebSocket transport:
const feedmeServerCore = require("feedme-server-core");
const wsTransport = require("feedme-transport-ws/server");
const server = feedmeServerCore({
transport: wsTransport({ url: "https://some.url/api/websocket" }),
});
Once a server has been initialized, the application can listen for events and start the server.
To initialize a server:
const server = feedmeServerCore(options);
The server is initialized in the stopped
state and will remain stopped
until
there is a call to server.start()
.
The options
argument is an object with the following properties:
options.transport
- Required Object.
A transport object used to listen for and interact with clients. The transport must satisfy the requirements laid out in the developer documentation.
Applications must not operate on the transport object directly and must not pass a given transport object to more than one server instance.
The tranport object must be in the stopped
state.
options.handshakeMs
- Optional non-negative integer. Defaults to 30000.
Specifies how long to wait for a client to transmit a valid and
library-compatible Handshake
message after connecting via the transport.
If greater than 0, then the server will wait handshakeMs
for a
newly-connected client to transmit a successful Handshake
message before
forcefully disconnecting the client.
If set to 0, then the server will wait indefinitely for a newly-connected
client to transmit a successful Handshake
message.
options.terminationMs
- Optional non-negative integer. Defaults to 30000.
Specifies feed termination window duration. If greater than zero, then
termination windows last terminationMs
. If set to zero, then feed
termination windows last for the duration of a client's connection.
A termination window begins after a FeedTermination
message has been
transmitted to a client. During the termination window, the server will accept
either a FeedOpen
or FeedClose
message referencing the feed. This behavior
accounts for transport latency, which can cause a client to transmit a
FeedClose
message while a FeedTermination
message is in transit from the
server.
If the server receives a FeedClose
message referencing a feed during the
termination window, it will respond with a FeedCloseResponse
indicating
success and will not emit a feedClose
event. The server will expect the next
client message referencing the feed to be FeedOpen
and will respond with a
ViolationResponse
if it receives another FeedClose
.
If the server receives a FeedOpen
message referencing a feed during the
termination window, it will emit a feedOpen
event as usual.
Errors thrown:
err.message === "INVALID_ARGUMENT: ..."
The options
argument was invalid.
A server can be in one of four states:
stopped
- The server is not listening for client connections and is not
attempting to start, but is ready to be started.
starting
- The server is attempting to begin listening for client
connections.
started
- The server is listening for client connections and may have
existing connections.
stopping
- The server has closed all existing client connections and has
stopped listenening for new connections, but is not ready to be restarted.
Library methods may cause certain events to be emitted synchronously, so the application should generally attach any event handlers immediately after initialization.
Emitted when the server state changes from stopped
to starting
.
Arguments: None
Emitted when the server state changes from starting
to started
.
Arguments: None
Emitted when the server state changes from starting
or started
to
stopping
.
If the server is transitioning from started
to stopping
, then a disconnect
event is emitted for each previously-connected client before the stopping
event is emitted.
Arguments passed to the listeners:
err
(Optional Error) indicates the reason for the stoppage. If the stoppage
resulted from a call to server.stop()
, then the argument is omitted. If the
stoppage resulted from a transport error, then err
takes the form
err.message === "FAILURE: ..."
.Emitted when the server state changes from stopping
to stopped
.
Arguments passed to the listeners:
err
(Optional Error) indicates the reason for the stoppage. If the stoppage
resulted from a call to server.stop()
, then the argument is omitted. If the
stoppage resulted from a transport error, then err
takes the form
err.message === "FAILURE: ..."
and matches the error emitted with the
stopping
event.The library will not automatically try to restart the server if the stoppage was
unexpected. The application must call start()
in order to restart the server.
Emitted when a client connects via the transport. Emitted before any messages
have been exchanged and, in particular, before a Handshake
message has been
transmitted by the client.
Arguments passed to the listeners:
clientId
(string) is the identifier assigned by the library to the client.
The client will be made aware of this identifier once it has transmitted a
library-compatible Handshake
message.Emitted when the server receives a valid and library-compatible Handshake
message.
Arguments passed to the listeners:
hreq
(Object) is a HandshakeRequest
object describing the client request.
hres
(Object) is a HandshakeResponse
object enabling the application to
respond to the request.
If there is a listener attached to the handshake
event, then the application
must call hres.success()
to return a HandshakeResponse
message to the
client.
If there is no listener attached to the handshake
event, then the server
immediataly returns a HandshakeResponse
message indicating success when a
library-compatible Handshake
message is received.
If the client transmits a valid Handshake
message specifying a Feedme version
not supported by the library, then the client is sent a HandshakeResponse
message indicating failure and a handshake
event is not emitted .
Emitted when the server receives a valid Action
message.
Arguments passed to the listeners:
areq
(Object) is an ActionRequest
object describing the action request.
ares
(Object) is an ActionResponse
object enabling the server to respond
to the request.
If there is no listener attached to the action
event, then the server
immediately returns an ActionResponse
message indicating failure when a valid
Action
message is received (error code "INTERNAL_ERROR"
).
Emitted when the server receives a valid FeedOpen
message.
Arguments passed to the listeners:
foreq
(Object) is a FeedOpenRequest
object describing the client request.
fores
(Object) is a FeedOpenResponse
object enabling the application to
respond to the request.
If there is no listener attached to the feedOpen
event, then the server
immediately returns a FeedOpenResponse
message indicating failure when a valid
FeedOpen
message is received (error code "INTERNAL_ERROR"
).
Emitted when the server receives a valid FeedClose
message.
Arguments passed to the listeners:
fcreq
(Object) is a FeedCloseRequest
object describing the client
request.
fcres
(Object) is a FeedCloseResponse
object enabling the application to
respond to the request.
If there is a listener attached to the feedClose
event, then the application
must call fcres.success()
to return a FeedCloseResponse
message to the
client.
If there is no listener attached to the feedClose
event, then the server
immediatally returns a FeedCloseResponse
message indicating success when a
valid FeedClose
message is received.
In both cases, the server stops transmitting ActionRevelation
messages
referencing the feed as soon as the FeedClose
message is received.
The server does not emit a feedClose
event for FeedClose
messages that
arrive during a termination window.
Emitted when a client connection ends.
Arguments passed to the listeners:
clientId
(string) is the identifier that the library assigned to the
client.
err
(Optional Error) indicates the reason for the disconnect. If the
disconnect resulted from a call to server.disconnect()
then the argument is
omitted.
The following errors are possible:
err.message === "HANDSHAKE_TIMEOUT: ..."
The client did not transmit a library-compatible Handshake
message within
the window specified by options.handshakeMs
.
err.message === "FAILURE: ..."
There was a transport connectivity problem or the connection was severed intentionally by the client.
err.message === "STOPPING: ..."
The server is stopping.
Emitted when a client violates the Feedme specification. The server transmits a
ViolationResponse
message to the client before the event is emitted.
Arguments passed to the listeners:
clientId
(string) is the client identifier that the library assigned to the
client.
err
(Error) describes the nature of the violation.
The following errors are possible:
err.message === "INVALID_MESSAGE: ..."
The client transmitted a message that was not valid JSON or that violated one of the JSON schemas laid out in the Feedme specification.
err.clientMessage
(JSON value) - The message received from the client. If
the message was not valid JSON, then this property holds the raw string
message, otherwise it holds the parsed JSON value.
err.parseError
(optional Error) is the error thrown by the JSON parser, if
applicable.
err.schemaViolation
(optional string) describes the schema violation, if
applicable.
err.message === "UNEXPECTED_MESSAGE: ..."
The client transmitted a message that was sequentially invalid.
err.clientMessage
(string) contains the client message.Emitted when the transport violates the requirements set out in the developer documentation.
Arguments passed to the listeners:
err
(Error) indicates the nature of the violation.The following errors are possible:
err.message === "INVALID_RESULT"
A transport method returned an unexpected value or threw an unexpected error.
err.message === "UNEXPECTED_EVENT"
The transport emitted an out-of-sequence event.
err.message === "BAD_EVENT_ARGUMENT"
The transport emitted an event with one or more invalid arguments.
Returns the current server state. One of "stopped"
, "starting"
, "started"
,
or "stopping"
.
Errors thrown:
err.message === "TRANSPORT_ERROR: ..."
The transport behaved unexpectedly.
Initiates an attempt to start the server.
The server state must be stopped
and after a sucessful call, the server state
becomes starting
. If the transport subsequently starts successfully, then the
server state becomes started
. If the transport fails to start, then the server
state becomes stopping
and eventually stopped
.
Errors thrown:
err.message === "INVALID_STATE: ..."
The server state is not stopped
.
err.message === "TRANSPORT_ERROR: ..."
The transport behaved unexpectedly.
Initiates the process of stopping the server. The server state must be started
and after a successful call, the server state becomes stopping
.
Errors thrown:
err.message === "INVALID_STATE: ..."
The server state is not started
.
err.message === "TRANSPORT_ERROR: ..."
The transport behaved unexpectedly.
Transmits ActionRevelation
messages to clients that have opened the specified
feed.
If no client have opened the specified feed then the function returns successfully.
The params
(Object) argument contains the following members:
params.actionName
(string) The name of the action being revealed.
params.actionData
(Object) The action data for the action being revealed.
params.feedName
(string) The name of the feed being revealed on.
params.feedArgs
(Object of strings) The arguments for the feed being
revealed on.
params.feedDeltas
(Array) An array of spec-compliant delta objects
describing any changes to the feed data that resulted from the action. It is
up to the application to ensure that deltas are valid given the current state
of the feed data.
params.feedMd5
(optional string) A spec-compliant hash of the feed data with
the deltas applied. If this parameter is present, then params.feedData
must
not be present; if neither parameter is present, then clients will not be sent
a hash for feed data integrify verification.
params.feedData
(optional Object) A reference to the feed data with the
deltas applied. The library will generate a spec-compliant hash of the feed
data and distribute it with the action revelation. If this parameter is
present, then params.feedMd5
must not be present; if neither parameter is
present, then clients will not be sent a hash for feed data integrity
verification.
Errors thrown:
err.message === "INVALID_ARGUMENT: ..."
One or more arguments was invalid.
err.message === "INVALID_STATE: ..."
The server is not started
.
err.message === "TRANSPORT_ERROR: ..."
The transport behaved unexpectedly.
Forcefully closes one or more client feeds.
There are three usages: (1) terminate a specified feed for a specified client, (2) terminate all feeds for a specified client, and (3) terminate all clients on a specified feed.
Behavior depends on the state of the client feed(s) being terminated:
When terminating a client feed that is opening
(i.e. the library has emitted
a feedOpen
event referencing the feed but the application has not yet called
fores.success()
or fores.failure()
), then the client is immediately sent a
FeedOpenResponse
message indicating failure. The error code and data
transmitted with the message are determined by the parameters passed to this
method. No further action is taken if the application subsequently calls
fores.success()
or fores.failure()
and either call will return
successfully.
When terminating a client feed that is open
, then the client is immediately
sent a FeedTermination
message. The library will open a feed termination
window as configured by options.terminationMs
.
When terminating a client feed that is closing
(i.e. the library has stopped
revealing actions on the client feed and has emitted a feedClose
event but
the application has not yet called fcres.success()
), then the client is
immediately sent a FeedCloseResponse
message indicating success. No further
action is taken if the application subsequently calls fcres.success()
and
the call will return successfully.
When terminating a client feed that is already closed
, nothing is sent to
the client and the method returns successfully.
The params
(Object) argument must contain the following members:
params.clientId
(string) The id of the client whose feed is being
terminated.
params.feedName
(string) The name of the feed being terminated.
params.feedArgs
(Object of strings) The arguments for the feed being
terminated.
params.errorCode
(string) The error code to return to the client.
params.errorData
(Object) The error data to return to the client.
The params
(Object) argument must contain the following members:
params.clientId
(string) The id of the client whose feeds are being
terminated.
params.errorCode
(string) The error code to return to the client.
params.errorData
(Object) The error data to return to the client.
The params
(Object) argument must contain the following members:
params.feedName
(string) The name of the feed whose clients are being
terminated.
params.feedArgs
(Object of strings) The arguments for the feed whose clients
are being terminated.
params.errorCode
(string) The error code to return to the clients.
params.errorData
(Object) The error data to return to the clients.
Errors thrown (for all three usages):
err.message === "INVALID_ARGUMENT: ..."
One or more arguments was invalid.
err.message === "INVALID_STATE: ..."
The server is not started
.
err.message === "TRANSPORT_ERROR: ..."
The transport behaved unexpectedly.
Forcibly disconnects a client transport connection.
The method returns successfully irrespective of the client connection state.
Arguments:
clientId
(string) The id of the client being disconnected.Errors thrown:
err.message === "INVALID_ARGUMENT: ..."
One or more arguments was invalid.
err.message === "INVALID_STATE: ..."
The server is not started
.
err.message === "TRANSPORT_ERROR: ..."
The transport behaved unexpectedly.
Applications respond to client messages using the following types of objects.
When the handshake
event is fired, listeners are passed two arguments: a
HandshakeRequest
object and a HandshakeResponse
object.
HandshakeRequest
objects (hreq
) have the following properties:
hreq.clientId
(string) is the identifier that the library has assigned to
the client. The identifier is shared with the client.HandshakeResponse
objects (hres
) have the following methods:
hres.success()
Returns a HandshakeResponse
message to the client indicating success. The
server will begin to accept Action
, FeedOpen
, and FeedClose
messages
from the client.
If the client has disconnected or the server has stopped, then the method will do nothing but will return successfully.
Errors thrown:
err.message === "ALREADY_RESPONDED: ..."
There has already been a call to hres.success()
.
When the action
event is fired, listeners are passed two arguments: an
ActionRequest
object and an ActionResponse
object.
ActionRequest
objects (areq
) have the following properties:
areq.clientId
(string) is the identifier that the library assigned to the
client.
areq.actionName
(string) is the name of the action being invoked.
areq.actionArgs
(Object) contains arguments for the invocation.
ActionResponse
objects (ares
) have the following methods:
ares.success(actionData)
Returns an ActionResponse
message to the client indicating success.
If the client has disconnected or the server has stopped, then the method will do nothing but will return successfully.
Arguments:
actionData
(Object) is the action data, which is transmitted to the
client.Errors thrown:
err.message === "INVALID_ARGUMENT: ..."
One or more of the specified arguments was invalid.
err.message === "ALREADY_RESPONDED: ..."
There has already been a call to ares.success()
or ares.failure()
.
ares.failure(errorCode, errorData)
Returns an ActionResponse
message to the client indicating failure.
If the client has disconnected or the server has stopped, then the method will do nothing but will return successfully.
Arguments:
errorCode
(string) describes the failure.
errorData
(optional Object) may provide additional details, which are
transmitted to the client.
Errors thrown:
err.message === "INVALID_ARGUMENT: ..."
One or more of the specified arguments was invalid.
err.message === "ALREADY_RESPONDED: ..."
There has already been a call to ares.success()
or ares.failure()
.
When the feedOpen
event is fired, listeners are passed two arguments: a
FeedOpenRequest
object and a FeedOpenResponse
object.
FeedOpenRequest
objects (foreq
) have the following properties:
foreq.clientId
(string) is the identifier that the library assigned to the
client.
foreq.feedName
(string) is the name of the feed being opened.
foreq.feedArgs
(Object of strings) contains arguments for the feed being
opened.
FeedOpenResponse
objects (fores
) have the following methods:
fores.success(feedData)
Returns a FeedOpenResponse
message to the client indicating success.
If the client has disconnected, the server has stopped, or the feed was
terminated using server.feedTermination()
after the feedOpen
event was
emitted, then the method will do nothing but will return successfully.
Arguments:
feedData
(Object) specifies the initial state of the feed data.Errors thrown:
err.message === "INVALID_ARGUMENT: ..."
One or more of the specified arguments was invalid.
err.message === "ALREADY_RESPONDED: ..."
There has already been a call to fores.success()
or fores.failure()
.
fores.failure(errorCode, errorData)
Returns a FeedOpenResponse
message to the client indicating failure.
If the client has disconnected, the server has stopped, or the feed was
terminated using server.feedTermination()
after the feedOpen
event was
emitted, then the method will do nothing but will return successfully.
Arguments:
errorCode
(string) describes the failure.
errorData
(optional Object) may provide additional details, which are
transmitted to the client.
Errors thrown:
err.message === "INVALID_ARGUMENT: ..."
One or more of the specified arguments was invalid.
err.message === "ALREADY_RESPONDED: ..."
There has already been a call to fores.success()
or fores.failure()
.
When the feedClose
event is fired, listeners are passed two arguments: a
FeedCloseRequest
object and a FeedCloseResponse
object.
FeedCloseRequest
objects (fcreq
) have the following properties:
fcreq.clientId
(string) is the identifier that the library assigned to the
client.
fcreq.feedName
(string) is the name of the feed being closed.
fcreq.feedArgs
(Object of strings) contains arguments for the feed being
closed.
FeedCloseResponse
objects (fcres
) have the following methods:
fcres.success()
Returns a FeedCloseResponse
message to the client indicating success.
If the client has disconnected or the server has stopped, then the method will do nothing but will return successfully.
Errors thrown:
err.message === "ALREADY_RESPONDED: ..."
There has already been a call to fcres.success()
.
FAQs
A low-level Feedme server library for Node.js.
The npm package feedme-server-core receives a total of 1 weekly downloads. As such, feedme-server-core popularity was classified as not popular.
We found that feedme-server-core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.