diff --git a/packages/web/src/api/client.ts b/packages/web/src/api/client.ts index db5701a9..dd651824 100644 --- a/packages/web/src/api/client.ts +++ b/packages/web/src/api/client.ts @@ -813,9 +813,3 @@ export function createApiClient(origin: string, getToken: () => string | null, o return new BackspaceApiClient(baseUrl, getToken, onUnauthorized); } -// Re-export the cross-store origin resolver so consumers can do -// `import { getApiForOrigin } from '../api/client'`. The real implementation -// lives in `utils/crossStoreResolvers` to avoid TDZ cycles between stores; -// re-exporting here keeps the public import surface clean for callers that -// don't need to know about the internal indirection. -export { getApiForOrigin } from '../utils/crossStoreResolvers'; diff --git a/packages/web/src/components/chat/SpaceInviteCard.test.tsx b/packages/web/src/components/chat/SpaceInviteCard.test.tsx index 014869f3..7ca65b0a 100644 --- a/packages/web/src/components/chat/SpaceInviteCard.test.tsx +++ b/packages/web/src/components/chat/SpaceInviteCard.test.tsx @@ -3,17 +3,19 @@ import { render, screen, waitFor } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; import { SpaceInviteCard } from './SpaceInviteCard'; -const mockJoinByCode = vi.fn(); +const { mockJoinByCode, mockGetApiForOrigin } = vi.hoisted(() => ({ + mockJoinByCode: vi.fn(), + mockGetApiForOrigin: vi.fn(() => ({ + spaces: { invitePreview: vi.fn() }, + })), +})); vi.mock('../../stores/spaceStore', () => ({ useSpaceStore: (selector: any) => selector({ joinByCode: mockJoinByCode }), + getApiForOrigin: mockGetApiForOrigin, })); vi.mock('../../api/client', () => ({ createApiClient: vi.fn(), - getApiForOrigin: vi.fn(() => ({ - spaces: { invitePreview:vi.fn() }, - })), })); -import { getApiForOrigin } from '../../api/client'; const basePayload = { event: 'space_invite' as const, @@ -38,7 +40,7 @@ describe('SpaceInviteCard', () => { }); it('renders snapshot fields immediately on mount (snapshot-only state)', () => { - (getApiForOrigin as any).mockReturnValue({ + mockGetApiForOrigin.mockReturnValue({ spaces: { invitePreview:() => new Promise(() => {}) }, // never resolves }); render(); @@ -48,7 +50,7 @@ describe('SpaceInviteCard', () => { }); it('refreshes member count when live preview resolves (live-confirmed state)', async () => { - (getApiForOrigin as any).mockReturnValue({ + mockGetApiForOrigin.mockReturnValue({ spaces: { invitePreview:vi.fn().mockResolvedValue({ ...basePayload.snapshot, spaceId: 'S1', memberCount: 99 }) }, }); render(); @@ -56,7 +58,7 @@ describe('SpaceInviteCard', () => { }); it('shows revoked state when preview rejects (revoked state)', async () => { - (getApiForOrigin as any).mockReturnValue({ + mockGetApiForOrigin.mockReturnValue({ spaces: { invitePreview:vi.fn().mockRejectedValue(new Error('not found')) }, }); render(); @@ -75,7 +77,7 @@ describe('SpaceInviteCard', () => { const userEvent = (await import('@testing-library/user-event')).default; const user = userEvent.setup(); - (getApiForOrigin as any).mockReturnValue({ + mockGetApiForOrigin.mockReturnValue({ spaces: { invitePreview:vi.fn().mockResolvedValue({ ...basePayload.snapshot, spaceId: 'S1' }) }, }); diff --git a/packages/web/src/components/chat/SpaceInviteCard.tsx b/packages/web/src/components/chat/SpaceInviteCard.tsx index 56dcebd8..67ee64d4 100644 --- a/packages/web/src/components/chat/SpaceInviteCard.tsx +++ b/packages/web/src/components/chat/SpaceInviteCard.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Avatar } from '../ui/Avatar'; -import { getApiForOrigin } from '../../api/client'; +import { getApiForOrigin } from '../../stores/spaceStore'; import { useSpaceStore } from '../../stores/spaceStore'; import type { SpaceInviteSystemPayload } from '@backspace/shared'; @@ -62,8 +62,8 @@ export function SpaceInviteCard({ payload, senderName }: Props) { }; return ( -
-
+
+
{senderName} sent an invite