Creates an interface for NostrClient
This commit is contained in:
+110
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip01Core.relay.client
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayPool
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
interface INostrClient {
|
||||
fun relayStatusFlow(): StateFlow<RelayPool.RelayPoolStatus>
|
||||
|
||||
fun connect()
|
||||
|
||||
fun disconnect()
|
||||
|
||||
fun isActive(): Boolean
|
||||
|
||||
fun openReqSubscription(
|
||||
subId: String = newSubId(),
|
||||
filters: Map<NormalizedRelayUrl, List<Filter>>,
|
||||
)
|
||||
|
||||
fun openCountSubscription(
|
||||
subId: String = newSubId(),
|
||||
filters: Map<NormalizedRelayUrl, List<Filter>>,
|
||||
)
|
||||
|
||||
fun close(subscriptionId: String)
|
||||
|
||||
fun sendIfExists(
|
||||
event: Event,
|
||||
connectedRelay: NormalizedRelayUrl,
|
||||
)
|
||||
|
||||
fun send(
|
||||
event: Event,
|
||||
relayList: Set<NormalizedRelayUrl>,
|
||||
)
|
||||
|
||||
fun subscribe(listener: IRelayClientListener)
|
||||
|
||||
fun unsubscribe(listener: IRelayClientListener)
|
||||
|
||||
fun getReqFiltersOrNull(subId: String): Map<NormalizedRelayUrl, List<Filter>>?
|
||||
|
||||
fun getCountFiltersOrNull(subId: String): Map<NormalizedRelayUrl, List<Filter>>?
|
||||
}
|
||||
|
||||
object EmptyNostrClient : INostrClient {
|
||||
override fun relayStatusFlow() = MutableStateFlow(RelayPool.RelayPoolStatus())
|
||||
|
||||
override fun connect() { }
|
||||
|
||||
override fun disconnect() { }
|
||||
|
||||
override fun isActive() = false
|
||||
|
||||
override fun openReqSubscription(
|
||||
subId: String,
|
||||
filters: Map<NormalizedRelayUrl, List<Filter>>,
|
||||
) { }
|
||||
|
||||
override fun openCountSubscription(
|
||||
subId: String,
|
||||
filters: Map<NormalizedRelayUrl, List<Filter>>,
|
||||
) { }
|
||||
|
||||
override fun close(subscriptionId: String) { }
|
||||
|
||||
override fun sendIfExists(
|
||||
event: Event,
|
||||
connectedRelay: NormalizedRelayUrl,
|
||||
) { }
|
||||
|
||||
override fun send(
|
||||
event: Event,
|
||||
relayList: Set<NormalizedRelayUrl>,
|
||||
) { }
|
||||
|
||||
override fun subscribe(listener: IRelayClientListener) {}
|
||||
|
||||
override fun unsubscribe(listener: IRelayClientListener) {}
|
||||
|
||||
override fun getReqFiltersOrNull(subId: String): Map<NormalizedRelayUrl, List<Filter>>? = null
|
||||
|
||||
override fun getCountFiltersOrNull(subId: String): Map<NormalizedRelayUrl, List<Filter>>? = null
|
||||
}
|
||||
+18
-16
@@ -29,7 +29,6 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.PoolSubscriptionRepo
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayPool
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.basic.BasicRelayClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.stats.RelayStats
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
@@ -73,7 +72,8 @@ import kotlinx.coroutines.flow.stateIn
|
||||
class NostrClient(
|
||||
private val websocketBuilder: WebsocketBuilder,
|
||||
private val scope: CoroutineScope,
|
||||
) : IRelayClientListener {
|
||||
) : INostrClient,
|
||||
IRelayClientListener {
|
||||
private val relayPool: RelayPool = RelayPool(this, ::buildRelay)
|
||||
private val activeRequests: PoolSubscriptionRepository = PoolSubscriptionRepository()
|
||||
private val activeCounts: PoolSubscriptionRepository = PoolSubscriptionRepository()
|
||||
@@ -124,17 +124,17 @@ class NostrClient(
|
||||
}
|
||||
|
||||
// Reconnects all relays that may have disconnected
|
||||
fun connect() {
|
||||
override fun connect() {
|
||||
isActive = true
|
||||
relayPool.connect()
|
||||
}
|
||||
|
||||
fun disconnect() {
|
||||
override fun disconnect() {
|
||||
isActive = false
|
||||
relayPool.disconnect()
|
||||
}
|
||||
|
||||
fun isActive() = isActive
|
||||
override fun isActive() = isActive
|
||||
|
||||
@Synchronized
|
||||
fun reconnect(onlyIfChanged: Boolean = false) {
|
||||
@@ -204,8 +204,8 @@ class NostrClient(
|
||||
return false
|
||||
}
|
||||
|
||||
fun openReqSubscription(
|
||||
subId: String = newSubId(),
|
||||
override fun openReqSubscription(
|
||||
subId: String,
|
||||
filters: Map<NormalizedRelayUrl, List<Filter>>,
|
||||
) {
|
||||
val oldFilters = activeRequests.getSubscriptionFiltersOrNull(subId) ?: emptyMap()
|
||||
@@ -240,8 +240,8 @@ class NostrClient(
|
||||
}
|
||||
}
|
||||
|
||||
fun openCountSubscription(
|
||||
subId: String = newSubId(),
|
||||
override fun openCountSubscription(
|
||||
subId: String,
|
||||
filters: Map<NormalizedRelayUrl, List<Filter>>,
|
||||
) {
|
||||
val oldFilters = activeCounts.getSubscriptionFiltersOrNull(subId) ?: emptyMap()
|
||||
@@ -276,7 +276,7 @@ class NostrClient(
|
||||
}
|
||||
}
|
||||
|
||||
fun sendIfExists(
|
||||
override fun sendIfExists(
|
||||
event: Event,
|
||||
connectedRelay: NormalizedRelayUrl,
|
||||
) {
|
||||
@@ -288,7 +288,7 @@ class NostrClient(
|
||||
}
|
||||
}
|
||||
|
||||
fun send(
|
||||
override fun send(
|
||||
event: Event,
|
||||
relayList: Set<NormalizedRelayUrl>,
|
||||
) {
|
||||
@@ -301,7 +301,7 @@ class NostrClient(
|
||||
}
|
||||
}
|
||||
|
||||
fun close(subscriptionId: String) {
|
||||
override fun close(subscriptionId: String) {
|
||||
activeRequests.remove(subscriptionId)
|
||||
activeCounts.remove(subscriptionId)
|
||||
relayPool.close(subscriptionId)
|
||||
@@ -386,13 +386,13 @@ class NostrClient(
|
||||
listeners.forEach { it.onError(relay, subId, error) }
|
||||
}
|
||||
|
||||
fun subscribe(listener: IRelayClientListener) {
|
||||
override fun subscribe(listener: IRelayClientListener) {
|
||||
listeners = listeners.plus(listener)
|
||||
}
|
||||
|
||||
fun isSubscribed(listener: IRelayClientListener): Boolean = listeners.contains(listener)
|
||||
|
||||
fun unsubscribe(listener: IRelayClientListener) {
|
||||
override fun unsubscribe(listener: IRelayClientListener) {
|
||||
listeners = listeners.minus(listener)
|
||||
}
|
||||
|
||||
@@ -402,7 +402,9 @@ class NostrClient(
|
||||
|
||||
fun activeOutboxCache(url: NormalizedRelayUrl): Set<HexKey> = eventOutbox.activeOutboxCacheFor(url)
|
||||
|
||||
fun getSubscriptionFiltersOrNull(subId: String): Map<NormalizedRelayUrl, List<Filter>>? = activeRequests.getSubscriptionFiltersOrNull(subId)
|
||||
override fun getReqFiltersOrNull(subId: String): Map<NormalizedRelayUrl, List<Filter>>? = activeRequests.getSubscriptionFiltersOrNull(subId)
|
||||
|
||||
fun relayStatusFlow() = relayPool.statusFlow
|
||||
override fun getCountFiltersOrNull(subId: String): Map<NormalizedRelayUrl, List<Filter>>? = activeCounts.getSubscriptionFiltersOrNull(subId)
|
||||
|
||||
override fun relayStatusFlow() = relayPool.statusFlow
|
||||
}
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@
|
||||
package com.vitorpamplona.quartz.nip01Core.relay.client.accessories
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId
|
||||
@@ -32,7 +32,7 @@ import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
fun NostrClient.downloadFirstEvent(
|
||||
fun INostrClient.downloadFirstEvent(
|
||||
subscriptionId: String = newSubId(),
|
||||
filters: Map<NormalizedRelayUrl, List<Filter>>,
|
||||
onResponse: (Event) -> Unit,
|
||||
|
||||
+3
-2
@@ -21,6 +21,7 @@
|
||||
package com.vitorpamplona.quartz.nip01Core.relay.client.subscriptions
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
|
||||
@@ -47,7 +48,7 @@ import com.vitorpamplona.quartz.utils.LargeCache
|
||||
* - Dismiss subscriptions with [dismissSubscription].
|
||||
*/
|
||||
class SubscriptionController(
|
||||
val client: NostrClient,
|
||||
val client: INostrClient,
|
||||
) {
|
||||
private val subscriptions = LargeCache<String, Subscription>()
|
||||
private val stats = SubscriptionStats()
|
||||
@@ -108,7 +109,7 @@ class SubscriptionController(
|
||||
fun updateRelays() {
|
||||
val currentFilters =
|
||||
subscriptions.associateWith { id, sub ->
|
||||
client.getSubscriptionFiltersOrNull(id)
|
||||
client.getReqFiltersOrNull(id)
|
||||
}
|
||||
|
||||
subscriptions.forEach { id, sub ->
|
||||
|
||||
Reference in New Issue
Block a user