forked from nostr/nostrweb
feed: update subscriptions
playing around with subscriptions, feed now loads profile names, profile views also show replied to notes and notes recursively search for replies or replies. this commit does too many subscriptions, ideally a max of three subscriptions are done at once. in future commit it would be nice to subscribe modularly, have done callbacks or push into subscribe next queues.
parent
7113bf1a4d
commit
30809ccbce
|
@ -49,17 +49,17 @@ const renderFeed = bounce(() => {
|
|||
switch (view.type) {
|
||||
case 'note':
|
||||
textNoteList
|
||||
.concat(replyList)
|
||||
.concat(replyList) // search id in notes and replies
|
||||
.filter(note => note.id === view.id)
|
||||
.forEach(renderNote);
|
||||
break;
|
||||
case 'profile':
|
||||
const isEvent = <T>(evt?: T): evt is T => evt !== undefined;
|
||||
[
|
||||
...textNoteList
|
||||
...textNoteList // get notes
|
||||
.filter(note => note.pubkey === view.id),
|
||||
...replyList.filter(reply => reply.pubkey === view.id)
|
||||
.map(reply => textNoteList.find(note => note.id === reply.replyTo) || replyList.find(note => note.id === reply.replyTo) )
|
||||
...replyList.filter(reply => reply.pubkey === view.id) // and replies
|
||||
.map(reply => textNoteList.find(note => note.id === reply.replyTo)) // and the replied to notes
|
||||
.filter(isEvent)
|
||||
]
|
||||
.sort(sortByCreatedAt)
|
||||
|
|
|
@ -8,11 +8,12 @@ type SubCallback = (
|
|||
type Subscribe = {
|
||||
cb: SubCallback;
|
||||
filter: Filter;
|
||||
unsub?: boolean;
|
||||
};
|
||||
|
||||
const relayList: Array<Relay> = [];
|
||||
const subList: Array<Sub> = [];
|
||||
const currentSubList: Array<Subscribe> = [];
|
||||
const relayMap = new Map<string, Relay>();
|
||||
|
||||
export const addRelay = async (url: string) => {
|
||||
const relay = relayInit(url);
|
||||
|
@ -25,13 +26,13 @@ export const addRelay = async (url: string) => {
|
|||
try {
|
||||
await relay.connect();
|
||||
currentSubList.forEach(({cb, filter}) => subscribe(cb, filter, relay));
|
||||
relayList.push(relay);
|
||||
relayMap.set(url, relay);
|
||||
} catch {
|
||||
console.warn(`could not connect to ${url}`);
|
||||
}
|
||||
};
|
||||
|
||||
const unsubscribe = (sub: Sub) => {
|
||||
export const unsubscribe = (sub: Sub) => {
|
||||
sub.unsub();
|
||||
subList.splice(subList.indexOf(sub), 1);
|
||||
};
|
||||
|
@ -40,28 +41,38 @@ const subscribe = (
|
|||
cb: SubCallback,
|
||||
filter: Filter,
|
||||
relay: Relay,
|
||||
unsub?: boolean
|
||||
) => {
|
||||
const sub = relay.sub([filter]);
|
||||
subList.push(sub);
|
||||
sub.on('event', (event: Event) => {
|
||||
cb(event, relay.url);
|
||||
});
|
||||
sub.on('eose', () => {
|
||||
// console.log('eose', relay.url);
|
||||
// unsubscribe(sub);
|
||||
});
|
||||
};
|
||||
|
||||
const subscribeAll = (
|
||||
cb: SubCallback,
|
||||
filter: Filter,
|
||||
) => {
|
||||
relayList.forEach(relay => subscribe(cb, filter, relay));
|
||||
if (unsub) {
|
||||
sub.on('eose', () => {
|
||||
console.log('eose', relay.url);
|
||||
unsubscribe(sub);
|
||||
});
|
||||
}
|
||||
return sub;
|
||||
};
|
||||
|
||||
export const sub = (obj: Subscribe) => {
|
||||
currentSubList.push(obj);
|
||||
subscribeAll(obj.cb, obj.filter);
|
||||
relayMap.forEach((relay) => subscribe(obj.cb, obj.filter, relay, obj.unsub));
|
||||
};
|
||||
|
||||
export const subOnce = (
|
||||
obj: Subscribe & {relay: string}
|
||||
) => {
|
||||
const relay = relayMap.get(obj.relay);
|
||||
if (relay) {
|
||||
const sub = subscribe(obj.cb, obj.filter, relay);
|
||||
sub.on('eose', () => {
|
||||
console.log('eose', obj.relay);
|
||||
unsubscribe(sub);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const unsubAll = () => {
|
||||
|
@ -78,7 +89,7 @@ export const publish = (
|
|||
event: Event,
|
||||
cb: PublishCallback,
|
||||
) => {
|
||||
relayList.forEach(relay => {
|
||||
relayMap.forEach((relay, url) => {
|
||||
const pub = relay.publish(event);
|
||||
pub.on('ok', () => {
|
||||
console.info(`${relay.url} has accepted our event`);
|
||||
|
@ -91,9 +102,10 @@ export const publish = (
|
|||
});
|
||||
};
|
||||
|
||||
addRelay('wss://relay.snort.social'); // good one
|
||||
|
||||
addRelay('wss://relay.snort.social');
|
||||
addRelay('wss://nostr.bitcoiner.social');
|
||||
addRelay('wss://nostr.mom');
|
||||
addRelay('wss://relay.nostr.bg');
|
||||
addRelay('wss://nos.lol');
|
||||
addRelay('wss://relay.nostr.ch');
|
||||
// addRelay('wss://relay.nostr.ch');
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {Event} from 'nostr-tools';
|
||||
import {sub, unsubAll} from './relays';
|
||||
import {getReplyTo, hasEventTag, isMention} from './events';
|
||||
import {sub, subOnce, unsubAll} from './relays';
|
||||
|
||||
type SubCallback = (
|
||||
event: Event,
|
||||
|
@ -9,17 +10,86 @@ type SubCallback = (
|
|||
/** subscribe to global feed */
|
||||
export const sub24hFeed = (onEvent: SubCallback) => {
|
||||
unsubAll();
|
||||
sub({
|
||||
cb: onEvent,
|
||||
const now = Math.floor(Date.now() * 0.001);
|
||||
const pubkeys = new Set<string>();
|
||||
const notes = new Set<string>();
|
||||
sub({ // get past events
|
||||
cb: (evt, relay) => {
|
||||
pubkeys.add(evt.pubkey);
|
||||
notes.add(evt.id);
|
||||
onEvent(evt, relay);
|
||||
},
|
||||
filter: {
|
||||
kinds: [0, 1, 2, 7],
|
||||
// until: Math.floor(Date.now() * 0.001),
|
||||
since: Math.floor((Date.now() * 0.001) - (24 * 60 * 60)),
|
||||
limit: 50,
|
||||
}
|
||||
kinds: [1],
|
||||
until: now,
|
||||
since: Math.floor(now - (24 * 60 * 60)),
|
||||
limit: 100,
|
||||
},
|
||||
unsub: true
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
// get profile info
|
||||
sub({
|
||||
cb: onEvent,
|
||||
filter: {
|
||||
authors: Array.from(pubkeys),
|
||||
kinds: [0],
|
||||
limit: pubkeys.size,
|
||||
},
|
||||
unsub: true,
|
||||
});
|
||||
pubkeys.clear();
|
||||
|
||||
// get reactions
|
||||
sub({
|
||||
cb: onEvent,
|
||||
filter: {
|
||||
'#e': Array.from(notes),
|
||||
kinds: [7],
|
||||
until: now,
|
||||
since: Math.floor(now - (24 * 60 * 60)),
|
||||
},
|
||||
unsub: true,
|
||||
});
|
||||
notes.clear();
|
||||
}, 2000);
|
||||
|
||||
// subscribe to future notes, reactions and profile updates
|
||||
sub({
|
||||
cb: (evt, relay) => {
|
||||
onEvent(evt, relay);
|
||||
subOnce({ // get profil data
|
||||
relay,
|
||||
cb: onEvent,
|
||||
filter: {
|
||||
authors: [evt.pubkey],
|
||||
kinds: [0],
|
||||
limit: 1,
|
||||
}
|
||||
});
|
||||
},
|
||||
filter: {
|
||||
kinds: [0, 1, 7],
|
||||
since: now,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/** subscribe to global feed */
|
||||
// export const simpleSub24hFeed = (onEvent: SubCallback) => {
|
||||
// unsubAll();
|
||||
// sub({
|
||||
// cb: onEvent,
|
||||
// filter: {
|
||||
// kinds: [0, 1, 2, 7],
|
||||
// // until: Math.floor(Date.now() * 0.001),
|
||||
// since: Math.floor((Date.now() * 0.001) - (24 * 60 * 60)),
|
||||
// limit: 250,
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
|
||||
/** subscribe to a note id (nip-19) */
|
||||
export const subNote = (
|
||||
eventId: string,
|
||||
|
@ -32,14 +102,34 @@ export const subNote = (
|
|||
ids: [eventId],
|
||||
kinds: [1],
|
||||
limit: 1,
|
||||
}
|
||||
},
|
||||
unsub: true,
|
||||
});
|
||||
|
||||
const replies = new Set<string>();
|
||||
|
||||
const onReply = (evt: Event, relay: string) => {
|
||||
replies.add(evt.id)
|
||||
onEvent(evt, relay);
|
||||
unsubAll();
|
||||
sub({
|
||||
cb: onEvent,
|
||||
filter: {
|
||||
'#e': Array.from(replies),
|
||||
kinds: [1, 7],
|
||||
},
|
||||
unsub: true,
|
||||
});
|
||||
};
|
||||
|
||||
replies.add(eventId)
|
||||
sub({
|
||||
cb: onEvent,
|
||||
cb: onReply,
|
||||
filter: {
|
||||
'#e': [eventId],
|
||||
kinds: [1, 7],
|
||||
}
|
||||
},
|
||||
unsub: true,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -59,7 +149,25 @@ export const subProfile = (
|
|||
});
|
||||
// get notes for profile
|
||||
sub({
|
||||
cb: onEvent,
|
||||
cb: (evt, relay) => {
|
||||
const repliesTo = new Set<string>();
|
||||
if (evt.tags.some(hasEventTag) && !evt.tags.some(isMention)) {
|
||||
const note = getReplyTo(evt);
|
||||
if (note && !repliesTo.has(note)) {
|
||||
repliesTo.add(note);
|
||||
subOnce({
|
||||
relay,
|
||||
cb: onEvent,
|
||||
filter: {
|
||||
ids: [note],
|
||||
kinds: [1],
|
||||
limit: 1,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
onEvent(evt, relay);
|
||||
},
|
||||
filter: {
|
||||
authors: [pubkey],
|
||||
kinds: [1],
|
||||
|
|
|
@ -184,8 +184,8 @@ export const updateElemHeight = (
|
|||
|
||||
export const elemArticle = (
|
||||
content: Array<HTMLElement>,
|
||||
attrs: Attributes<HTMLElementTagNameMap['div']> = {}
|
||||
attrs: Attributes<HTMLElementTagNameMap['div']> = {},
|
||||
) => {
|
||||
const className = attrs.className ? ['mbox', attrs?.className].join(' ') : 'mbox';
|
||||
const className = attrs.className ? `mbox ${attrs.className}` : 'mbox';
|
||||
return elem('article', {...attrs, className}, content);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue