diff --git a/apps/dashboard/src/lib/prefetch/url-prefetcher.tsx b/apps/dashboard/src/lib/prefetch/url-prefetcher.tsx index 3cb32a877..311ac690b 100644 --- a/apps/dashboard/src/lib/prefetch/url-prefetcher.tsx +++ b/apps/dashboard/src/lib/prefetch/url-prefetcher.tsx @@ -81,7 +81,7 @@ const urlPrefetchers: Record { - useAdminApp(projectId).useTeams(); + useAdminApp(projectId).useTeams({ limit: 1 }); }, ], "/projects/*/teams/*": [ @@ -213,16 +213,6 @@ const urlPrefetchers: Record { useDashboardInternalUser(); }, - ([_, projectId]) => { - const project = useAdminApp(projectId).useProject(); - const teams = useDashboardInternalUser().useTeams(); - const ownerTeam = teams.find((team) => team.id === project.ownerTeamId); - if (ownerTeam) { - return [() => { - ownerTeam.useUsers(); - }]; - } - }, ], "/projects/*/payments/**": [ ([_, projectId]) => { diff --git a/packages/template/src/lib/hexclave-app/apps/implementations/server-app-impl.ts b/packages/template/src/lib/hexclave-app/apps/implementations/server-app-impl.ts index 1594e4dcc..7b6c64fef 100644 --- a/packages/template/src/lib/hexclave-app/apps/implementations/server-app-impl.ts +++ b/packages/template/src/lib/hexclave-app/apps/implementations/server-app-impl.ts @@ -86,6 +86,16 @@ export class _HexclaveServerAppImplIncomplete(async ([userId, orderBy, desc, cursor, limit, query]) => { return await this._interface.listServerTeamsPaginated({ userId, orderBy, desc, cursor, limit, query }); }); + private readonly _serverTeamCache = createCache(async ([teamId]) => { + try { + return await this._interface.getServerTeam(teamId); + } catch (error) { + if (KnownErrors.TeamNotFound.isInstance(error)) { + return null; + } + throw error; + } + }); protected async _refreshTeamMembership(teamId: string, userId: string) { await Promise.all([ @@ -709,15 +719,15 @@ export class _HexclaveServerAppImplIncomplete t.id === teamId) ?? null; + const team = Result.orThrow(await app._serverTeamCache.getOrWait([teamId], "write-only")); + return team == null ? null : app._serverTeamFromCrud(team); }, // IF_PLATFORM react-like useTeam(teamId: string) { - const teams = this.useTeams(); + const team = useAsyncCache(app._serverTeamCache, [teamId], "user.useTeam()"); return useMemo(() => { - return teams.find((t) => t.id === teamId) ?? null; - }, [teams, teamId]); + return team == null ? null : app._serverTeamFromCrud(team); + }, [team]); }, // END_PLATFORM async listTeams(options?: ServerListTeamsOptions): Promise { @@ -1038,6 +1048,7 @@ export class _HexclaveServerAppImplIncomplete) { await app._interface.updateServerTeam(crud.id, serverTeamUpdateOptionsToCrud(update)); await Promise.all([ + app._serverTeamCache.refresh([crud.id]), app._serverTeamsCache.refreshWhere(() => true), app._serverUsersCache.refreshWhere(() => true), ]); @@ -1045,6 +1056,7 @@ export class _HexclaveServerAppImplIncomplete true), app._serverUsersCache.refreshWhere(() => true), ]); @@ -1543,6 +1555,7 @@ export class _HexclaveServerAppImplIncomplete { const team = await this._interface.createServerTeam(serverTeamCreateOptionsToCrud(data)); + await this._serverTeamCache.refresh([team.id]); await this._serverTeamsCache.refreshWhere(() => true); return this._serverTeamFromCrud(team); } @@ -1586,8 +1599,11 @@ export class _HexclaveServerAppImplIncomplete t.id === teamId) ?? null; + if (teamId == null) { + return null; + } + const team = Result.orThrow(await this._serverTeamCache.getOrWait([teamId], "write-only")); + return team == null ? null : this._serverTeamFromCrud(team); } } @@ -1599,10 +1615,13 @@ export class _HexclaveServerAppImplIncomplete { - return teams.find((t) => t.id === teamId) ?? null; - }, [teams, teamId]); + return team == null ? null : this._serverTeamFromCrud(team); + }, [team]); } } // END_PLATFORM diff --git a/sdks/spec/src/types/users/server-user.spec.md b/sdks/spec/src/types/users/server-user.spec.md index 6af5029ef..129465797 100644 --- a/sdks/spec/src/types/users/server-user.spec.md +++ b/sdks/spec/src/types/users/server-user.spec.md @@ -113,7 +113,9 @@ teamId: string Returns: ServerTeam | null -Find in listTeams() by id. +GET /api/v1/teams/{teamId} [server-only] + +Returns the team with the requested ID, or null if it does not exist. Does not error.