From 3844f68d1a5507c36b7bc27ec39063e83e067bfe Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Thu, 18 Feb 2021 16:04:41 -0300 Subject: [PATCH] remove ramda and rework logic. --- package.json | 3 +-- pool.js | 72 +++++++++++++++++++++++++++++----------------------- relay.js | 13 ++++------ 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index 84a5257..04bff31 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nostr-tools", - "version": "0.4.0", + "version": "0.4.1", "description": "Tools for making a Nostr client.", "main": "index.js", "repository": { @@ -10,7 +10,6 @@ "dependencies": { "buffer": "^6.0.3", "noble-secp256k1": "^1.1.1", - "ramda": "^0.27.1", "websocket-polyfill": "^0.0.3" }, "keywords": [ diff --git a/pool.js b/pool.js index b810f62..f3232dc 100644 --- a/pool.js +++ b/pool.js @@ -6,15 +6,8 @@ const R = require('ramda') export function relayPool(globalPrivateKey) { const relays = {} const globalSub = [] - const eventCallbacks = [] const noticeCallbacks = [] - function propagateEvent(event, context, relayURL) { - for (let i = 0; i < eventCallbacks.length; i++) { - let {relay} = relays[relayURL] - eventCallbacks[i](event, context, relay) - } - } function propagateNotice(notice, relayURL) { for (let i = 0; i < noticeCallbacks.length; i++) { let {relay} = relays[relayURL] @@ -22,23 +15,42 @@ export function relayPool(globalPrivateKey) { } } - const sub = async (cb, params) => { - const subControllers = R.map(({relay}) => { - return relay.sub(params, cb.bind(null, relay)) - }, R.filter(R.pipe(R.prop('policy'), R.prop('write'), R.equals(true)), relays)) + const activeSubscriptions = {} - return { - sub: (cb, params) => - R.map( - R.pipe(R.prop('sub'), R.flip(R.apply)([cb, params])), - subControllers - ), - unsub: () => R.map(R.pipe(R.prop('unsub'), R.call), subControllers) + const sub = async (id, cb, filter) => { + const subControllers = Object.fromEntries( + Object.values(relays) + .filter(({policy}) => policy.read) + .map(({relay}) => [ + relay.url, + relay.sub({filter, cb: event => cb(event, relay)}) + ]) + ) + + activeSubscriptions[id] = { + sub: ({cb = cb, filter = filter}) => + Object.entries(subControllers).map(([relayURL, sub]) => [ + relayURL, + sub(id, {cb, filter}) + ]), + addRelay: relay => { + subControllers[relay.url] = relay.sub({cb, filter}) + }, + removeRelay: relayURL => { + subControllers[relayURL].unsub() + if (Object.keys(subControllers).length === 0) unsub() + }, + unsub: () => { + Object.values(subControllers).forEach(sub => sub.unsub()) + delete activeSubscriptions[id] + } } + + return activeSubscriptions[id] } return { - sub, + sub: sub.bind(null, Math.random()), relays, setPrivateKey(privateKey) { globalPrivateKey = privateKey @@ -47,21 +59,14 @@ export function relayPool(globalPrivateKey) { let relayURL = normalizeRelayURL(url) if (relayURL in relays) return - let relay = relayConnect( - url, - (context, event) => { - propagateEvent(context, event, relayURL) - }, - notice => { - propagateNotice(notice, relayURL) - } - ) + let relay = relayConnect(url, notice => { + propagateNotice(notice, relayURL) + }) relays[relayURL] = {relay, policy} - // automatically subscribe to everybody on this - for (let key in globalSub) { - relay.subKey(key) - } + Object.values(activeSubscriptions).forEach(subscription => + subscription.addRelay(relay) + ) return relay }, @@ -69,6 +74,9 @@ export function relayPool(globalPrivateKey) { let relayURL = normalizeRelayURL(url) let {relay} = relays[relayURL] if (!relay) return + Object.values(activeSubscriptions).forEach(subscription => + subscription.removeRelay(relay) + ) relay.close() delete relays[relayURL] }, diff --git a/relay.js b/relay.js index 51f74da..85b27b9 100644 --- a/relay.js +++ b/relay.js @@ -3,13 +3,11 @@ import 'websocket-polyfill' import {verifySignature} from './event' import {sha256} from './utils' -const R = require('ramda') - export function normalizeRelayURL(url) { let [host, ...qs] = url.split('?') if (host.slice(0, 4) === 'http') host = 'ws' + host.slice(4) + if (host.slice(0, 2) !== 'ws') host = 'wss://' + host if (host.length && host[host.length - 1] === '/') host = host.slice(0, -1) - if (host.slice(-3) !== '/ws') host = host + '/ws' return [host, ...qs].join('?') } @@ -118,20 +116,19 @@ export function relayConnect(url, onNotice) { } } - const sub = async (channel, cb, params) => { - trySend(['REQ', channel, params]) - + const sub = async (channel, {cb, filter}) => { + trySend(['REQ', channel, filter]) channels[channel] = cb return { - sub: R.partial(sub, [channel]), + sub: ({cb = cb, filter = filter}) => sub(channel, {cb, filter}), unsub: () => trySend(['CLOSE', channel]) } } return { url, - sub: R.partial(sub, [sha256(Math.random().toString())]), + sub: sub.bind(null, sha256(Math.random().toString())), async publish(event) { trySend(JSON.stringify(['EVENT', event])) },