remove ramda and rework logic.

This commit is contained in:
fiatjaf
2021-02-18 16:04:41 -03:00
parent 87de1310b5
commit 3844f68d1a
3 changed files with 46 additions and 42 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "nostr-tools", "name": "nostr-tools",
"version": "0.4.0", "version": "0.4.1",
"description": "Tools for making a Nostr client.", "description": "Tools for making a Nostr client.",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -10,7 +10,6 @@
"dependencies": { "dependencies": {
"buffer": "^6.0.3", "buffer": "^6.0.3",
"noble-secp256k1": "^1.1.1", "noble-secp256k1": "^1.1.1",
"ramda": "^0.27.1",
"websocket-polyfill": "^0.0.3" "websocket-polyfill": "^0.0.3"
}, },
"keywords": [ "keywords": [

72
pool.js
View File

@@ -6,15 +6,8 @@ const R = require('ramda')
export function relayPool(globalPrivateKey) { export function relayPool(globalPrivateKey) {
const relays = {} const relays = {}
const globalSub = [] const globalSub = []
const eventCallbacks = []
const noticeCallbacks = [] 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) { function propagateNotice(notice, relayURL) {
for (let i = 0; i < noticeCallbacks.length; i++) { for (let i = 0; i < noticeCallbacks.length; i++) {
let {relay} = relays[relayURL] let {relay} = relays[relayURL]
@@ -22,23 +15,42 @@ export function relayPool(globalPrivateKey) {
} }
} }
const sub = async (cb, params) => { const activeSubscriptions = {}
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))
return { const sub = async (id, cb, filter) => {
sub: (cb, params) => const subControllers = Object.fromEntries(
R.map( Object.values(relays)
R.pipe(R.prop('sub'), R.flip(R.apply)([cb, params])), .filter(({policy}) => policy.read)
subControllers .map(({relay}) => [
), relay.url,
unsub: () => R.map(R.pipe(R.prop('unsub'), R.call), subControllers) 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 { return {
sub, sub: sub.bind(null, Math.random()),
relays, relays,
setPrivateKey(privateKey) { setPrivateKey(privateKey) {
globalPrivateKey = privateKey globalPrivateKey = privateKey
@@ -47,21 +59,14 @@ export function relayPool(globalPrivateKey) {
let relayURL = normalizeRelayURL(url) let relayURL = normalizeRelayURL(url)
if (relayURL in relays) return if (relayURL in relays) return
let relay = relayConnect( let relay = relayConnect(url, notice => {
url, propagateNotice(notice, relayURL)
(context, event) => { })
propagateEvent(context, event, relayURL)
},
notice => {
propagateNotice(notice, relayURL)
}
)
relays[relayURL] = {relay, policy} relays[relayURL] = {relay, policy}
// automatically subscribe to everybody on this Object.values(activeSubscriptions).forEach(subscription =>
for (let key in globalSub) { subscription.addRelay(relay)
relay.subKey(key) )
}
return relay return relay
}, },
@@ -69,6 +74,9 @@ export function relayPool(globalPrivateKey) {
let relayURL = normalizeRelayURL(url) let relayURL = normalizeRelayURL(url)
let {relay} = relays[relayURL] let {relay} = relays[relayURL]
if (!relay) return if (!relay) return
Object.values(activeSubscriptions).forEach(subscription =>
subscription.removeRelay(relay)
)
relay.close() relay.close()
delete relays[relayURL] delete relays[relayURL]
}, },

View File

@@ -3,13 +3,11 @@ import 'websocket-polyfill'
import {verifySignature} from './event' import {verifySignature} from './event'
import {sha256} from './utils' import {sha256} from './utils'
const R = require('ramda')
export function normalizeRelayURL(url) { export function normalizeRelayURL(url) {
let [host, ...qs] = url.split('?') let [host, ...qs] = url.split('?')
if (host.slice(0, 4) === 'http') host = 'ws' + host.slice(4) 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.length && host[host.length - 1] === '/') host = host.slice(0, -1)
if (host.slice(-3) !== '/ws') host = host + '/ws'
return [host, ...qs].join('?') return [host, ...qs].join('?')
} }
@@ -118,20 +116,19 @@ export function relayConnect(url, onNotice) {
} }
} }
const sub = async (channel, cb, params) => { const sub = async (channel, {cb, filter}) => {
trySend(['REQ', channel, params]) trySend(['REQ', channel, filter])
channels[channel] = cb channels[channel] = cb
return { return {
sub: R.partial(sub, [channel]), sub: ({cb = cb, filter = filter}) => sub(channel, {cb, filter}),
unsub: () => trySend(['CLOSE', channel]) unsub: () => trySend(['CLOSE', channel])
} }
} }
return { return {
url, url,
sub: R.partial(sub, [sha256(Math.random().toString())]), sub: sub.bind(null, sha256(Math.random().toString())),
async publish(event) { async publish(event) {
trySend(JSON.stringify(['EVENT', event])) trySend(JSON.stringify(['EVENT', event]))
}, },