Package Exports
- paravel
- paravel/types
Readme
Paravel 
Another nostr toolkit, focused on creating highly a configurable client system. What paravel provides is less a library of code than a library of abstractions. Odds are you will end up creating a custom implementation of every component to suit your needs, but if you start with paravel that will be much easier than if you pile on parameters over time.
Utilities
- Deferred is just a promise with
resolveandrejectmethods. - Socket is a wrapper around isomorphic-ws that handles json parsing/serialization.
- Queue is an implementation of an asynchronous queue.
Components
- Connection is a wrapper for
Socketwith send and receive queues, and aConnectionMetainstance. - ConnectionMeta tracks stats for a given
Connection. - Executor implements common nostr flows on
target - Pool is a thin wrapper around
Mapfor use withRelays.
Executor targets
Executor targets have an event bus, a send method, a cleanup method, and are passed to an Executor for use.
- Relay takes a
Connectionand provides listeners for different verbs. - Relays takes an array of
Connections and provides listeners for different verbs, merging all events into a single stream. - Plex takes an array of urls and a
Connectionand sends and receives wrapped nostr messages over that connection.
Example
Functionality is split into small chunks to allow for changing out implementations as needed. This is useful when attempting to support novel use cases. Here's a simple implementation of an agent that can use a multiplexer if enabled, or can fall back to communicating directly with all relays.
class Agent {
constructor(multiplexerUrl) {
this.multiplexerUrl = multiplexerUrl
this.pool = new Pool()
}
getTarget(urls) {
return this.multiplexerUrl
? new Plex(urls, this.pool.get(this.multiplexerUrl))
: new Relays(urls.map(url => this.pool.get(url)))
}
subscribe(urls, filters, id, {onEvent, onEose}) {
const executor = new Executor(this.getTarget(urls))
return executor.subscribe(filters, id, {onEvent, onEose})
}
}