refactor(offline-sync): share query keys/options between hooks and offline warm
The 'Make available offline' warm path re-typed React Query key literals and
re-declared queryKey+queryFn pairs that the feature hooks already owned, so the
two could silently drift (a hook key change would leave the warm cache under a
stale key). Centralize them so there is one source:
- Add pageKeys (page-query.ts) and spaceKeys (space-query.ts) key factories and
route the inline key literals through them. Partial-match keys and 2-element
spaceMembers invalidations are deliberately left inline so their effective key
VALUE (and invalidation breadth) is unchanged.
- Add queryOptions factories sidebarPagesQueryOptions and spaceByIdQueryOptions,
consumed by both the hooks (fetchAllAncestorChildren, useGetSpaceBySlugQuery)
and the warm path. Comments reuse the existing RQ_KEY factory.
The warm path also stops silently succeeding: warmInfiniteAll returns a boolean
and logs failures; makePageAvailableOffline is best-effort (never throws) and
returns { ok, failed[] }, recording each failed step by label; the tree menu
caller now shows a success or error toast from result.ok. Removed the unused
slugId/parentPageId params from the offline params type.
This is a behavior-preserving centralization: effective query keys, queryFns,
staleTime and enabled are unchanged for every hook.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -84,18 +84,29 @@ export function NodeMenu({ node, canEdit }: NodeMenuProps) {
|
||||
const handleMakeAvailableOffline = async () => {
|
||||
notifications.show({ message: t("Saving page for offline use...") });
|
||||
try {
|
||||
// Prefetch read queries so they get persisted to IndexedDB.
|
||||
await makePageAvailableOffline({
|
||||
// Prefetch read queries so they get persisted to IndexedDB. The result
|
||||
// reports whether every warm step succeeded.
|
||||
const result = await makePageAvailableOffline({
|
||||
pageId: node.id,
|
||||
slugId: node.slugId,
|
||||
spaceId: node.spaceId,
|
||||
parentPageId: node.parentPageId,
|
||||
});
|
||||
// Best-effort: warm the page's Yjs document into IndexedDB.
|
||||
await warmPageYdoc(node.id, getCollaborationUrl(), collabQuery?.token);
|
||||
notifications.show({ message: t("Page is now available offline") });
|
||||
|
||||
if (result.ok) {
|
||||
notifications.show({ message: t("Page is now available offline") });
|
||||
} else {
|
||||
// Partial warm — the page may still be partly usable offline, but some
|
||||
// queries failed to cache, so surface it as an error rather than a
|
||||
// silent success.
|
||||
notifications.show({
|
||||
message: t("Failed to make page available offline"),
|
||||
color: "red",
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// makePageAvailableOffline / warmPageYdoc never throw, but stay safe.
|
||||
// makePageAvailableOffline no longer throws, but warmPageYdoc and other
|
||||
// unexpected failures stay guarded here.
|
||||
notifications.show({
|
||||
message: t("Failed to make page available offline"),
|
||||
color: "red",
|
||||
|
||||
Reference in New Issue
Block a user