useSubscribe, handle emitted requests in sqlite
This commit is contained in:
@ -8,7 +8,7 @@ export async function sendEventToRelays(
|
||||
setResults?: (x: Array<OkResponse>) => void,
|
||||
) {
|
||||
if (customRelays) {
|
||||
system.HandleEvent({ ...ev, relays: [] });
|
||||
system.HandleEvent("*", { ...ev, relays: [] });
|
||||
return removeUndefined(
|
||||
await Promise.all(
|
||||
customRelays.map(async r => {
|
||||
|
@ -36,10 +36,10 @@ const TimelineFollows = (props: TimelineFollowsProps) => {
|
||||
const [latest, setLatest] = useHistoryState(unixNow(), "TimelineFollowsLatest");
|
||||
const [limit, setLimit] = useState(50);
|
||||
const feed = useFollowsTimelineView(limit);
|
||||
console.log("feed", feed);
|
||||
const { muted, isEventMuted } = useModeration();
|
||||
|
||||
const sortedFeed = useMemo(() => orderDescending(feed), [feed]);
|
||||
const oldest = useMemo(() => sortedFeed.at(-1)?.created_at, [sortedFeed]);
|
||||
const oldest = useMemo(() => feed.at(-1)?.created_at, [feed]);
|
||||
|
||||
const postsOnly = useCallback(
|
||||
(a: NostrEvent) => (props.postsOnly ? !a.tags.some(b => b[0] === "e" || b[0] === "a") : true),
|
||||
@ -58,8 +58,8 @@ const TimelineFollows = (props: TimelineFollowsProps) => {
|
||||
|
||||
const mixin = useHashtagsFeed();
|
||||
const mainFeed = useMemo(() => {
|
||||
return filterPosts((sortedFeed ?? []).filter(a => a.created_at <= latest));
|
||||
}, [sortedFeed, filterPosts, latest, login.follows.timestamp]);
|
||||
return filterPosts((feed ?? []).filter(a => a.created_at <= latest));
|
||||
}, [feed, filterPosts, latest, login.follows.timestamp]);
|
||||
|
||||
const findHashTagContext = (a: NostrEvent) => {
|
||||
const tag = a.tags.filter(a => a[0] === "t").find(a => login.tags.item.includes(a[1].toLowerCase()))?.[1];
|
||||
@ -81,12 +81,12 @@ const TimelineFollows = (props: TimelineFollowsProps) => {
|
||||
}, [mixin, mainFeed, postsOnly, isEventMuted]);
|
||||
|
||||
const latestFeed = useMemo(() => {
|
||||
return filterPosts((sortedFeed ?? []).filter(a => a.created_at > latest));
|
||||
}, [sortedFeed, latest]);
|
||||
return filterPosts((feed ?? []).filter(a => a.created_at > latest));
|
||||
}, [feed, latest]);
|
||||
|
||||
const liveStreams = useMemo(() => {
|
||||
return (sortedFeed ?? []).filter(a => a.kind === EventKind.LiveEvent && findTag(a, "status") === "live");
|
||||
}, [sortedFeed]);
|
||||
return (feed ?? []).filter(a => a.kind === EventKind.LiveEvent && findTag(a, "status") === "live");
|
||||
}, [feed]);
|
||||
|
||||
const latestAuthors = useMemo(() => {
|
||||
return dedupeByPubkey(latestFeed).map(e => e.pubkey);
|
||||
@ -120,7 +120,7 @@ const TimelineFollows = (props: TimelineFollowsProps) => {
|
||||
}}
|
||||
displayAs={displayAs}
|
||||
/>
|
||||
{sortedFeed.length > 0 && (
|
||||
{feed.length > 0 && (
|
||||
<ShowMoreInView
|
||||
onClick={() => {
|
||||
setLimit(s => s + 20);
|
||||
|
@ -35,7 +35,7 @@ export default function TrendingNotes({ count = Infinity, small = false }: { cou
|
||||
console.error(`Event with invalid sig\n\n${ev}\n\nfrom ${trendingNotesUrl}`);
|
||||
return;
|
||||
}
|
||||
System.HandleEvent(ev as TaggedNostrEvent);
|
||||
System.HandleEvent("*", ev as TaggedNostrEvent);
|
||||
return ev;
|
||||
}),
|
||||
);
|
||||
|
@ -4,6 +4,7 @@ import { useRequestBuilder } from "@snort/system-react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
import useLogin from "@/Hooks/useLogin";
|
||||
import useSubscribe from "@/Hooks/useSubscribe";
|
||||
import { Relay } from "@/system";
|
||||
import { Day } from "@/Utils/Const";
|
||||
|
||||
@ -77,16 +78,15 @@ export function useFollowsTimelineView(limit = 20) {
|
||||
const follows = useLogin(s => s.follows.item);
|
||||
const kinds = [EventKind.TextNote, EventKind.Repost, EventKind.Polls];
|
||||
|
||||
const filter = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
authors: follows,
|
||||
kinds,
|
||||
limit,
|
||||
},
|
||||
];
|
||||
}, [follows, limit]);
|
||||
return useWorkerRelayView("follows-timeline", filter, Day * 7);
|
||||
const filter = useMemo(
|
||||
() => ({
|
||||
authors: follows,
|
||||
kinds,
|
||||
limit,
|
||||
}),
|
||||
[follows, limit],
|
||||
);
|
||||
return useSubscribe("follows-timeline", filter);
|
||||
}
|
||||
|
||||
export function useNotificationsView() {
|
||||
@ -101,7 +101,7 @@ export function useNotificationsView() {
|
||||
},
|
||||
];
|
||||
}, [publicKey]);
|
||||
return useWorkerRelayView("notifications", req, Day * 30);
|
||||
return useSubscribe("notifications", req[0]);
|
||||
}
|
||||
|
||||
export function useReactionsView(ids: Array<NostrLink>, leaveOpen = true) {
|
||||
@ -123,7 +123,7 @@ export function useReactionsView(ids: Array<NostrLink>, leaveOpen = true) {
|
||||
return rb.buildRaw();
|
||||
}, [ids]);
|
||||
|
||||
return useWorkerRelayView("reactions", req, undefined);
|
||||
return useSubscribe("reactions", req[0]);
|
||||
}
|
||||
|
||||
export function useReactionsViewCount(ids: Array<NostrLink>, leaveOpen = true) {
|
||||
@ -160,5 +160,5 @@ export function useFollowsContactListView() {
|
||||
},
|
||||
];
|
||||
}, [follows]);
|
||||
return useWorkerRelayView("follows-contacts-relays", filter, undefined);
|
||||
return useSubscribe("follows-contacts-relays", filter[0]);
|
||||
}
|
||||
|
31
packages/app/src/Hooks/useSubscribe.ts
Normal file
31
packages/app/src/Hooks/useSubscribe.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { ReqFilter, RequestBuilder, TaggedNostrEvent } from "@snort/system";
|
||||
import inMemoryDB from "@snort/system/src/InMemoryDB";
|
||||
import { useRequestBuilder } from "@snort/system-react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
import { System } from "@/system";
|
||||
|
||||
export default function useSubscribe(id: string, filter: ReqFilter): TaggedNostrEvent[] {
|
||||
const getEvents = () => inMemoryDB.findArray(filter);
|
||||
const [events, setEvents] = useState(getEvents());
|
||||
const rb = useMemo(() => {
|
||||
const rb = new RequestBuilder(id);
|
||||
rb.withBareFilter(filter);
|
||||
return rb;
|
||||
}, [id, filter]);
|
||||
useRequestBuilder(rb);
|
||||
|
||||
useEffect(() => {
|
||||
const cb = (subId: string) => {
|
||||
if (subId === id) {
|
||||
setEvents(getEvents());
|
||||
}
|
||||
};
|
||||
System.on("event", cb);
|
||||
return () => {
|
||||
System.off("event", cb);
|
||||
};
|
||||
}, [id, filter]);
|
||||
|
||||
return events as Array<TaggedNostrEvent>;
|
||||
}
|
@ -91,7 +91,7 @@ export class Nip29ChatSystem extends ExternalStore<Array<Chat>> implements ChatS
|
||||
},
|
||||
sendMessage: async (ev, system: SystemInterface) => {
|
||||
ev.forEach(async a => {
|
||||
system.HandleEvent({ ...a, relays: [] });
|
||||
system.HandleEvent("*", { ...a, relays: [] });
|
||||
await system.WriteOnceToRelay(`wss://${relay}`, a);
|
||||
});
|
||||
},
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { removeUndefined, throwIfOffline } from "@snort/shared";
|
||||
import LRUSet from "@snort/shared/src/LRUSet";
|
||||
import { mapEventToProfile, NostrEvent, NostrSystem, ProfileLoaderService, socialGraphInstance } from "@snort/system";
|
||||
import { WorkerRelayInterface } from "@snort/worker-relay";
|
||||
import WorkerRelayPath from "@snort/worker-relay/dist/worker?worker&url";
|
||||
@ -70,9 +71,21 @@ export async function initRelayWorker() {
|
||||
if (await Relay.init()) {
|
||||
if (await Relay.open()) {
|
||||
await Relay.migrate();
|
||||
const seen = new LRUSet<string>(100);
|
||||
System.on("event", async (_, ev) => {
|
||||
if (seen.has(ev.id)) return;
|
||||
seen.add(ev.id);
|
||||
await Relay.event(ev);
|
||||
});
|
||||
System.on("request", async (subId, f) => {
|
||||
const evs = await Relay.req(["REQ", "", ...f.filters]);
|
||||
evs.forEach(ev => {
|
||||
seen.add(ev.id);
|
||||
queueMicrotask(() => {
|
||||
System.HandleEvent(subId, { ...ev, relays: [] });
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
Reference in New Issue
Block a user