Retro Bulletin Board Systems on atproto. Web app and TUI. lazy mirror of alyraffauf/atbbs atbbs.xyz
forums python tui atproto bbs
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

web: persist cache with react-query-persist-client

+81 -3
+46
web/package-lock.json
··· 11 11 "@atcute/atproto": "^3.1.11", 12 12 "@atcute/client": "^4.2.1", 13 13 "@atcute/oauth-browser-client": "^3.0.0", 14 + "@tanstack/query-sync-storage-persister": "^5.100.1", 14 15 "@tanstack/react-query": "^5.100.1", 15 16 "@tanstack/react-query-devtools": "^5.100.1", 17 + "@tanstack/react-query-persist-client": "^5.100.1", 16 18 "lucide-react": "^1.8.0", 17 19 "react": "^19.2.5", 18 20 "react-dom": "^19.2.5", ··· 1358 1360 "url": "https://github.com/sponsors/tannerlinsley" 1359 1361 } 1360 1362 }, 1363 + "node_modules/@tanstack/query-persist-client-core": { 1364 + "version": "5.100.1", 1365 + "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.100.1.tgz", 1366 + "integrity": "sha512-zopD/OxWWjKUBmB8ydTzz9LBw/MGRz9vbdMV/DFxlMFTg9bP+QiBAMDgdWYpswhdjGlixbjml8mTD9HX4v1Uww==", 1367 + "license": "MIT", 1368 + "dependencies": { 1369 + "@tanstack/query-core": "5.100.1" 1370 + }, 1371 + "funding": { 1372 + "type": "github", 1373 + "url": "https://github.com/sponsors/tannerlinsley" 1374 + } 1375 + }, 1376 + "node_modules/@tanstack/query-sync-storage-persister": { 1377 + "version": "5.100.1", 1378 + "resolved": "https://registry.npmjs.org/@tanstack/query-sync-storage-persister/-/query-sync-storage-persister-5.100.1.tgz", 1379 + "integrity": "sha512-6lSgoZy+Vqgr0tQjQu4dL0af86bRi2mN94k4yMXVI1EFevY4gPYpKM/PIMbdE0qDVP/CqBALG2zaNTIJtgHj8g==", 1380 + "license": "MIT", 1381 + "dependencies": { 1382 + "@tanstack/query-core": "5.100.1", 1383 + "@tanstack/query-persist-client-core": "5.100.1" 1384 + }, 1385 + "funding": { 1386 + "type": "github", 1387 + "url": "https://github.com/sponsors/tannerlinsley" 1388 + } 1389 + }, 1361 1390 "node_modules/@tanstack/react-query": { 1362 1391 "version": "5.100.1", 1363 1392 "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.100.1.tgz", ··· 1381 1410 "license": "MIT", 1382 1411 "dependencies": { 1383 1412 "@tanstack/query-devtools": "5.100.1" 1413 + }, 1414 + "funding": { 1415 + "type": "github", 1416 + "url": "https://github.com/sponsors/tannerlinsley" 1417 + }, 1418 + "peerDependencies": { 1419 + "@tanstack/react-query": "^5.100.1", 1420 + "react": "^18 || ^19" 1421 + } 1422 + }, 1423 + "node_modules/@tanstack/react-query-persist-client": { 1424 + "version": "5.100.1", 1425 + "resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.100.1.tgz", 1426 + "integrity": "sha512-9APCLGDNoNkJmFFdQ5nvRrQMwZr2IjD3cpF8g+2WRs2QVehpRotxg5gzKgTFOaiRKBs8/FWbyiNjyZ7Vkp0aTg==", 1427 + "license": "MIT", 1428 + "dependencies": { 1429 + "@tanstack/query-persist-client-core": "5.100.1" 1384 1430 }, 1385 1431 "funding": { 1386 1432 "type": "github",
+2
web/package.json
··· 12 12 "@atcute/atproto": "^3.1.11", 13 13 "@atcute/client": "^4.2.1", 14 14 "@atcute/oauth-browser-client": "^3.0.0", 15 + "@tanstack/query-sync-storage-persister": "^5.100.1", 15 16 "@tanstack/react-query": "^5.100.1", 16 17 "@tanstack/react-query-devtools": "^5.100.1", 18 + "@tanstack/react-query-persist-client": "^5.100.1", 17 19 "lucide-react": "^1.8.0", 18 20 "react": "^19.2.5", 19 21 "react-dom": "^19.2.5",
+26
web/src/lib/queryPersister.ts
··· 1 + import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister"; 2 + 3 + // Bump when cache shapes change (lexicon edits, query-key restructures) so 4 + // older clients discard incompatible cached data on next load instead of 5 + // deserializing into crashes. 6 + const BUSTER = "atbbs-v1"; 7 + const MAX_AGE = 24 * 60 * 60 * 1000; 8 + 9 + const persister = createSyncStoragePersister({ 10 + storage: localStorage, 11 + key: "atbbs:query-cache", 12 + }); 13 + 14 + export const persistOptions = { 15 + persister, 16 + buster: BUSTER, 17 + maxAge: MAX_AGE, 18 + dehydrateOptions: { 19 + // Skip fingerprinted thread-page entries. Their keys churn whenever a 20 + // reply is added or deleted, so persisting them just bloats localStorage 21 + // with old-fingerprint garbage. thread-refs is persisted and drives the 22 + // page rebuild on load. 23 + shouldDehydrateQuery: (query: { queryKey: readonly unknown[] }) => 24 + query.queryKey[0] !== "thread-page", 25 + }, 26 + };
+7 -3
web/src/main.tsx
··· 1 1 import { StrictMode } from "react"; 2 2 import { createRoot } from "react-dom/client"; 3 3 import { RouterProvider } from "react-router-dom"; 4 - import { QueryClientProvider } from "@tanstack/react-query"; 4 + import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client"; 5 5 import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; 6 6 import { queryClient } from "./lib/queryClient"; 7 + import { persistOptions } from "./lib/queryPersister"; 7 8 import { router } from "./router/routes"; 8 9 import { BreadcrumbProvider } from "./hooks/useBreadcrumb"; 9 10 import "./index.css"; ··· 14 15 15 16 createRoot(document.getElementById("root")!).render( 16 17 <StrictMode> 17 - <QueryClientProvider client={queryClient}> 18 + <PersistQueryClientProvider 19 + client={queryClient} 20 + persistOptions={persistOptions} 21 + > 18 22 <BreadcrumbProvider> 19 23 <RouterProvider router={router} /> 20 24 </BreadcrumbProvider> 21 25 {import.meta.env.DEV && ( 22 26 <ReactQueryDevtools buttonPosition="bottom-left" /> 23 27 )} 24 - </QueryClientProvider> 28 + </PersistQueryClientProvider> 25 29 </StrictMode>, 26 30 );