I'm building a ground-up Nostr websockets library in TypeScript. It's a collection of low-level tiny modules that each do one thing well, as well as a few opinionated modules like NiceRelay and Firehose that combine the pieces into something usable out of the box. Some of the pieces include:
AsyncSocket: get WebSocket messages as a generator, async "send" function that just works.
Relay: low-level websocket wrapper that deals with client-relay messages directly and doesn't care about subscriptions.
Pubsub: data store for managing REQ subscriptions (but it's actually just a general-purpose topics pubsub).
Machina: converts event emitters into async generators.
Reanimator: revives disconnected websockets and triggers a callback.
NiceRelay: keeps a Relay instance internally, revives the socket if dead, provides messages as an async iterator, stores and manages subscriptions, async "send" with a parsed NIP-20 response.
There are problems with existing libraries. For instance, most libraries manage subscriptions in the Relay module itself. Then the Pool shoehorns in an array of Relay instances. This is problematic because the Pool itself wants to manage the subscriptions. By breaking it into smaller parts, we can make the Pool work better, and we can even create opinionated Pool implementations like a Firehose, which can resume subscriptions for newly added relays.
I'll host the code and put up a link today. In case you're wondering what I've been up to on Ditto, this library will solve problems I'm having on both the client and relay side.
AsyncSocket: get WebSocket messages as a generator, async "send" function that just works.
Relay: low-level websocket wrapper that deals with client-relay messages directly and doesn't care about subscriptions.
Pubsub: data store for managing REQ subscriptions (but it's actually just a general-purpose topics pubsub).
Machina: converts event emitters into async generators.
Reanimator: revives disconnected websockets and triggers a callback.
NiceRelay: keeps a Relay instance internally, revives the socket if dead, provides messages as an async iterator, stores and manages subscriptions, async "send" with a parsed NIP-20 response.
There are problems with existing libraries. For instance, most libraries manage subscriptions in the Relay module itself. Then the Pool shoehorns in an array of Relay instances. This is problematic because the Pool itself wants to manage the subscriptions. By breaking it into smaller parts, we can make the Pool work better, and we can even create opinionated Pool implementations like a Firehose, which can resume subscriptions for newly added relays.
I'll host the code and put up a link today. In case you're wondering what I've been up to on Ditto, this library will solve problems I'm having on both the client and relay side.