@sanity/sdk-react 0.0.0-rc.6 → 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +5 -57
  2. package/dist/index.d.ts +1000 -438
  3. package/dist/index.js +324 -258
  4. package/dist/index.js.map +1 -1
  5. package/package.json +17 -16
  6. package/src/_exports/sdk-react.ts +4 -1
  7. package/src/components/SDKProvider.tsx +6 -1
  8. package/src/components/SanityApp.test.tsx +29 -47
  9. package/src/components/SanityApp.tsx +12 -11
  10. package/src/components/auth/AuthBoundary.test.tsx +177 -7
  11. package/src/components/auth/AuthBoundary.tsx +32 -2
  12. package/src/components/auth/ConfigurationError.ts +22 -0
  13. package/src/components/auth/LoginError.tsx +9 -3
  14. package/src/hooks/auth/useVerifyOrgProjects.test.tsx +136 -0
  15. package/src/hooks/auth/useVerifyOrgProjects.tsx +48 -0
  16. package/src/hooks/client/useClient.ts +3 -3
  17. package/src/hooks/comlink/useManageFavorite.test.ts +276 -27
  18. package/src/hooks/comlink/useManageFavorite.ts +102 -51
  19. package/src/hooks/comlink/useWindowConnection.ts +3 -2
  20. package/src/hooks/document/useApplyDocumentActions.ts +105 -31
  21. package/src/hooks/document/useDocument.test.ts +41 -4
  22. package/src/hooks/document/useDocument.ts +198 -114
  23. package/src/hooks/document/useDocumentEvent.test.ts +5 -5
  24. package/src/hooks/document/useDocumentEvent.ts +67 -23
  25. package/src/hooks/document/useDocumentPermissions.ts +47 -8
  26. package/src/hooks/document/useDocumentSyncStatus.test.ts +12 -5
  27. package/src/hooks/document/useDocumentSyncStatus.ts +41 -14
  28. package/src/hooks/document/useEditDocument.test.ts +24 -6
  29. package/src/hooks/document/useEditDocument.ts +238 -133
  30. package/src/hooks/documents/useDocuments.test.tsx +1 -1
  31. package/src/hooks/documents/useDocuments.ts +153 -44
  32. package/src/hooks/paginatedDocuments/usePaginatedDocuments.test.tsx +1 -1
  33. package/src/hooks/paginatedDocuments/usePaginatedDocuments.ts +120 -47
  34. package/src/hooks/projection/useProjection.ts +134 -46
  35. package/src/hooks/query/useQuery.test.tsx +4 -4
  36. package/src/hooks/query/useQuery.ts +115 -43
  37. package/src/hooks/releases/useActiveReleases.test.tsx +84 -0
  38. package/src/hooks/releases/useActiveReleases.ts +39 -0
  39. package/src/hooks/releases/usePerspective.test.tsx +120 -0
  40. package/src/hooks/releases/usePerspective.ts +50 -0
