mirror of
https://github.com/aljazceru/rabbit.git
synced 2025-12-17 14:04:21 +01:00
fix: latest event query
This commit is contained in:
@@ -6,6 +6,16 @@ import { compareEvents, pickLatestEvent, sortEvents } from '@/nostr/event/compar
|
|||||||
import { BatchedEventsTask, registerTask } from '@/nostr/useBatchedEvents';
|
import { BatchedEventsTask, registerTask } from '@/nostr/useBatchedEvents';
|
||||||
import timeout from '@/utils/timeout';
|
import timeout from '@/utils/timeout';
|
||||||
|
|
||||||
|
const chooseLatestEvent = (
|
||||||
|
prev: NostrEvent | undefined,
|
||||||
|
latest: NostrEvent | undefined,
|
||||||
|
): NostrEvent | undefined => {
|
||||||
|
if (latest != null && (prev == null || compareEvents(latest, prev) >= 0)) {
|
||||||
|
return latest;
|
||||||
|
}
|
||||||
|
return prev;
|
||||||
|
};
|
||||||
|
|
||||||
export const latestEventQuery =
|
export const latestEventQuery =
|
||||||
<K extends QueryKey>({
|
<K extends QueryKey>({
|
||||||
taskProvider,
|
taskProvider,
|
||||||
@@ -17,22 +27,32 @@ export const latestEventQuery =
|
|||||||
({ queryKey, signal }: { queryKey: K; signal?: AbortSignal }): Promise<NostrEvent | null> => {
|
({ queryKey, signal }: { queryKey: K; signal?: AbortSignal }): Promise<NostrEvent | null> => {
|
||||||
const task = taskProvider(queryKey);
|
const task = taskProvider(queryKey);
|
||||||
if (task == null) return Promise.resolve(null);
|
if (task == null) return Promise.resolve(null);
|
||||||
const promise = task.firstEventPromise().catch(() => {
|
const promise = task
|
||||||
throw new Error(`event not found: ${JSON.stringify(queryKey)}`);
|
.firstEventPromise()
|
||||||
});
|
.then((latest) => {
|
||||||
|
const prev = queryClient.getQueryData(queryKey) as NostrEvent;
|
||||||
|
return chooseLatestEvent(prev, latest) ?? null;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
throw new Error(`event not found: ${JSON.stringify(queryKey)}`);
|
||||||
|
});
|
||||||
|
|
||||||
task.onUpdate((events) => {
|
task.onUpdate((events) => {
|
||||||
const latest = pickLatestEvent(events);
|
const latest = pickLatestEvent(events);
|
||||||
queryClient.setQueriesData<NostrEvent>({ queryKey }, (prev) => {
|
queryClient.setQueriesData<NostrEvent>({ queryKey }, (prev) =>
|
||||||
if (latest != null && (prev == null || compareEvents(latest, prev) >= 0)) {
|
chooseLatestEvent(prev, latest),
|
||||||
return latest;
|
);
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
registerTask({ task, signal });
|
registerTask({ task, signal });
|
||||||
return timeout(15000, `${JSON.stringify(queryKey)}`)(promise);
|
return timeout(15000, `${JSON.stringify(queryKey)}`)(promise);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mergeEvents = (prev: NostrEvent[] | undefined, events: NostrEvent[]) => {
|
||||||
|
if (prev == null) return events;
|
||||||
|
const deduped = uniqBy([...prev, ...events], (e) => e.id);
|
||||||
|
return sortEvents(deduped);
|
||||||
|
};
|
||||||
|
|
||||||
export const eventsQuery =
|
export const eventsQuery =
|
||||||
<K extends QueryKey>({
|
<K extends QueryKey>({
|
||||||
taskProvider,
|
taskProvider,
|
||||||
@@ -44,14 +64,16 @@ export const eventsQuery =
|
|||||||
({ queryKey, signal }: { queryKey: K; signal?: AbortSignal }): Promise<NostrEvent[]> => {
|
({ queryKey, signal }: { queryKey: K; signal?: AbortSignal }): Promise<NostrEvent[]> => {
|
||||||
const task = taskProvider(queryKey);
|
const task = taskProvider(queryKey);
|
||||||
if (task == null) return Promise.resolve([]);
|
if (task == null) return Promise.resolve([]);
|
||||||
const promise = task.toUpdatePromise().catch(() => []);
|
const promise = task
|
||||||
|
.toUpdatePromise()
|
||||||
|
.then((events) => {
|
||||||
|
const prev: NostrEvent[] = queryClient.getQueryData(queryKey) ?? [];
|
||||||
|
return mergeEvents(prev, events);
|
||||||
|
})
|
||||||
|
.catch(() => []);
|
||||||
task.onUpdate((events) => {
|
task.onUpdate((events) => {
|
||||||
// TODO consider kind:5 deletion
|
// TODO consider kind:5 deletion
|
||||||
queryClient.setQueriesData<NostrEvent[]>({ queryKey }, (prev) => {
|
queryClient.setQueriesData<NostrEvent[]>({ queryKey }, (prev) => mergeEvents(prev, events));
|
||||||
if (prev == null) return events;
|
|
||||||
const deduped = uniqBy([...prev, ...events], (e) => e.id);
|
|
||||||
return sortEvents(deduped);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
registerTask({ task, signal });
|
registerTask({ task, signal });
|
||||||
return timeout(15000, `${JSON.stringify(queryKey)}`)(promise);
|
return timeout(15000, `${JSON.stringify(queryKey)}`)(promise);
|
||||||
|
|||||||
Reference in New Issue
Block a user