buffer subsequent requests to avoid hammering relays
This commit is contained in:
parent
6b831c62c7
commit
d8ac846fae
5 changed files with 40 additions and 23 deletions
12
demo.html
12
demo.html
|
|
@ -11,15 +11,11 @@
|
||||||
<p>Below, we have inserted a <code>script</code> tag that should
|
<p>Below, we have inserted a <code>script</code> tag that should
|
||||||
renter a Svelte component upon loading this page.</p>
|
renter a Svelte component upon loading this page.</p>
|
||||||
|
|
||||||
<script
|
<script src="public/bundle.js"
|
||||||
src="public/bundle.js"
|
data-chat-type="GLOBAL"
|
||||||
data-chat-type="GLOBAL"
|
data-chat-tags="nostrica,nostrica2023"
|
||||||
data-chat-tags="nostrica"
|
data-relays="wss://relay.nostrica.com,wss://relay.f7z.io,wss://nos.lol,wss://relay.nostr.info,wss://nostr-pub.wellorder.net,wss://relay.current.fyi,wss://relay.nostr.band"
|
||||||
data-relays="ws://localhost:8080"
|
|
||||||
></script>
|
></script>
|
||||||
<link rel="stylesheet" href="public/bundle.css">
|
|
||||||
></script>
|
|
||||||
|
|
||||||
|
|
||||||
<p>This text will come after the embedded content.</p>
|
<p>This text will come after the embedded content.</p>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -91,11 +91,16 @@
|
||||||
isThread = new Set(pubkeysTagged).size >= 2;
|
isThread = new Set(pubkeysTagged).size >= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
responses[message.id] = [];
|
if (!responses[message.id]) { responses[message.id] = [] };
|
||||||
|
|
||||||
if (isThread) {
|
if (isThread) {
|
||||||
|
// get the last "e" tag, which is tagging the immediate parent
|
||||||
const lastETag = message.tags.filter(tag => tag[0] === 'e').pop();
|
const lastETag = message.tags.filter(tag => tag[0] === 'e').pop();
|
||||||
if (lastETag && lastETag[1] && responses[lastETag[1]]) {
|
if (lastETag && lastETag[1]) {
|
||||||
|
// if there is one, add it to the response
|
||||||
|
if (!responses[lastETag[1]]) {
|
||||||
|
responses[lastETag[1]] = [];
|
||||||
|
}
|
||||||
responses[lastETag[1]].push(message);
|
responses[lastETag[1]].push(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
import { selectedMessage } from './lib/store';
|
import { selectedMessage } from './lib/store';
|
||||||
import { chatData } from './lib/store';
|
import { chatData, chatAdapter } from './lib/store';
|
||||||
|
// import { prettifyContent } from '$lib/utils';
|
||||||
export let event;
|
export let event;
|
||||||
export let responses;
|
export let responses;
|
||||||
export let websiteOwnerPubkey;
|
export let websiteOwnerPubkey;
|
||||||
|
|
@ -16,13 +18,20 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delay-fetch responses
|
||||||
|
onMount(() => {
|
||||||
|
$chatAdapter.delayedSubscribe(
|
||||||
|
{kinds: [1], '#e': [event.id]}
|
||||||
|
, 'responses', 500)
|
||||||
|
})
|
||||||
|
|
||||||
const byWebsiteOwner = !!websiteOwnerPubkey === event.pubkey;
|
const byWebsiteOwner = !!websiteOwnerPubkey === event.pubkey;
|
||||||
|
|
||||||
$: profiles = $chatData.profiles;
|
$: profiles = $chatData.profiles;
|
||||||
$: displayName = profiles[event.pubkey] && profiles[event.pubkey].display_name || `[${event.pubkey.slice(0, 6)}]`;
|
$: displayName = profiles[event.pubkey] && profiles[event.pubkey].display_name || `[${event.pubkey.slice(0, 6)}]`;
|
||||||
$: nip05 = profiles[event.pubkey] && profiles[event.pubkey].nip05;
|
$: nip05 = profiles[event.pubkey] && profiles[event.pubkey].nip05;
|
||||||
|
|
||||||
$: profilePicture = profiles[event.pubkey] && profiles[event.pubkey].picture || `https://robohash.org/${event.pubkey}.png?set=set1`;
|
$: profilePicture = profiles[event.pubkey] && profiles[event.pubkey].picture || `https://robohash.org/${event.pubkey.slice(0, 2)}.png?set=set1`;
|
||||||
|
|
||||||
const repliedIds = event.tags.filter(e => e[0] === 'e').map(e => e[1]);
|
const repliedIds = event.tags.filter(e => e[0] === 'e').map(e => e[1]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ class NstrAdapter {
|
||||||
#profileRequestQueue = [];
|
#profileRequestQueue = [];
|
||||||
#requestedProfiles = [];
|
#requestedProfiles = [];
|
||||||
#profileRequestTimer;
|
#profileRequestTimer;
|
||||||
|
#delayedSubscriptions = {};
|
||||||
|
#delayedSubscriptionTimeouts = {};
|
||||||
|
|
||||||
constructor(clientPubkey, {tags, referenceTags, type='DM', websiteOwnerPubkey, relays} = {}) {
|
constructor(clientPubkey, {tags, referenceTags, type='DM', websiteOwnerPubkey, relays} = {}) {
|
||||||
this.pubkey = clientPubkey;
|
this.pubkey = clientPubkey;
|
||||||
|
|
@ -72,8 +74,6 @@ class NstrAdapter {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('filters', filters);
|
|
||||||
|
|
||||||
if (filters && filters.length > 0) {
|
if (filters && filters.length > 0) {
|
||||||
this.subscribe(filters, (e) => { this.#emitMessage(e) })
|
this.subscribe(filters, (e) => { this.#emitMessage(e) })
|
||||||
}
|
}
|
||||||
|
|
@ -170,6 +170,21 @@ class NstrAdapter {
|
||||||
messageCallback(event)
|
messageCallback(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async delayedSubscribe(filters, family, timeout) {
|
||||||
|
this.#delayedSubscriptions[family] = this.#delayedSubscriptions[family] || []
|
||||||
|
this.#delayedSubscriptions[family].push(filters);
|
||||||
|
|
||||||
|
if (!this.#delayedSubscriptionTimeouts[family]) {
|
||||||
|
this.#delayedSubscriptionTimeouts[family] = setTimeout(() => {
|
||||||
|
delete this.#delayedSubscriptionTimeouts[family];
|
||||||
|
filters = this.#delayedSubscriptions[family];
|
||||||
|
delete this.#delayedSubscriptions[family];
|
||||||
|
|
||||||
|
this.subscribe(filters, (e) => { this.#emitMessage(e)});
|
||||||
|
}, timeout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async subscribe(filters, messageCallback=null) {
|
async subscribe(filters, messageCallback=null) {
|
||||||
if (!messageCallback) { messageCallback = (e) => { this.#emitMessage(e) } }
|
if (!messageCallback) { messageCallback = (e) => { this.#emitMessage(e) } }
|
||||||
return this.#_subscribe(filters, messageCallback)
|
return this.#_subscribe(filters, messageCallback)
|
||||||
|
|
@ -200,14 +215,6 @@ class NstrAdapter {
|
||||||
event.content = await this.decrypt(this.#websiteOwnerPubkey, event.content);
|
event.content = await this.decrypt(this.#websiteOwnerPubkey, event.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have tags we were filtering for, filter here in case the relay doesn't support filtering
|
|
||||||
if (this.tags && this.tags.length > 0) {
|
|
||||||
if (!event.tags.find(t => t[0] === 't' && this.tags.includes(t[1]))) {
|
|
||||||
console.log(`discarded event not tagged with [${this.tags.join(', ')}], tags: ${event.tags.filter(t => t[0] === 't').map(t => t[1]).join(', ')}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.kind === 1) {
|
if (event.kind === 1) {
|
||||||
if (!event.tags.find(t => t[0] === 'e')) {
|
if (!event.tags.find(t => t[0] === 'e')) {
|
||||||
// a top level message that we should subscribe to since responses won't tag the url
|
// a top level message that we should subscribe to since responses won't tag the url
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@
|
||||||
chatType,
|
chatType,
|
||||||
chatTags,
|
chatTags,
|
||||||
chatReferenceTags,
|
chatReferenceTags,
|
||||||
}} {websiteOwnerPubkey} {relays} bind:chatStarted={chatStarted} />
|
}} {relays} bind:chatStarted={chatStarted} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue