Skip to content

Commit

Permalink
Chat local storage persister (#52)
Browse files Browse the repository at this point in the history
* Added persistence to the localStorage;

* Updated chat-message stale time; Updated chat storage key to be specific;

* Better verifyToken gcTime;
  • Loading branch information
stef-coenen authored Jan 9, 2024
1 parent 57d58ab commit 4ffe721
Show file tree
Hide file tree
Showing 13 changed files with 101 additions and 23 deletions.
57 changes: 50 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion packages/chat-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
"UNSUPPORTED_dotyoucore_build": "rm -rf ../../../dotyoucore/services/Youverse.Hosting/client/chat-app && VITE_VERSION=$(date +%s) vite build --outDir ../../../dotyoucore/services/Youverse.Hosting/client/chat-app/"
},
"dependencies": {
"@tanstack/query-sync-storage-persister": "^5.17.9",
"@tanstack/react-query": "^5.4.3",
"@tanstack/react-query-persist-client": "^5.17.9",
"@tanstack/react-virtual": "^3.0.0-beta.68",
"@youfoundation/common-app": "*",
"@youfoundation/js-lib": "*",
"@youfoundation/ui-lib": "*",
"@youfoundation/rich-text-editor": "*",
"@youfoundation/ui-lib": "*",
"axios": "1.5.1",
"emoji-picker-element": "^1.15.1",
"lodash-es": "^4.17.21",
Expand Down
39 changes: 35 additions & 4 deletions packages/chat-app/src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import {
} from 'react-router-dom';

import { Helmet, HelmetProvider } from 'react-helmet-async';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { QueryClient } from '@tanstack/react-query';
import {
PersistQueryClientOptions,
PersistQueryClientProvider,
removeOldestQuery,
} from '@tanstack/react-query-persist-client';
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister';

import { MinimalLayout, NoLayout } from '../components/ui/Layout/Layout';

Expand All @@ -29,7 +35,32 @@ const AUTH_PATH = ROOT_PATH + '/auth';

import { ErrorBoundary, NotFound } from '@youfoundation/common-app';

const queryClient = new QueryClient();
const queryClient = new QueryClient({
defaultOptions: {
queries: {
gcTime: 1000 * 60 * 60 * 24, // 24 hours
},
},
});

const localStoragePersister = createSyncStoragePersister({
storage: window.localStorage,
retry: removeOldestQuery,
key: 'CHAT_REACT_QUERY_OFFLINE_CACHE',
});

// Explicit includes to avoid persisting media items, or large data in general
const INCLUDED_QUERY_KEYS = ['chat-message', 'chat', 'conversation', 'conversations'];
const persistOptions: Omit<PersistQueryClientOptions, 'queryClient'> = {
maxAge: Infinity,
persister: localStoragePersister,
dehydrateOptions: {
shouldDehydrateQuery: (query) => {
const { queryKey } = query;
return INCLUDED_QUERY_KEYS.some((key) => queryKey.includes(key));
},
},
};

function App() {
const router = createBrowserRouter(
Expand Down Expand Up @@ -87,9 +118,9 @@ function App() {
<Helmet>
<meta name="v" content={import.meta.env.VITE_VERSION} />
</Helmet>
<QueryClientProvider client={queryClient}>
<PersistQueryClientProvider client={queryClient} persistOptions={persistOptions}>
<RouterProvider router={router} fallbackElement={<></>} />
</QueryClientProvider>
</PersistQueryClientProvider>
</HelmetProvider>
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/chat-app/src/hooks/auth/useVerifyToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ export const useVerifyToken = (dotYouClient: DotYouClient) => {
queryFn: fetchData,
refetchOnMount: false,
staleTime: MINUTE_IN_MS * 10,
gcTime: MINUTE_IN_MS * 10,
});
};
6 changes: 3 additions & 3 deletions packages/chat-app/src/hooks/chat/useChatMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ export const useChatMessages = (props?: { conversationId: string | undefined })
const dotYouClient = useDotYouClient().getDotYouClient();
const queryClient = useQueryClient();

const fetchMessages = async (conversationId: string, cursorState: string | undefined) => {
return await getChatMessages(dotYouClient, conversationId, cursorState, PAGE_SIZE);
};
const fetchMessages = async (conversationId: string, cursorState: string | undefined) =>
await getChatMessages(dotYouClient, conversationId, cursorState, PAGE_SIZE);

const markAsRead = async ({
conversation,
Expand Down Expand Up @@ -78,6 +77,7 @@ export const useChatMessages = (props?: { conversationId: string | undefined })
getNextPageParam: (lastPage) =>
lastPage.searchResults?.length >= PAGE_SIZE ? lastPage.cursorState : undefined,
enabled: !!conversationId,
staleTime: 1000 * 60 * 5, // 5 minutes; The chat messages are already invalidated by the websocket
refetchOnMount: false,
refetchOnWindowFocus: false,
}),
Expand Down
2 changes: 1 addition & 1 deletion packages/common-app/src/hooks/posts/useBlog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const useBlog = ({ channelSlug, channelId, blogSlug }: useBlogProps = {})
queryFn: () => fetchBlog({ blogSlug }),
refetchOnMount: false,
enabled: channelFetched && !!blogSlug,
gcTime: 10 * 60 * 1000,
gcTime: isOwner ? 0 : 10 * 60 * 1000,
staleTime: isOwner ? 0 : 10 * 60 * 1000,
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export const useEmojiReactions = (context?: ReactionContext) => {
initialPageParam: undefined as string | undefined,
queryFn: ({ pageParam }) => fetch({ context, pageParam }),
staleTime: 1000 * 60 * 1, // 1 minute
gcTime: Infinity,
getNextPageParam: (lastPage) =>
lastPage && lastPage.reactions?.length >= PAGE_SIZE ? lastPage.cursor : undefined,
refetchOnMount: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ export const useEmojiSummary = ({
queryFn: () => fetch(context),
refetchOnMount: false,
refetchOnWindowFocus: false,
staleTime: 1000 * 30, // 30 seconds
staleTime: 1000 * 30, // 30 seconds => Just for the initial render
gcTime: Infinity,
initialData: reactionPreview,
// By default, initialData is treated as totally fresh, as if it were just fetched. This also means that it will affect how it is interpreted by the staleTime option.
enabled:
!!context.authorOdinId &&
!!context.channelId &&
Expand Down
1 change: 1 addition & 0 deletions packages/feed-app/src/hooks/auth/useVerifyToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ export const useVerifyToken = (dotYouClient: DotYouClient) => {
queryFn: fetchData,
refetchOnMount: false,
staleTime: MINUTE_IN_MS * 10,
gcTime: MINUTE_IN_MS * 10,
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const useFetchIsManagedDomainAvailable = (prefix: string, apex: string) =
fetchIsManagedDomainAvailable: useQuery<boolean, AxiosError>({
queryKey: ['is-managed-domain-available', apex, prefix],
queryFn: () => fetchIsManagedDomainAvailable(prefix, apex),
gcTime: 0,
gcTime: 0, // Immediately garbage collect this query so it's always fresh
enabled: true,
refetchOnWindowFocus: true, // Refetch as the available status may have changed on the server
retry: false,
Expand Down
4 changes: 2 additions & 2 deletions packages/provisioning-app/src/hooks/ownDomain/useOwnDomain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export const useApexDomain = (domain?: string) => {
queryFn: () => getApexDomain(domain),
retry: false,
enabled: !!domain,
gcTime: Infinity,
staleTime: Infinity,
gcTime: 1000 * 60 * 60 * 24, // 24 hours => Very unlikely to change
staleTime: 1000 * 60 * 60 * 24, // 24 hours => Very unlikely to change
});
};
2 changes: 1 addition & 1 deletion packages/ui-lib/src/hooks/image/useImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export const useImage = (
refetchOnMount: true,
refetchOnWindowFocus: false,
staleTime: 1000 * 60, // 1 min
gcTime: Infinity,
gcTime: 1000 * 60 * 60 * 24, // 24 hours
enabled: !!imageFileId && imageFileId !== '',
}),
};
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-lib/src/hooks/image/useTinyThumb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export const useTinyThumb = (
refetchOnMount: false,
refetchOnWindowFocus: false,
staleTime: 1000 * 60 * 10, // 10min
gcTime: Infinity,
gcTime: 1000 * 60 * 60 * 24, // 24 hours
enabled: !!imageFileId && imageFileId !== '' && !!imageFileKey && imageFileKey !== '',
});
};

0 comments on commit 4ffe721

Please sign in to comment.