@sanity/sdk 0.0.0-alpha.21 → 0.0.0-alpha.23
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.
- package/dist/index.d.ts +428 -325
- package/dist/index.js +1618 -1553
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
- package/src/_exports/index.ts +31 -30
- package/src/auth/authStore.test.ts +149 -104
- package/src/auth/authStore.ts +51 -100
- package/src/auth/handleAuthCallback.test.ts +67 -34
- package/src/auth/handleAuthCallback.ts +8 -7
- package/src/auth/logout.test.ts +61 -29
- package/src/auth/logout.ts +26 -28
- package/src/auth/refreshStampedToken.test.ts +9 -9
- package/src/auth/refreshStampedToken.ts +62 -56
- package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +5 -5
- package/src/auth/subscribeToStateAndFetchCurrentUser.ts +45 -47
- package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +4 -5
- package/src/auth/subscribeToStorageEventsAndSetToken.ts +22 -24
- package/src/client/clientStore.test.ts +131 -67
- package/src/client/clientStore.ts +117 -116
- package/src/comlink/controller/actions/destroyController.test.ts +38 -13
- package/src/comlink/controller/actions/destroyController.ts +11 -15
- package/src/comlink/controller/actions/getOrCreateChannel.test.ts +56 -27
- package/src/comlink/controller/actions/getOrCreateChannel.ts +37 -35
- package/src/comlink/controller/actions/getOrCreateController.test.ts +27 -16
- package/src/comlink/controller/actions/getOrCreateController.ts +23 -22
- package/src/comlink/controller/actions/releaseChannel.test.ts +37 -13
- package/src/comlink/controller/actions/releaseChannel.ts +22 -21
- package/src/comlink/controller/comlinkControllerStore.test.ts +65 -36
- package/src/comlink/controller/comlinkControllerStore.ts +44 -5
- package/src/comlink/node/actions/getOrCreateNode.test.ts +31 -15
- package/src/comlink/node/actions/getOrCreateNode.ts +30 -29
- package/src/comlink/node/actions/releaseNode.test.ts +75 -55
- package/src/comlink/node/actions/releaseNode.ts +19 -21
- package/src/comlink/node/comlinkNodeStore.test.ts +6 -11
- package/src/comlink/node/comlinkNodeStore.ts +22 -5
- package/src/config/authConfig.ts +79 -0
- package/src/config/sanityConfig.ts +48 -0
- package/src/datasets/datasets.test.ts +2 -2
- package/src/datasets/datasets.ts +18 -5
- package/src/document/actions.test.ts +22 -10
- package/src/document/actions.ts +44 -56
- package/src/document/applyDocumentActions.test.ts +96 -36
- package/src/document/applyDocumentActions.ts +140 -99
- package/src/document/documentStore.test.ts +103 -155
- package/src/document/documentStore.ts +247 -237
- package/src/document/listen.ts +56 -55
- package/src/document/patchOperations.ts +0 -43
- package/src/document/permissions.test.ts +25 -12
- package/src/document/permissions.ts +11 -4
- package/src/document/processActions.test.ts +41 -8
- package/src/document/reducers.test.ts +87 -16
- package/src/document/reducers.ts +2 -2
- package/src/document/sharedListener.test.ts +34 -16
- package/src/document/sharedListener.ts +33 -11
- package/src/preview/getPreviewState.test.ts +40 -39
- package/src/preview/getPreviewState.ts +68 -56
- package/src/preview/previewConstants.ts +43 -0
- package/src/preview/previewQuery.test.ts +1 -1
- package/src/preview/previewQuery.ts +4 -5
- package/src/preview/previewStore.test.ts +13 -58
- package/src/preview/previewStore.ts +7 -21
- package/src/preview/resolvePreview.test.ts +33 -104
- package/src/preview/resolvePreview.ts +11 -21
- package/src/preview/subscribeToStateAndFetchBatches.test.ts +96 -97
- package/src/preview/subscribeToStateAndFetchBatches.ts +85 -81
- package/src/preview/util.ts +1 -0
- package/src/project/project.test.ts +3 -3
- package/src/project/project.ts +28 -5
- package/src/projection/getProjectionState.test.ts +69 -49
- package/src/projection/getProjectionState.ts +42 -50
- package/src/projection/projectionQuery.ts +1 -1
- package/src/projection/projectionStore.test.ts +13 -51
- package/src/projection/projectionStore.ts +6 -18
- package/src/projection/resolveProjection.test.ts +32 -127
- package/src/projection/resolveProjection.ts +15 -28
- package/src/projection/subscribeToStateAndFetchBatches.test.ts +105 -90
- package/src/projection/subscribeToStateAndFetchBatches.ts +94 -81
- package/src/projection/util.ts +2 -0
- package/src/projects/projects.test.ts +13 -4
- package/src/projects/projects.ts +6 -1
- package/src/query/queryStore.test.ts +10 -47
- package/src/query/queryStore.ts +151 -133
- package/src/query/queryStoreConstants.ts +2 -0
- package/src/store/createActionBinder.test.ts +153 -0
- package/src/store/createActionBinder.ts +176 -0
- package/src/store/createSanityInstance.test.ts +84 -0
- package/src/store/createSanityInstance.ts +124 -0
- package/src/store/createStateSourceAction.test.ts +196 -0
- package/src/store/createStateSourceAction.ts +260 -0
- package/src/store/createStoreInstance.test.ts +81 -0
- package/src/store/createStoreInstance.ts +80 -0
- package/src/store/createStoreState.test.ts +85 -0
- package/src/store/createStoreState.ts +92 -0
- package/src/store/defineStore.test.ts +18 -0
- package/src/store/defineStore.ts +81 -0
- package/src/users/reducers.test.ts +318 -0
- package/src/users/reducers.ts +88 -0
- package/src/users/types.ts +46 -4
- package/src/users/usersConstants.ts +4 -0
- package/src/users/usersStore.test.ts +350 -223
- package/src/users/usersStore.ts +285 -149
- package/src/utils/createFetcherStore.test.ts +6 -7
- package/src/utils/createFetcherStore.ts +150 -153
- package/src/{common/util.test.ts → utils/hashString.test.ts} +1 -1
- package/src/auth/fetchLoginUrls.test.ts +0 -163
- package/src/auth/fetchLoginUrls.ts +0 -74
- package/src/common/createLiveEventSubscriber.test.ts +0 -121
- package/src/common/createLiveEventSubscriber.ts +0 -55
- package/src/common/types.ts +0 -4
- package/src/instance/identity.test.ts +0 -46
- package/src/instance/identity.ts +0 -29
- package/src/instance/sanityInstance.test.ts +0 -77
- package/src/instance/sanityInstance.ts +0 -57
- package/src/instance/types.ts +0 -37
- package/src/preview/getPreviewProjection.ts +0 -45
- package/src/resources/README.md +0 -370
- package/src/resources/createAction.test.ts +0 -101
- package/src/resources/createAction.ts +0 -44
- package/src/resources/createResource.test.ts +0 -112
- package/src/resources/createResource.ts +0 -102
- package/src/resources/createStateSourceAction.test.ts +0 -114
- package/src/resources/createStateSourceAction.ts +0 -83
- package/src/resources/createStore.test.ts +0 -67
- package/src/resources/createStore.ts +0 -46
- package/src/store/createStore.test.ts +0 -108
- package/src/store/createStore.ts +0 -106
- /package/src/{common/util.ts → utils/hashString.ts} +0 -0
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import {type LiveEventMessage, SanityClient} from '@sanity/client'
|
|
2
|
-
import {Observable, of, Subject} from 'rxjs'
|
|
3
|
-
import {describe, it, vi} from 'vitest'
|
|
4
|
-
|
|
5
|
-
import {getClientState} from '../client/clientStore'
|
|
6
|
-
import {createSanityInstance} from '../instance/sanityInstance'
|
|
7
|
-
import {createResourceState, type ResourceState} from '../resources/createResource'
|
|
8
|
-
import {type StateSource} from '../resources/createStateSourceAction'
|
|
9
|
-
import {createLiveEventSubscriber} from './createLiveEventSubscriber'
|
|
10
|
-
import {type LiveEventAwareState} from './types'
|
|
11
|
-
|
|
12
|
-
vi.mock('../client/clientStore.ts', () => ({getClientState: vi.fn()}))
|
|
13
|
-
|
|
14
|
-
vi.mock('../resources/createResource', async (importOriginal) => {
|
|
15
|
-
const original = await importOriginal<typeof import('../resources/createResource')>()
|
|
16
|
-
return {...original, getOrCreateResource: vi.fn()}
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
describe('createLiveEventSubscriber', () => {
|
|
20
|
-
const TEST_TAG = 'test-tag'
|
|
21
|
-
const instance = createSanityInstance({projectId: 'exampleProject', dataset: 'exampleDataset'})
|
|
22
|
-
const initialState: LiveEventAwareState = {
|
|
23
|
-
lastLiveEventId: null,
|
|
24
|
-
syncTags: {},
|
|
25
|
-
}
|
|
26
|
-
let state: ResourceState<LiveEventAwareState>
|
|
27
|
-
|
|
28
|
-
beforeEach(() => {
|
|
29
|
-
state = createResourceState(initialState)
|
|
30
|
-
vi.clearAllMocks()
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('listens for matching sync tags and updates the `lastLiveEventId`', async () => {
|
|
34
|
-
const mockLiveEvents = new Observable<LiveEventMessage>((observer) => {
|
|
35
|
-
observer.next({
|
|
36
|
-
type: 'message',
|
|
37
|
-
id: 'event123',
|
|
38
|
-
tags: ['s1:tag1', 's1:tag2'],
|
|
39
|
-
})
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
const mockClient = {
|
|
43
|
-
live: {
|
|
44
|
-
events: vi.fn().mockReturnValue(mockLiveEvents),
|
|
45
|
-
},
|
|
46
|
-
config: vi.fn().mockReturnValue({}),
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Mock the getSubscribableClient to emit our mock client
|
|
50
|
-
vi.mocked(getClientState).mockReturnValue({
|
|
51
|
-
observable: of(mockClient as unknown as SanityClient),
|
|
52
|
-
} as StateSource<SanityClient>)
|
|
53
|
-
|
|
54
|
-
// Set up initial state with a matching sync tag
|
|
55
|
-
state.set('setSyncTags', {
|
|
56
|
-
syncTags: {
|
|
57
|
-
's1:tag1': true,
|
|
58
|
-
},
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
// Create and subscribe to live events
|
|
62
|
-
const subscribeToLiveAndSetLastLiveEventId =
|
|
63
|
-
createLiveEventSubscriber<LiveEventAwareState>(TEST_TAG)
|
|
64
|
-
const subscription = subscribeToLiveAndSetLastLiveEventId({instance, state})
|
|
65
|
-
|
|
66
|
-
// Verify the client was configured correctly
|
|
67
|
-
expect(mockClient.live.events).toHaveBeenCalledWith({
|
|
68
|
-
includeDrafts: false,
|
|
69
|
-
tag: TEST_TAG,
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
// Verify the state was updated with the new event ID
|
|
73
|
-
expect(state.get().lastLiveEventId).toBe('event123')
|
|
74
|
-
|
|
75
|
-
// Clean up subscription
|
|
76
|
-
subscription.unsubscribe()
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
it('unsubscribes from the previous live content connection if any', () => {
|
|
80
|
-
const unsubscribe = vi.fn()
|
|
81
|
-
|
|
82
|
-
const mockLiveEvents = new Observable<LiveEventMessage>((observer) => {
|
|
83
|
-
observer.next({
|
|
84
|
-
type: 'message',
|
|
85
|
-
id: 'event123',
|
|
86
|
-
tags: ['s1:tag1'],
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
return unsubscribe
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
const mockClient = {
|
|
93
|
-
live: {
|
|
94
|
-
events: vi.fn().mockReturnValue(mockLiveEvents),
|
|
95
|
-
},
|
|
96
|
-
config: vi.fn().mockReturnValue({}),
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const clientSubject = new Subject()
|
|
100
|
-
|
|
101
|
-
vi.mocked(getClientState).mockReturnValue({
|
|
102
|
-
observable: clientSubject as Observable<SanityClient>,
|
|
103
|
-
} as StateSource<SanityClient>)
|
|
104
|
-
|
|
105
|
-
// Create and subscribe to live events
|
|
106
|
-
const subscribeToLiveAndSetLastLiveEventId =
|
|
107
|
-
createLiveEventSubscriber<LiveEventAwareState>(TEST_TAG)
|
|
108
|
-
const liveSubscription = subscribeToLiveAndSetLastLiveEventId({instance, state})
|
|
109
|
-
clientSubject.next(mockClient)
|
|
110
|
-
|
|
111
|
-
expect(mockClient.live.events).toHaveBeenCalledTimes(1)
|
|
112
|
-
|
|
113
|
-
const newClient = {...mockClient}
|
|
114
|
-
clientSubject.next(newClient)
|
|
115
|
-
expect(unsubscribe).toHaveBeenCalledTimes(1)
|
|
116
|
-
|
|
117
|
-
// Clean up subscriptions
|
|
118
|
-
liveSubscription.unsubscribe()
|
|
119
|
-
expect(unsubscribe).toHaveBeenCalledTimes(2)
|
|
120
|
-
})
|
|
121
|
-
})
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import {combineLatest, distinctUntilChanged, filter, map, type Subscription, switchMap} from 'rxjs'
|
|
2
|
-
|
|
3
|
-
import {getClientState} from '../client/clientStore'
|
|
4
|
-
import {type ActionContext, createInternalAction} from '../resources/createAction'
|
|
5
|
-
import {type LiveEventAwareState} from './types'
|
|
6
|
-
|
|
7
|
-
/*
|
|
8
|
-
* Factory function for creating a subscribeToLiveAndSetLastLiveEventId action.
|
|
9
|
-
* Typically invoked in the initialization of stores that depend on the live events API.
|
|
10
|
-
* It listens to events associated with sync tags (also kept internally in the store)
|
|
11
|
-
|
|
12
|
-
* Usage like:
|
|
13
|
-
*
|
|
14
|
-
* const subscribeToLiveAndSetLastLiveEventId = createLiveEventSubscriber<ProjectionStoreState<TValue>>(TAG)
|
|
15
|
-
* const liveSubscription = subscribeToLiveAndSetLastLiveEventId(this)
|
|
16
|
-
*
|
|
17
|
-
* return () => {
|
|
18
|
-
* stateSubscriptionForBatches.unsubscribe()
|
|
19
|
-
* liveSubscription.unsubscribe()
|
|
20
|
-
*/
|
|
21
|
-
export function createLiveEventSubscriber<TState extends LiveEventAwareState>(
|
|
22
|
-
tag: string,
|
|
23
|
-
): (actionContext: ActionContext<TState>) => Subscription {
|
|
24
|
-
return createInternalAction(({instance, state}: ActionContext<TState>) => {
|
|
25
|
-
const client$ = getClientState(instance, {apiVersion: 'vX'}).observable
|
|
26
|
-
const syncTags$ = state.observable.pipe(
|
|
27
|
-
map((i) => i.syncTags),
|
|
28
|
-
distinctUntilChanged(),
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
return function () {
|
|
32
|
-
const messageEvents$ = client$.pipe(
|
|
33
|
-
switchMap((client) =>
|
|
34
|
-
client.live
|
|
35
|
-
.events({includeDrafts: !!client.config().token, tag})
|
|
36
|
-
.pipe(filter((e): e is Extract<typeof e, {type: 'message'}> => e.type === 'message')),
|
|
37
|
-
),
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
return combineLatest([messageEvents$, syncTags$]).subscribe({
|
|
41
|
-
next: ([event, currentSyncTags]) => {
|
|
42
|
-
for (const eventTag of event.tags) {
|
|
43
|
-
if (currentSyncTags[eventTag]) {
|
|
44
|
-
state.set('setLastLiveEventId', (prevState: TState) => ({
|
|
45
|
-
...prevState,
|
|
46
|
-
lastLiveEventId: event.id,
|
|
47
|
-
}))
|
|
48
|
-
return
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
})
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
}
|
package/src/common/types.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import {describe, expect, it} from 'vitest'
|
|
2
|
-
|
|
3
|
-
import {getSdkIdentity} from './identity'
|
|
4
|
-
|
|
5
|
-
describe('identity', () => {
|
|
6
|
-
describe('getSdkIdentity', () => {
|
|
7
|
-
it('creates a frozen object with expected properties', () => {
|
|
8
|
-
const identity = getSdkIdentity({
|
|
9
|
-
projectId: 'test-project',
|
|
10
|
-
dataset: 'test-dataset',
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
// Check if object is frozen
|
|
14
|
-
expect(Object.isFrozen(identity)).toBe(true)
|
|
15
|
-
|
|
16
|
-
// Check if all expected properties exist
|
|
17
|
-
expect(identity).toHaveProperty('id')
|
|
18
|
-
expect(identity).toHaveProperty('projectId', 'test-project')
|
|
19
|
-
expect(identity).toHaveProperty('dataset', 'test-dataset')
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('generates unique ids for different instances', () => {
|
|
23
|
-
const identity1 = getSdkIdentity({
|
|
24
|
-
projectId: 'test-project',
|
|
25
|
-
dataset: 'test-dataset',
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
const identity2 = getSdkIdentity({
|
|
29
|
-
projectId: 'test-project',
|
|
30
|
-
dataset: 'test-dataset',
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
expect(identity1.id).not.toBe(identity2.id)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it('generates id with correct format', () => {
|
|
37
|
-
const identity = getSdkIdentity({
|
|
38
|
-
projectId: 'test-project',
|
|
39
|
-
dataset: 'test-dataset',
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
// ID should be 16 characters long (8 pairs of hex digits)
|
|
43
|
-
expect(identity.id).toMatch(/^[0-9a-f]{16}$/)
|
|
44
|
-
})
|
|
45
|
-
})
|
|
46
|
-
})
|
package/src/instance/identity.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import {type SdkIdentity} from './types'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* thoughtLevel 2 - Primarily what we want is to have an object that we can bind stores/memoizations to, but let the things that depend on it (eg projectId, dataset) be internals that can't be overwritten by accident/intentionally
|
|
5
|
-
* @public
|
|
6
|
-
*/
|
|
7
|
-
export function getSdkIdentity({
|
|
8
|
-
projectId,
|
|
9
|
-
dataset,
|
|
10
|
-
}: {
|
|
11
|
-
projectId: string
|
|
12
|
-
dataset: string
|
|
13
|
-
}): SdkIdentity {
|
|
14
|
-
const id = generateId()
|
|
15
|
-
return Object.freeze({
|
|
16
|
-
id,
|
|
17
|
-
projectId,
|
|
18
|
-
dataset,
|
|
19
|
-
resourceId: `${projectId}.${dataset}`,
|
|
20
|
-
})
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function generateId() {
|
|
24
|
-
return Array.from({length: 8}, () =>
|
|
25
|
-
Math.floor(Math.random() * 16)
|
|
26
|
-
.toString(16)
|
|
27
|
-
.padStart(2, '0'),
|
|
28
|
-
).join('')
|
|
29
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import {beforeEach, describe, expect, test} from 'vitest'
|
|
2
|
-
|
|
3
|
-
import {disposeResources} from '../resources/createResource'
|
|
4
|
-
import {createSanityInstance, getOrCreateResource} from './sanityInstance'
|
|
5
|
-
import {type SanityConfig} from './types'
|
|
6
|
-
|
|
7
|
-
vi.mock('../resources/createResource')
|
|
8
|
-
|
|
9
|
-
describe('sanityInstance', () => {
|
|
10
|
-
let config: SanityConfig
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
config = {
|
|
14
|
-
projectId: 'test-project',
|
|
15
|
-
dataset: 'test-dataset',
|
|
16
|
-
}
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
describe('createSanityInstance', () => {
|
|
20
|
-
test('creates instance with correct configuration', () => {
|
|
21
|
-
const instance = createSanityInstance(config)
|
|
22
|
-
|
|
23
|
-
expect(instance.identity).toEqual(
|
|
24
|
-
expect.objectContaining({
|
|
25
|
-
projectId: 'test-project',
|
|
26
|
-
dataset: 'test-dataset',
|
|
27
|
-
}),
|
|
28
|
-
)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
test('instance.dispose', () => {
|
|
32
|
-
const instance = createSanityInstance(config)
|
|
33
|
-
instance.dispose()
|
|
34
|
-
|
|
35
|
-
expect(disposeResources).toHaveBeenCalled()
|
|
36
|
-
})
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
describe('getOrCreateResource', () => {
|
|
40
|
-
test('creates and caches resource', () => {
|
|
41
|
-
const instance = createSanityInstance(config)
|
|
42
|
-
let createCount = 0
|
|
43
|
-
|
|
44
|
-
const creator = () => {
|
|
45
|
-
createCount++
|
|
46
|
-
return {value: 'test-resource'}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// First call should create new resource
|
|
50
|
-
const resource1 = getOrCreateResource(instance, 'test-key', creator)
|
|
51
|
-
expect(resource1).toEqual({value: 'test-resource'})
|
|
52
|
-
expect(createCount).toBe(1)
|
|
53
|
-
|
|
54
|
-
// Second call should return cached resource
|
|
55
|
-
const resource2 = getOrCreateResource(instance, 'test-key', creator)
|
|
56
|
-
expect(resource2).toBe(resource1)
|
|
57
|
-
expect(createCount).toBe(1)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
test('different instances have separate resource caches', () => {
|
|
61
|
-
const instance1 = createSanityInstance({...config, projectId: 'project1'})
|
|
62
|
-
const instance2 = createSanityInstance({...config, projectId: 'project2'})
|
|
63
|
-
let createCount = 0
|
|
64
|
-
|
|
65
|
-
const creator = () => {
|
|
66
|
-
createCount++
|
|
67
|
-
return {value: 'test-resource'}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const resource1 = getOrCreateResource(instance1, 'test-key', creator)
|
|
71
|
-
const resource2 = getOrCreateResource(instance2, 'test-key', creator)
|
|
72
|
-
|
|
73
|
-
expect(resource1).not.toBe(resource2)
|
|
74
|
-
expect(createCount).toBe(2)
|
|
75
|
-
})
|
|
76
|
-
})
|
|
77
|
-
})
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import {disposeResources} from '../resources/createResource'
|
|
2
|
-
import {getSdkIdentity} from './identity'
|
|
3
|
-
import {type SanityConfig, type SanityInstance, type SdkIdentity} from './types'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Returns a new instance of dependencies required for SanitySDK.
|
|
7
|
-
*
|
|
8
|
-
* @public
|
|
9
|
-
*
|
|
10
|
-
* @param config - The configuration for this instance
|
|
11
|
-
*
|
|
12
|
-
* @returns A new "instance" of a Sanity SDK, used to bind resources/configuration to it
|
|
13
|
-
*/
|
|
14
|
-
export function createSanityInstance({
|
|
15
|
-
projectId = '',
|
|
16
|
-
dataset = '',
|
|
17
|
-
...config
|
|
18
|
-
}: SanityConfig): SanityInstance {
|
|
19
|
-
const identity = getSdkIdentity({projectId, dataset})
|
|
20
|
-
return {
|
|
21
|
-
identity,
|
|
22
|
-
config,
|
|
23
|
-
dispose: () => disposeResources(identity),
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const resourceStorage = new WeakMap<SdkIdentity, Map<string, unknown>>()
|
|
28
|
-
|
|
29
|
-
function getResource(instance: SanityInstance, key: string) {
|
|
30
|
-
const instanceMap = resourceStorage.get(instance.identity)
|
|
31
|
-
return instanceMap?.get(key)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function setResource(instance: SanityInstance, key: string, value: unknown) {
|
|
35
|
-
let instanceMap = resourceStorage.get(instance.identity)
|
|
36
|
-
if (!instanceMap) {
|
|
37
|
-
instanceMap = new Map()
|
|
38
|
-
resourceStorage.set(instance.identity, instanceMap)
|
|
39
|
-
}
|
|
40
|
-
instanceMap.set(key, value)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* This is an internal function that retrieves or creates a Zustand store resource.
|
|
45
|
-
* @internal
|
|
46
|
-
*/
|
|
47
|
-
export function getOrCreateResource<T>(instance: SanityInstance, key: string, creator: () => T): T {
|
|
48
|
-
const cached = getResource(instance, key)
|
|
49
|
-
|
|
50
|
-
if (cached) {
|
|
51
|
-
return cached as T
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const resource = creator()
|
|
55
|
-
setResource(instance, key, resource)
|
|
56
|
-
return resource
|
|
57
|
-
}
|
package/src/instance/types.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/consistent-type-specifier-style */
|
|
2
|
-
// NOTE: These have to be type import because we do not want the side-effect
|
|
3
|
-
// of importing these modules, we just want the types for their configs
|
|
4
|
-
import type {AuthConfig} from '../auth/authStore'
|
|
5
|
-
import type {ResourceId} from '../document/patchOperations'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @public
|
|
9
|
-
*/
|
|
10
|
-
export interface SanityConfig {
|
|
11
|
-
projectId: string
|
|
12
|
-
dataset: string
|
|
13
|
-
auth?: AuthConfig
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/** @public */
|
|
17
|
-
export interface SanityInstance {
|
|
18
|
-
/**
|
|
19
|
-
* The following is used to look up resources associated with this instance,
|
|
20
|
-
* and can be used to retrieve an "id" for the instance - useful in debugging.
|
|
21
|
-
*
|
|
22
|
-
* @public
|
|
23
|
-
*/
|
|
24
|
-
readonly identity: SdkIdentity
|
|
25
|
-
|
|
26
|
-
config: Omit<SanityConfig, 'projectId' | 'dataset'>
|
|
27
|
-
|
|
28
|
-
dispose: () => void
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** @public */
|
|
32
|
-
export interface SdkIdentity {
|
|
33
|
-
readonly id: string
|
|
34
|
-
readonly projectId: string
|
|
35
|
-
readonly dataset: string
|
|
36
|
-
readonly resourceId: ResourceId
|
|
37
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The fields to check for a title.
|
|
3
|
-
* The order of the items in the array defines the priority.
|
|
4
|
-
*
|
|
5
|
-
* @internal
|
|
6
|
-
*/
|
|
7
|
-
export const TITLE_CANDIDATES = ['title', 'name', 'label', 'heading', 'header', 'caption']
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* The fields to check for a subtitle.
|
|
11
|
-
* The order of the items in the array defines the priority.
|
|
12
|
-
*
|
|
13
|
-
* @internal
|
|
14
|
-
*/
|
|
15
|
-
export const SUBTITLE_CANDIDATES = ['description', 'subtitle', ...TITLE_CANDIDATES]
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Generates a GROQ projection for preview data without requiring a schema.
|
|
19
|
-
* Uses common field names to make educated guesses about which fields to use.
|
|
20
|
-
*
|
|
21
|
-
* @internal
|
|
22
|
-
*/
|
|
23
|
-
export function getPreviewProjection(): string {
|
|
24
|
-
return `{
|
|
25
|
-
// Get all potential title fields
|
|
26
|
-
"titleCandidates": {
|
|
27
|
-
${TITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(',\n ')}
|
|
28
|
-
},
|
|
29
|
-
// Get all potential subtitle fields
|
|
30
|
-
"subtitleCandidates": {
|
|
31
|
-
${SUBTITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(',\n ')}
|
|
32
|
-
},
|
|
33
|
-
"media": coalesce(
|
|
34
|
-
select(
|
|
35
|
-
defined(asset) => {"type": "image-asset", "_ref": asset._ref},
|
|
36
|
-
defined(image.asset) => {"type": "image-asset", "_ref": image.asset._ref},
|
|
37
|
-
defined(mainImage.asset) => {"type": "image-asset", "_ref": mainImage.asset._ref},
|
|
38
|
-
null
|
|
39
|
-
)
|
|
40
|
-
),
|
|
41
|
-
_type,
|
|
42
|
-
_id,
|
|
43
|
-
_updatedAt
|
|
44
|
-
}`
|
|
45
|
-
}
|