mirror of
https://github.com/luminous-devs/lume.git
synced 2024-10-02 09:50:47 +00:00
add prefetch data
This commit is contained in:
parent
f4390b29e2
commit
6f68c2762b
@ -34,6 +34,7 @@
|
|||||||
"@radix-ui/react-toolbar": "^1.0.4",
|
"@radix-ui/react-toolbar": "^1.0.4",
|
||||||
"@radix-ui/react-tooltip": "^1.0.7",
|
"@radix-ui/react-tooltip": "^1.0.7",
|
||||||
"@tanstack/react-query": "^5.8.7",
|
"@tanstack/react-query": "^5.8.7",
|
||||||
|
"@tanstack/react-query-devtools": "^5.10.0",
|
||||||
"@tauri-apps/api": "2.0.0-alpha.11",
|
"@tauri-apps/api": "2.0.0-alpha.11",
|
||||||
"@tauri-apps/cli": "2.0.0-alpha.17",
|
"@tauri-apps/cli": "2.0.0-alpha.17",
|
||||||
"@tauri-apps/plugin-autostart": "2.0.0-alpha.3",
|
"@tauri-apps/plugin-autostart": "2.0.0-alpha.3",
|
||||||
|
@ -53,6 +53,9 @@ dependencies:
|
|||||||
'@tanstack/react-query':
|
'@tanstack/react-query':
|
||||||
specifier: ^5.8.7
|
specifier: ^5.8.7
|
||||||
version: 5.8.7(react-dom@18.2.0)(react@18.2.0)
|
version: 5.8.7(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@tanstack/react-query-devtools':
|
||||||
|
specifier: ^5.10.0
|
||||||
|
version: 5.10.0(@tanstack/react-query@5.8.7)(react@18.2.0)
|
||||||
'@tauri-apps/api':
|
'@tauri-apps/api':
|
||||||
specifier: 2.0.0-alpha.11
|
specifier: 2.0.0-alpha.11
|
||||||
version: 2.0.0-alpha.11
|
version: 2.0.0-alpha.11
|
||||||
@ -2058,6 +2061,21 @@ packages:
|
|||||||
resolution: {integrity: sha512-58xOSkxxZK4SGQ/uzX8MDZHLGZCkxlgkPxnfhxUOL2uchnNHyay2UVcR3mQNMgaMwH1e2l+0n+zfS7+UJ/MAJw==}
|
resolution: {integrity: sha512-58xOSkxxZK4SGQ/uzX8MDZHLGZCkxlgkPxnfhxUOL2uchnNHyay2UVcR3mQNMgaMwH1e2l+0n+zfS7+UJ/MAJw==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@tanstack/query-devtools@5.10.0:
|
||||||
|
resolution: {integrity: sha512-ZN17ZHiPFc8B1AZplueTLI6qxqNPuelV/8Q6gx2coNac2++AD1gq8NvCQxfq9HoaqFJM8xqS3oPYxa3HZZTo8w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@tanstack/react-query-devtools@5.10.0(@tanstack/react-query@5.8.7)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-amQN/6BdSMiYtILISk5j3IrZZiWz+HOHjJdcJNZHaTpzS7aIM1Z82bghCSoPdBtS7P1KbdoW35aD4glm9EkIuQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@tanstack/react-query': ^5.10.0
|
||||||
|
react: ^18.0.0
|
||||||
|
dependencies:
|
||||||
|
'@tanstack/query-devtools': 5.10.0
|
||||||
|
'@tanstack/react-query': 5.8.7(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
react: 18.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@tanstack/react-query@5.8.7(react-dom@18.2.0)(react@18.2.0):
|
/@tanstack/react-query@5.8.7(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-RYSSMmkhbJ7tPkf8w+MSRIXQLoUCm7DRnTLDcdf+uampupnriEsob3fVWTt9oaEj+AJWEKeCErDBdZeNcAzURQ==}
|
resolution: {integrity: sha512-RYSSMmkhbJ7tPkf8w+MSRIXQLoUCm7DRnTLDcdf+uampupnriEsob3fVWTt9oaEj+AJWEKeCErDBdZeNcAzURQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -1,66 +1,28 @@
|
|||||||
import NDK, { NDKNip46Signer, NDKPrivateKeySigner } from '@nostr-dev-kit/ndk';
|
import NDK, {
|
||||||
|
NDKEvent,
|
||||||
|
NDKKind,
|
||||||
|
NDKNip46Signer,
|
||||||
|
NDKPrivateKeySigner,
|
||||||
|
} from '@nostr-dev-kit/ndk';
|
||||||
import { ndkAdapter } from '@nostr-fetch/adapter-ndk';
|
import { ndkAdapter } from '@nostr-fetch/adapter-ndk';
|
||||||
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { ask } from '@tauri-apps/plugin-dialog';
|
import { ask } from '@tauri-apps/plugin-dialog';
|
||||||
import { fetch } from '@tauri-apps/plugin-http';
|
|
||||||
import { relaunch } from '@tauri-apps/plugin-process';
|
import { relaunch } from '@tauri-apps/plugin-process';
|
||||||
import { NostrFetcher } from 'nostr-fetch';
|
import { NostrFetcher } from 'nostr-fetch';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { toast } from 'sonner';
|
|
||||||
|
|
||||||
import NDKCacheAdapterTauri from '@libs/ndk/cache';
|
import NDKCacheAdapterTauri from '@libs/ndk/cache';
|
||||||
import { useStorage } from '@libs/storage/provider';
|
import { useStorage } from '@libs/storage/provider';
|
||||||
|
|
||||||
|
import { FETCH_LIMIT } from '@stores/constants';
|
||||||
|
|
||||||
export const NDKInstance = () => {
|
export const NDKInstance = () => {
|
||||||
const [ndk, setNDK] = useState<NDK | undefined>(undefined);
|
|
||||||
const [relayUrls, setRelayUrls] = useState<string[]>([]);
|
|
||||||
|
|
||||||
const { db } = useStorage();
|
const { db } = useStorage();
|
||||||
const fetcher = useMemo(
|
const queryClient = useQueryClient();
|
||||||
() => (ndk ? NostrFetcher.withCustomPool(ndkAdapter(ndk)) : null),
|
|
||||||
[ndk]
|
|
||||||
);
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
const [ndk, setNDK] = useState<NDK | undefined>(undefined);
|
||||||
async function getExplicitRelays() {
|
const [fetcher, setFetcher] = useState<NostrFetcher | undefined>(undefined);
|
||||||
try {
|
const [relayUrls, setRelayUrls] = useState<string[]>([]);
|
||||||
// get relays
|
|
||||||
const relays = await db.getExplicitRelayUrls();
|
|
||||||
const onlineRelays = new Set(relays);
|
|
||||||
|
|
||||||
const controller = new AbortController();
|
|
||||||
const timeoutId = setTimeout(() => controller.abort(), 8000);
|
|
||||||
|
|
||||||
for (const relay of relays) {
|
|
||||||
try {
|
|
||||||
const url = new URL(relay);
|
|
||||||
const res = await fetch(`https://${url.hostname}`, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
Accept: 'application/nostr+json',
|
|
||||||
},
|
|
||||||
signal: controller.signal,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
toast.warning(`${relay} is not working, skipping...`);
|
|
||||||
onlineRelays.delete(relay);
|
|
||||||
}
|
|
||||||
|
|
||||||
toast.success(`Connected to ${relay}`);
|
|
||||||
} catch {
|
|
||||||
toast.warning(`${relay} is not working, skipping...`);
|
|
||||||
onlineRelays.delete(relay);
|
|
||||||
} finally {
|
|
||||||
clearTimeout(timeoutId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return all online relays
|
|
||||||
return [...onlineRelays];
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getSigner(nsecbunker?: boolean) {
|
async function getSigner(nsecbunker?: boolean) {
|
||||||
if (!db.account) return;
|
if (!db.account) return;
|
||||||
@ -104,17 +66,88 @@ export const NDKInstance = () => {
|
|||||||
|
|
||||||
// connect
|
// connect
|
||||||
await instance.connect();
|
await instance.connect();
|
||||||
|
const tmpFetcher = NostrFetcher.withCustomPool(ndkAdapter(instance));
|
||||||
|
|
||||||
// update account's metadata
|
// update account's metadata
|
||||||
if (db.account) {
|
if (db.account) {
|
||||||
const user = instance.getUser({ pubkey: db.account.pubkey });
|
const user = instance.getUser({ pubkey: db.account.pubkey });
|
||||||
if (user) {
|
db.account.contacts = [...(await user.follows())].map((user) => user.pubkey);
|
||||||
db.account.contacts = [...(await user.follows())].map((user) => user.pubkey);
|
db.account.relayList = await user.relayList();
|
||||||
db.account.relayList = await user.relayList();
|
|
||||||
}
|
// prefetch data
|
||||||
|
await queryClient.prefetchInfiniteQuery({
|
||||||
|
queryKey: ['newsfeed'],
|
||||||
|
initialPageParam: 0,
|
||||||
|
queryFn: async ({
|
||||||
|
signal,
|
||||||
|
pageParam,
|
||||||
|
}: {
|
||||||
|
signal: AbortSignal;
|
||||||
|
pageParam: number;
|
||||||
|
}) => {
|
||||||
|
const rootIds = new Set();
|
||||||
|
const dedupQueue = new Set();
|
||||||
|
|
||||||
|
const events = await tmpFetcher.fetchLatestEvents(
|
||||||
|
explicitRelayUrls,
|
||||||
|
{
|
||||||
|
kinds: [NDKKind.Text, NDKKind.Repost],
|
||||||
|
authors: db.account.contacts,
|
||||||
|
},
|
||||||
|
FETCH_LIMIT,
|
||||||
|
{ asOf: pageParam === 0 ? undefined : pageParam, abortSignal: signal }
|
||||||
|
);
|
||||||
|
|
||||||
|
const ndkEvents = events.map((event) => {
|
||||||
|
return new NDKEvent(ndk, event);
|
||||||
|
});
|
||||||
|
|
||||||
|
ndkEvents.forEach((event) => {
|
||||||
|
const tags = event.tags.filter((el) => el[0] === 'e');
|
||||||
|
if (tags && tags.length > 0) {
|
||||||
|
const rootId = tags.filter((el) => el[3] === 'root')[1] ?? tags[0][1];
|
||||||
|
if (rootIds.has(rootId)) return dedupQueue.add(event.id);
|
||||||
|
rootIds.add(rootId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return ndkEvents
|
||||||
|
.filter((event) => !dedupQueue.has(event.id))
|
||||||
|
.sort((a, b) => b.created_at - a.created_at);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await queryClient.prefetchInfiniteQuery({
|
||||||
|
queryKey: ['notification'],
|
||||||
|
initialPageParam: 0,
|
||||||
|
queryFn: async ({
|
||||||
|
signal,
|
||||||
|
pageParam,
|
||||||
|
}: {
|
||||||
|
signal: AbortSignal;
|
||||||
|
pageParam: number;
|
||||||
|
}) => {
|
||||||
|
const events = await tmpFetcher.fetchLatestEvents(
|
||||||
|
explicitRelayUrls,
|
||||||
|
{
|
||||||
|
kinds: [NDKKind.Text, NDKKind.Repost, NDKKind.Reaction, NDKKind.Zap],
|
||||||
|
'#p': [db.account.pubkey],
|
||||||
|
},
|
||||||
|
FETCH_LIMIT,
|
||||||
|
{ asOf: pageParam === 0 ? undefined : pageParam, abortSignal: signal }
|
||||||
|
);
|
||||||
|
|
||||||
|
const ndkEvents = events.map((event) => {
|
||||||
|
return new NDKEvent(ndk, event);
|
||||||
|
});
|
||||||
|
|
||||||
|
return ndkEvents.sort((a, b) => b.created_at - a.created_at);
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setNDK(instance);
|
setNDK(instance);
|
||||||
|
setFetcher(tmpFetcher);
|
||||||
setRelayUrls(explicitRelayUrls);
|
setRelayUrls(explicitRelayUrls);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const yes = await ask(
|
const yes = await ask(
|
||||||
@ -135,7 +168,7 @@ export const NDKInstance = () => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
ndk,
|
ndk,
|
||||||
relayUrls,
|
|
||||||
fetcher,
|
fetcher,
|
||||||
|
relayUrls,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
|
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
import { Toaster } from 'sonner';
|
import { Toaster } from 'sonner';
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ const root = createRoot(container);
|
|||||||
|
|
||||||
root.render(
|
root.render(
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
|
<ReactQueryDevtools initialIsOpen={false} />
|
||||||
<Toaster position="top-center" closeButton theme="system" />
|
<Toaster position="top-center" closeButton theme="system" />
|
||||||
<StorageProvider>
|
<StorageProvider>
|
||||||
<NDKProvider>
|
<NDKProvider>
|
||||||
|
Loading…
Reference in New Issue
Block a user