@@ -0,0 +1,120 @@
1
+ import {type ClientPerspective} from '@sanity/client'
2
+ import {
3
+ getActiveReleasesState,
4
+ getPerspectiveState,
5
+ type PerspectiveHandle,
6
+ type ReleaseDocument,
7
+ type SanityInstance,
8
+ } from '@sanity/sdk'
9
+ import {renderHook} from '@testing-library/react'
10
+ import {BehaviorSubject} from 'rxjs'
11
+ import {describe, expect, it, vi} from 'vitest'
12
+
13
+ import {useSanityInstance} from '../context/useSanityInstance'
14
+ import {usePerspective} from './usePerspective'
15
+
16
+ // Mock the useSanityInstance hook
17
+ vi.mock('../context/useSanityInstance', () => ({
18
+ useSanityInstance: vi.fn(),
19
+ }))
20
+
21
+ // Mock the SDK functions
22
+ vi.mock('@sanity/sdk', async () => {
23
+ const actual = await vi.importActual('@sanity/sdk')
24
+ return {
25
+ ...actual,
26
+ getPerspectiveState: vi.fn(),
27
+ // getPerspectiveState uses getActiveReleasesState
28
+ // to determine if it should suspend
29
+ getActiveReleasesState: vi.fn(),
30
+ }
31
+ })
32
+
33
+ describe('usePerspective', () => {
34
+ beforeEach(() => {
35
+ vi.clearAllMocks()
36
+ })
37
+
38
+ it('should suspend when initial state is undefined', () => {
39
+ const mockInstance = {} as SanityInstance
40
+ vi.mocked(useSanityInstance).mockReturnValue(mockInstance)
41
+
42
+ const perspectiveHandle: PerspectiveHandle = {
43
+ perspective: 'published',
44
+ }
45
+
46
+ const mockSubject = new BehaviorSubject<ClientPerspective | undefined>(undefined)
47
+ const mockStateSource = {
48
+ subscribe: vi.fn((callback) => {
49
+ const subscription = mockSubject.subscribe(callback)
50
+ return () => subscription.unsubscribe()
51
+ }),
52
+ getCurrent: vi.fn(() => undefined),
53
+ observable: mockSubject,
54
+ }
55
+
56
+ // Mock the active releases observable for the suspender
57
+ const mockReleaseDoc: ReleaseDocument = {
58
+ _id: 'release1',
59
+ _type: 'release',
60
+ _createdAt: '2021-01-01T00:00:00Z',
61
+ _updatedAt: '2021-01-01T00:00:00Z',
62
+ _rev: 'rev1',
63
+ name: 'Test Release',
64
+ metadata: {
65
+ title: 'Test Release',
66
+ releaseType: 'asap',
67
+ },
68
+ }
69
+ const mockReleasesSubject = new BehaviorSubject([mockReleaseDoc])
70
+ const mockReleasesStateSource = {
71
+ subscribe: vi.fn(),
72
+ getCurrent: vi.fn(),
73
+ observable: mockReleasesSubject,
74
+ }
75
+
76
+ vi.mocked(getPerspectiveState).mockReturnValue(mockStateSource)
77
+ vi.mocked(getActiveReleasesState).mockReturnValue(mockReleasesStateSource)
78
+
79
+ const {result} = renderHook(() => {
80
+ try {
81
+ return usePerspective(perspectiveHandle)
82
+ } catch (e) {
83
+ return e
84
+ }
85
+ })
86
+
87
+ // Verify that the hook threw a promise (suspended)
88
+ expect(result.current).toBeInstanceOf(Promise)
89
+ expect(mockStateSource.getCurrent).toHaveBeenCalled()
90
+ })
91
+
92
+ it('should resolve with perspective when data is available', () => {
93
+ const mockInstance = {} as SanityInstance
94
+ vi.mocked(useSanityInstance).mockReturnValue(mockInstance)
95
+
96
+ const perspectiveHandle: PerspectiveHandle = {
97
+ perspective: 'published',
98
+ }
99
+
100
+ const mockPerspective: ClientPerspective = 'published'
101
+ const mockSubject = new BehaviorSubject<ClientPerspective>(mockPerspective)
102
+ const mockStateSource = {
103
+ subscribe: vi.fn((callback) => {
104
+ const subscription = mockSubject.subscribe(callback)
105
+ return () => subscription.unsubscribe()
106
+ }),
107
+ getCurrent: vi.fn(() => mockPerspective),
108
+ observable: mockSubject,
109
+ }
110
+
111
+ vi.mocked(getPerspectiveState).mockReturnValue(mockStateSource)
112
+
113
+ const {result} = renderHook(() => usePerspective(perspectiveHandle))
114
+
115
+ // Verify that the hook returned the perspective without suspending
116
+ expect(result.current).toEqual(mockPerspective)
117
+ expect(mockStateSource.getCurrent).toHaveBeenCalled()
118
+ expect(getPerspectiveState).toHaveBeenCalledWith(mockInstance, perspectiveHandle)
119
+ })
120
+ })
@@ -0,0 +1,50 @@
1
+ import {
2
+ getActiveReleasesState,
3
+ getPerspectiveState,
4
+ type PerspectiveHandle,
5
+ type SanityInstance,
6
+ type StateSource,
7
+ } from '@sanity/sdk'
8
+ import {filter, firstValueFrom} from 'rxjs'
9
+
10
+ import {createStateSourceHook} from '../helpers/createStateSourceHook'
11
+
12
+ /**
13
+ * @public
14
+ */
15
+ type UsePerspective = {
16
+ (perspectiveHandle: PerspectiveHandle): string | string[]
17
+ }
18
+
19
+ /**
20
+ * @public
21
+ * @function
22
+ *
23
+ * Returns a single or stack of perspectives for the given perspective handle,
24
+ * which can then be used to correctly query the documents
25
+ * via the `perspective` parameter in the client.
26
+ *
27
+ * @param perspectiveHandle - The perspective handle to get the perspective for.
28
+ * @category Documents
29
+ * @example
30
+ * ```tsx
31
+ * import {usePerspective, useQuery} from '@sanity/sdk-react'
32
+
33
+ * const perspective = usePerspective({perspective: 'rxg1346', projectId: 'abc123', dataset: 'production'})
34
+ * const {data} = useQuery<Movie[]>('*[_type == "movie"]', {
35
+ * perspective: perspective,
36
+ * })
37
+ * ```
38
+ *
39
+ * @returns The perspective for the given perspective handle.
40
+ */
41
+ export const usePerspective: UsePerspective = createStateSourceHook({
42
+ getState: getPerspectiveState as (
43
+ instance: SanityInstance,
44
+ perspectiveHandle?: PerspectiveHandle,
45
+ ) => StateSource<string | string[]>,
46
+ shouldSuspend: (instance: SanityInstance, options?: PerspectiveHandle): boolean =>
47
+ getPerspectiveState(instance, options).getCurrent() === undefined,
48
+ suspender: (instance: SanityInstance, _options?: PerspectiveHandle) =>
49
+ firstValueFrom(getActiveReleasesState(instance).observable.pipe(filter(Boolean))),
50
+ })