Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
}
},
"scripts": {
"docs:generate": "tsdoc --src=src/contexts/*,src/hooks/*,src/lib/types.ts --dest=docs/API.md --noemoji --types",
"docs:generate": "tsdoc --src=src/contexts/*,src/hooks/*,src/lib/types.ts,src/lib/react-query/prefetch.ts --dest=docs/API.md --noemoji --types",
"lint:eslint": "eslint --cache .",
"lint:format": "prettier --cache --check .",
"lint": "npm-run-all --parallel --continue-on-error --print-label --aggregate-output lint:*",
Expand Down
8 changes: 8 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,11 @@ export {
type WriteableDocumentType,
type WriteableValue,
} from './lib/types.js'
export {
prefetchProjects,
prefetchProjectApi,
prefetchProjectSettings,
prefetchOwnRoleInProject,
prefetchMembers,
prefetchIsArchiveDevice,
} from './lib/react-query/prefetch.js'
164 changes: 164 additions & 0 deletions src/lib/react-query/prefetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import type { MapeoClientApi, MapeoProjectApi } from '@comapeo/ipc'
import type { QueryClient } from '@tanstack/react-query'

import { isArchiveDeviceQueryOptions } from './client.js'
import {
projectByIdQueryOptions,
projectMembersQueryOptions,
projectOwnRoleQueryOptions,
projectSettingsQueryOptions,
projectsQueryOptions,
} from './projects.js'

/**
* Prefetch project list into the React Query cache.
*
* @param queryClient React Query client instance
* @param clientApi CoMapeo Client API instance
*
* @example
* ```tsx
*
* function MenuScreen() {
* const queryClient = useQueryClient()
* const clientApi = useClientApi()
*
* useFocusEffect(
* React.useCallback(() => {
* prefetchProjects(queryClient, clientApi)
* }, [queryClient, clientApi])
* )
*
* return <UI />
* }
* ```
*/
export async function prefetchProjects(
queryClient: QueryClient,
clientApi: MapeoClientApi,
): Promise<void> {
const opts = projectsQueryOptions({ clientApi })
await queryClient.prefetchQuery({ ...opts, staleTime: Infinity })
}

/**
* Ensure the project API instance is cached and available.
*
* Returns the project API handle if available.
*
* @param queryClient React Query client instance
* @param clientApi CoMapeo Client API instance
* @param projectId Project public ID
*
* @example
* ```tsx
* const projectApi = await prefetchProjectApi(queryClient, clientApi, projectId)
* if (!projectApi) {
* // Project not found or failed to load; handle gracefully
* }
* ```
*/
export async function prefetchProjectApi(
queryClient: QueryClient,
clientApi: MapeoClientApi,
projectId: string,
): Promise<MapeoProjectApi | undefined> {
try {
const opts = projectByIdQueryOptions({ clientApi, projectId })
const api = await queryClient.ensureQueryData({
...opts,
staleTime: Infinity,
})
return api
} catch {
return undefined
}
}

/**
* Prefetch project settings for a project.
*
* @param queryClient React Query client instance
* @param clientApi CoMapeo Client API instance
* @param projectId Project public ID
*
* @example
* ```tsx
* await prefetchProjectSettings(queryClient, clientApi, projectId)
* ```
*/
export async function prefetchProjectSettings(
queryClient: QueryClient,
clientApi: MapeoClientApi,
projectId: string,
): Promise<void> {
const projectApi = await prefetchProjectApi(queryClient, clientApi, projectId)
if (!projectApi) return
const opts = projectSettingsQueryOptions({ projectApi, projectId })
await queryClient.prefetchQuery({ ...opts, staleTime: Infinity })
}

/**
* Prefetch the current device's role in a project.
*
* @param queryClient React Query client instance
* @param clientApi CoMapeo Client API instance
* @param projectId Project public ID
*
* @example
* ```tsx
* await prefetchOwnRoleInProject(queryClient, clientApi, projectId)
* ```
*/
export async function prefetchOwnRoleInProject(
queryClient: QueryClient,
clientApi: MapeoClientApi,
projectId: string,
): Promise<void> {
const projectApi = await prefetchProjectApi(queryClient, clientApi, projectId)
if (!projectApi) return
const opts = projectOwnRoleQueryOptions({ projectApi, projectId })
await queryClient.prefetchQuery({ ...opts, staleTime: Infinity })
}

/**
* Prefetch all members for a project.
*
* @param queryClient React Query client instance
* @param clientApi CoMapeo Client API instance
* @param projectId Project public ID
*
* @example
* ```tsx
* await prefetchMembers(queryClient, clientApi, projectId)
* ```
*/
export async function prefetchMembers(
queryClient: QueryClient,
clientApi: MapeoClientApi,
projectId: string,
): Promise<void> {
const projectApi = await prefetchProjectApi(queryClient, clientApi, projectId)
if (!projectApi) return
const opts = projectMembersQueryOptions({ projectApi, projectId })
await queryClient.prefetchQuery({ ...opts, staleTime: Infinity })
}

/**
* Prefetch whether the current device is an archive device.
*
* @param queryClient React Query client instance
* @param clientApi CoMapeo Client API instance
*
* @example
* ```tsx
* await prefetchIsArchiveDevice(queryClient, clientApi)
* ```
*/
export async function prefetchIsArchiveDevice(
queryClient: QueryClient,
clientApi: MapeoClientApi,
): Promise<void> {
const opts = isArchiveDeviceQueryOptions({ clientApi })
await queryClient.prefetchQuery({ ...opts, staleTime: Infinity })
}