@sanity/sdk 2.4.0 → 2.5.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.
- package/dist/index.d.ts +35 -90
- package/dist/index.js +237 -111
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
- package/src/auth/authStore.test.ts +13 -13
- package/src/auth/refreshStampedToken.test.ts +16 -16
- package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +6 -6
- package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +4 -4
- package/src/comlink/controller/actions/destroyController.test.ts +2 -2
- package/src/comlink/controller/actions/getOrCreateChannel.test.ts +6 -6
- package/src/comlink/controller/actions/getOrCreateController.test.ts +5 -5
- package/src/comlink/controller/actions/getOrCreateController.ts +1 -1
- package/src/comlink/controller/actions/releaseChannel.test.ts +3 -2
- package/src/comlink/controller/comlinkControllerStore.test.ts +4 -4
- package/src/comlink/node/actions/getOrCreateNode.test.ts +7 -7
- package/src/comlink/node/actions/releaseNode.test.ts +2 -2
- package/src/comlink/node/comlinkNodeStore.test.ts +4 -3
- package/src/config/sanityConfig.ts +8 -3
- package/src/document/actions.ts +11 -7
- package/src/document/applyDocumentActions.test.ts +9 -6
- package/src/document/applyDocumentActions.ts +9 -49
- package/src/document/documentStore.test.ts +128 -115
- package/src/document/documentStore.ts +40 -10
- package/src/document/permissions.test.ts +9 -9
- package/src/document/permissions.ts +17 -7
- package/src/document/processActions.test.ts +248 -0
- package/src/document/processActions.ts +173 -0
- package/src/document/reducers.ts +13 -6
- package/src/presence/presenceStore.ts +13 -7
- package/src/preview/previewStore.test.ts +10 -2
- package/src/preview/previewStore.ts +2 -1
- package/src/preview/subscribeToStateAndFetchBatches.test.ts +8 -5
- package/src/preview/subscribeToStateAndFetchBatches.ts +9 -3
- package/src/projection/projectionStore.test.ts +18 -2
- package/src/projection/projectionStore.ts +2 -1
- package/src/projection/subscribeToStateAndFetchBatches.test.ts +6 -5
- package/src/projection/subscribeToStateAndFetchBatches.ts +9 -3
- package/src/releases/getPerspectiveState.ts +2 -2
- package/src/releases/releasesStore.ts +10 -4
- package/src/store/createActionBinder.test.ts +8 -6
- package/src/store/createActionBinder.ts +44 -29
- package/src/store/createStateSourceAction.test.ts +12 -11
- package/src/store/createStateSourceAction.ts +6 -6
- package/src/store/createStoreInstance.test.ts +29 -16
- package/src/store/createStoreInstance.ts +6 -5
- package/src/store/defineStore.test.ts +1 -1
- package/src/store/defineStore.ts +12 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Sanity SDK",
|
|
6
6
|
"keywords": [
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "git+
|
|
21
|
+
"url": "git+https://github.com/sanity-io/sdk.git",
|
|
22
|
+
"directory": "packages/core"
|
|
22
23
|
},
|
|
23
24
|
"license": "MIT",
|
|
24
25
|
"author": "Sanity <developers@sanity.io>",
|
|
@@ -48,7 +49,7 @@
|
|
|
48
49
|
"@sanity/diff-match-patch": "^3.2.0",
|
|
49
50
|
"@sanity/diff-patch": "^6.0.0",
|
|
50
51
|
"@sanity/json-match": "^1.0.5",
|
|
51
|
-
"@sanity/message-protocol": "^0.
|
|
52
|
+
"@sanity/message-protocol": "^0.18.0",
|
|
52
53
|
"@sanity/mutate": "^0.12.4",
|
|
53
54
|
"@sanity/types": "^3.83.0",
|
|
54
55
|
"groq": "3.88.1-typegen-experimental.0",
|
|
@@ -60,7 +61,7 @@
|
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
63
|
"@sanity/browserslist-config": "^1.0.5",
|
|
63
|
-
"@sanity/pkg-utils": "^
|
|
64
|
+
"@sanity/pkg-utils": "^8.1.29",
|
|
64
65
|
"@sanity/prettier-config": "^1.0.6",
|
|
65
66
|
"@types/lodash-es": "^4.17.12",
|
|
66
67
|
"@vitest/coverage-v8": "3.2.4",
|
|
@@ -70,14 +71,14 @@
|
|
|
70
71
|
"typescript": "^5.8.3",
|
|
71
72
|
"vite": "^6.3.4",
|
|
72
73
|
"vitest": "^3.2.4",
|
|
74
|
+
"@repo/config-eslint": "0.0.0",
|
|
73
75
|
"@repo/config-test": "0.0.1",
|
|
74
76
|
"@repo/package.bundle": "3.82.0",
|
|
75
|
-
"@repo/config
|
|
76
|
-
"@repo/tsconfig": "0.0.1"
|
|
77
|
-
"@repo/package.config": "0.0.1"
|
|
77
|
+
"@repo/package.config": "0.0.1",
|
|
78
|
+
"@repo/tsconfig": "0.0.1"
|
|
78
79
|
},
|
|
79
80
|
"engines": {
|
|
80
|
-
"node": ">=20.
|
|
81
|
+
"node": ">=20.19"
|
|
81
82
|
},
|
|
82
83
|
"publishConfig": {
|
|
83
84
|
"access": "public"
|
|
@@ -92,7 +92,7 @@ describe('authStore', () => {
|
|
|
92
92
|
},
|
|
93
93
|
})
|
|
94
94
|
|
|
95
|
-
const {options, dashboardContext} = authStore.getInitialState(instance)
|
|
95
|
+
const {options, dashboardContext} = authStore.getInitialState(instance, null)
|
|
96
96
|
|
|
97
97
|
expect(options.apiHost).toBe(apiHost)
|
|
98
98
|
expect(options.callbackUrl).toBe(callbackUrl)
|
|
@@ -114,7 +114,7 @@ describe('authStore', () => {
|
|
|
114
114
|
auth: {initialLocationHref},
|
|
115
115
|
})
|
|
116
116
|
|
|
117
|
-
const {dashboardContext, authState} = authStore.getInitialState(instance)
|
|
117
|
+
const {dashboardContext, authState} = authStore.getInitialState(instance, null)
|
|
118
118
|
expect(dashboardContext).toEqual(context)
|
|
119
119
|
expect(authState.type).toBe(AuthStateType.LOGGED_OUT)
|
|
120
120
|
})
|
|
@@ -129,7 +129,7 @@ describe('authStore', () => {
|
|
|
129
129
|
auth: {initialLocationHref},
|
|
130
130
|
})
|
|
131
131
|
|
|
132
|
-
const {dashboardContext, authState} = authStore.getInitialState(instance)
|
|
132
|
+
const {dashboardContext, authState} = authStore.getInitialState(instance, null)
|
|
133
133
|
expect(dashboardContext).toEqual(expectedContext)
|
|
134
134
|
expect(authState.type).toBe(AuthStateType.LOGGED_OUT)
|
|
135
135
|
})
|
|
@@ -143,7 +143,7 @@ describe('authStore', () => {
|
|
|
143
143
|
auth: {initialLocationHref},
|
|
144
144
|
})
|
|
145
145
|
|
|
146
|
-
const {dashboardContext, authState} = authStore.getInitialState(instance)
|
|
146
|
+
const {dashboardContext, authState} = authStore.getInitialState(instance, null)
|
|
147
147
|
expect(dashboardContext).toStrictEqual({})
|
|
148
148
|
expect(authState.type).toBe(AuthStateType.LOGGED_OUT)
|
|
149
149
|
expect(errorSpy).toHaveBeenCalledWith(
|
|
@@ -166,7 +166,7 @@ describe('authStore', () => {
|
|
|
166
166
|
},
|
|
167
167
|
})
|
|
168
168
|
|
|
169
|
-
const {authState, dashboardContext} = authStore.getInitialState(instance)
|
|
169
|
+
const {authState, dashboardContext} = authStore.getInitialState(instance, null)
|
|
170
170
|
expect(authState).toMatchObject({type: AuthStateType.LOGGED_IN, token})
|
|
171
171
|
expect(dashboardContext).toEqual(context)
|
|
172
172
|
})
|
|
@@ -182,7 +182,7 @@ describe('authStore', () => {
|
|
|
182
182
|
|
|
183
183
|
vi.mocked(getAuthCode).mockReturnValue('auth-code')
|
|
184
184
|
|
|
185
|
-
const {authState, dashboardContext} = authStore.getInitialState(instance)
|
|
185
|
+
const {authState, dashboardContext} = authStore.getInitialState(instance, null)
|
|
186
186
|
expect(authState).toMatchObject({type: AuthStateType.LOGGING_IN})
|
|
187
187
|
expect(dashboardContext).toEqual(context)
|
|
188
188
|
})
|
|
@@ -197,7 +197,7 @@ describe('authStore', () => {
|
|
|
197
197
|
vi.mocked(getAuthCode).mockReturnValue(null)
|
|
198
198
|
vi.mocked(getTokenFromStorage).mockReturnValue(storageToken)
|
|
199
199
|
|
|
200
|
-
const {authState, dashboardContext} = authStore.getInitialState(instance)
|
|
200
|
+
const {authState, dashboardContext} = authStore.getInitialState(instance, null)
|
|
201
201
|
expect(authState).toMatchObject({type: AuthStateType.LOGGED_IN, token: storageToken})
|
|
202
202
|
expect(dashboardContext).toStrictEqual({})
|
|
203
203
|
})
|
|
@@ -215,7 +215,7 @@ describe('authStore', () => {
|
|
|
215
215
|
vi.mocked(getAuthCode).mockReturnValue(null)
|
|
216
216
|
vi.mocked(getTokenFromStorage).mockReturnValue(storageToken)
|
|
217
217
|
|
|
218
|
-
const {authState, dashboardContext} = authStore.getInitialState(instance)
|
|
218
|
+
const {authState, dashboardContext} = authStore.getInitialState(instance, null)
|
|
219
219
|
expect(authState).toMatchObject({type: AuthStateType.LOGGED_OUT})
|
|
220
220
|
expect(dashboardContext).toEqual(context)
|
|
221
221
|
})
|
|
@@ -229,7 +229,7 @@ describe('authStore', () => {
|
|
|
229
229
|
vi.mocked(getAuthCode).mockReturnValue(null)
|
|
230
230
|
vi.mocked(getTokenFromStorage).mockReturnValue(null)
|
|
231
231
|
|
|
232
|
-
const {authState, dashboardContext} = authStore.getInitialState(instance)
|
|
232
|
+
const {authState, dashboardContext} = authStore.getInitialState(instance, null)
|
|
233
233
|
expect(authState).toMatchObject({type: AuthStateType.LOGGED_OUT})
|
|
234
234
|
expect(dashboardContext).toStrictEqual({})
|
|
235
235
|
})
|
|
@@ -252,7 +252,7 @@ describe('authStore', () => {
|
|
|
252
252
|
auth: {storageArea: mockStorage}, // Provide mock storage
|
|
253
253
|
})
|
|
254
254
|
|
|
255
|
-
const {authState, options} = authStore.getInitialState(instance)
|
|
255
|
+
const {authState, options} = authStore.getInitialState(instance, null)
|
|
256
256
|
expect(getStudioTokenFromLocalStorage).toHaveBeenCalledWith(mockStorage, studioStorageKey)
|
|
257
257
|
expect(authState).toMatchObject({type: AuthStateType.LOGGED_IN, token: studioToken})
|
|
258
258
|
expect(options.authMethod).toBe('localstorage')
|
|
@@ -277,7 +277,7 @@ describe('authStore', () => {
|
|
|
277
277
|
})
|
|
278
278
|
|
|
279
279
|
// Verify initial state without async cookie probe
|
|
280
|
-
const {authState: initialAuthState} = authStore.getInitialState(instance)
|
|
280
|
+
const {authState: initialAuthState} = authStore.getInitialState(instance, null)
|
|
281
281
|
expect(initialAuthState.type).toBe(AuthStateType.LOGGED_OUT)
|
|
282
282
|
expect(getStudioTokenFromLocalStorage).toHaveBeenCalledWith(mockStorage, studioStorageKey)
|
|
283
283
|
|
|
@@ -296,7 +296,7 @@ describe('authStore', () => {
|
|
|
296
296
|
dataset: 'd',
|
|
297
297
|
})
|
|
298
298
|
|
|
299
|
-
const {authState, options} = authStore.getInitialState(instance)
|
|
299
|
+
const {authState, options} = authStore.getInitialState(instance, null)
|
|
300
300
|
expect(getStudioTokenFromLocalStorage).not.toHaveBeenCalled()
|
|
301
301
|
expect(checkForCookieAuth).not.toHaveBeenCalled()
|
|
302
302
|
expect(getTokenFromStorage).toHaveBeenCalled()
|
|
@@ -314,7 +314,7 @@ describe('authStore', () => {
|
|
|
314
314
|
vi.mocked(getAuthCode).mockReturnValue(null)
|
|
315
315
|
vi.mocked(getTokenFromLocation).mockReturnValue('hash-token')
|
|
316
316
|
|
|
317
|
-
const {authState} = authStore.getInitialState(instance)
|
|
317
|
+
const {authState} = authStore.getInitialState(instance, null)
|
|
318
318
|
expect(authState).toMatchObject({
|
|
319
319
|
type: AuthStateType.LOGGING_IN,
|
|
320
320
|
isExchangingToken: false,
|
|
@@ -122,7 +122,7 @@ describe('refreshStampedToken', () => {
|
|
|
122
122
|
dataset: 'd',
|
|
123
123
|
auth: {clientFactory: mockClientFactory, storageArea: mockStorage},
|
|
124
124
|
})
|
|
125
|
-
const initialState = authStore.getInitialState(instance)
|
|
125
|
+
const initialState = authStore.getInitialState(instance, null)
|
|
126
126
|
initialState.authState = {
|
|
127
127
|
type: AuthStateType.LOGGED_IN,
|
|
128
128
|
token: 'sk-initial-token-st123',
|
|
@@ -131,7 +131,7 @@ describe('refreshStampedToken', () => {
|
|
|
131
131
|
initialState.dashboardContext = {mode: 'test'}
|
|
132
132
|
const state = createStoreState(initialState)
|
|
133
133
|
|
|
134
|
-
const subscription = refreshStampedToken({state, instance})
|
|
134
|
+
const subscription = refreshStampedToken({state, instance, key: null})
|
|
135
135
|
subscriptions.push(subscription)
|
|
136
136
|
|
|
137
137
|
await vi.advanceTimersToNextTimerAsync()
|
|
@@ -168,7 +168,7 @@ describe('refreshStampedToken', () => {
|
|
|
168
168
|
dataset: 'd',
|
|
169
169
|
auth: {clientFactory: mockClientFactory, storageArea: mockStorage},
|
|
170
170
|
})
|
|
171
|
-
const initialState = authStore.getInitialState(instance)
|
|
171
|
+
const initialState = authStore.getInitialState(instance, null)
|
|
172
172
|
initialState.authState = {
|
|
173
173
|
type: AuthStateType.LOGGED_IN,
|
|
174
174
|
token: 'sk-initial-token-st123',
|
|
@@ -177,7 +177,7 @@ describe('refreshStampedToken', () => {
|
|
|
177
177
|
initialState.dashboardContext = {mode: 'test'}
|
|
178
178
|
const state = createStoreState(initialState)
|
|
179
179
|
|
|
180
|
-
const subscription = refreshStampedToken({state, instance})
|
|
180
|
+
const subscription = refreshStampedToken({state, instance, key: null})
|
|
181
181
|
subscriptions.push(subscription)
|
|
182
182
|
|
|
183
183
|
await vi.advanceTimersToNextTimerAsync()
|
|
@@ -202,7 +202,7 @@ describe('refreshStampedToken', () => {
|
|
|
202
202
|
dataset: 'd',
|
|
203
203
|
auth: {clientFactory: mockClientFactory, storageArea: mockStorage},
|
|
204
204
|
})
|
|
205
|
-
const initialState = authStore.getInitialState(instance)
|
|
205
|
+
const initialState = authStore.getInitialState(instance, null)
|
|
206
206
|
initialState.authState = {
|
|
207
207
|
type: AuthStateType.LOGGED_IN,
|
|
208
208
|
token: 'sk-initial-token-st123',
|
|
@@ -213,7 +213,7 @@ describe('refreshStampedToken', () => {
|
|
|
213
213
|
let subscription: Subscription | undefined
|
|
214
214
|
// We expect this NOT to throw, but accept we can't easily test the lock call or outcome
|
|
215
215
|
expect(() => {
|
|
216
|
-
subscription = refreshStampedToken({state, instance})
|
|
216
|
+
subscription = refreshStampedToken({state, instance, key: null})
|
|
217
217
|
subscriptions.push(subscription!)
|
|
218
218
|
}).not.toThrow()
|
|
219
219
|
|
|
@@ -253,7 +253,7 @@ describe('refreshStampedToken', () => {
|
|
|
253
253
|
dataset: 'd',
|
|
254
254
|
auth: {clientFactory: mockClientFactory, storageArea: mockStorage},
|
|
255
255
|
})
|
|
256
|
-
const initialState = authStore.getInitialState(instance)
|
|
256
|
+
const initialState = authStore.getInitialState(instance, null)
|
|
257
257
|
initialState.authState = {
|
|
258
258
|
type: AuthStateType.LOGGED_IN,
|
|
259
259
|
token: 'sk-initial-token-st123',
|
|
@@ -261,7 +261,7 @@ describe('refreshStampedToken', () => {
|
|
|
261
261
|
}
|
|
262
262
|
const state = createStoreState(initialState)
|
|
263
263
|
|
|
264
|
-
const subscription = refreshStampedToken({state, instance})
|
|
264
|
+
const subscription = refreshStampedToken({state, instance, key: null})
|
|
265
265
|
subscriptions.push(subscription)
|
|
266
266
|
|
|
267
267
|
// DO NOT advance timers or yield here - focus on immediate observable logic
|
|
@@ -303,7 +303,7 @@ describe('refreshStampedToken', () => {
|
|
|
303
303
|
dataset: 'd',
|
|
304
304
|
auth: {clientFactory: mockClientFactory, storageArea: mockStorage},
|
|
305
305
|
})
|
|
306
|
-
const initialState = authStore.getInitialState(instance)
|
|
306
|
+
const initialState = authStore.getInitialState(instance, null)
|
|
307
307
|
initialState.authState = {
|
|
308
308
|
type: AuthStateType.LOGGED_IN,
|
|
309
309
|
token: 'sk-initial-token-st123',
|
|
@@ -311,7 +311,7 @@ describe('refreshStampedToken', () => {
|
|
|
311
311
|
}
|
|
312
312
|
const state = createStoreState(initialState)
|
|
313
313
|
|
|
314
|
-
const subscription = refreshStampedToken({state, instance})
|
|
314
|
+
const subscription = refreshStampedToken({state, instance, key: null})
|
|
315
315
|
subscriptions.push(subscription)
|
|
316
316
|
|
|
317
317
|
// Advance timers to allow the async `performRefresh` to execute
|
|
@@ -349,7 +349,7 @@ describe('refreshStampedToken', () => {
|
|
|
349
349
|
dataset: 'd',
|
|
350
350
|
auth: {clientFactory: mockClientFactory, storageArea: mockStorage},
|
|
351
351
|
})
|
|
352
|
-
const initialState = authStore.getInitialState(instance)
|
|
352
|
+
const initialState = authStore.getInitialState(instance, null)
|
|
353
353
|
initialState.authState = {
|
|
354
354
|
type: AuthStateType.LOGGED_IN,
|
|
355
355
|
token: 'sk-initial-token-st123',
|
|
@@ -358,7 +358,7 @@ describe('refreshStampedToken', () => {
|
|
|
358
358
|
initialState.dashboardContext = {mode: 'test'}
|
|
359
359
|
const state = createStoreState(initialState)
|
|
360
360
|
|
|
361
|
-
const subscription = refreshStampedToken({state, instance})
|
|
361
|
+
const subscription = refreshStampedToken({state, instance, key: null})
|
|
362
362
|
subscriptions.push(subscription)
|
|
363
363
|
|
|
364
364
|
await vi.advanceTimersToNextTimerAsync()
|
|
@@ -378,14 +378,14 @@ describe('refreshStampedToken', () => {
|
|
|
378
378
|
dataset: 'd',
|
|
379
379
|
auth: {clientFactory: mockClientFactory, storageArea: mockStorage},
|
|
380
380
|
})
|
|
381
|
-
const initialState = authStore.getInitialState(instance)
|
|
381
|
+
const initialState = authStore.getInitialState(instance, null)
|
|
382
382
|
initialState.authState = {
|
|
383
383
|
type: AuthStateType.LOGGED_OUT,
|
|
384
384
|
isDestroyingSession: false,
|
|
385
385
|
} as AuthState
|
|
386
386
|
const state = createStoreState(initialState)
|
|
387
387
|
|
|
388
|
-
const subscription = refreshStampedToken({state, instance})
|
|
388
|
+
const subscription = refreshStampedToken({state, instance, key: null})
|
|
389
389
|
subscriptions.push(subscription)
|
|
390
390
|
|
|
391
391
|
await vi.advanceTimersByTimeAsync(0)
|
|
@@ -404,7 +404,7 @@ describe('refreshStampedToken', () => {
|
|
|
404
404
|
dataset: 'd',
|
|
405
405
|
auth: {clientFactory: mockClientFactory, storageArea: mockStorage},
|
|
406
406
|
})
|
|
407
|
-
const initialState = authStore.getInitialState(instance)
|
|
407
|
+
const initialState = authStore.getInitialState(instance, null)
|
|
408
408
|
initialState.authState = {
|
|
409
409
|
type: AuthStateType.LOGGED_IN,
|
|
410
410
|
token: 'sk-nonstamped-token',
|
|
@@ -412,7 +412,7 @@ describe('refreshStampedToken', () => {
|
|
|
412
412
|
}
|
|
413
413
|
const state = createStoreState(initialState)
|
|
414
414
|
|
|
415
|
-
const subscription = refreshStampedToken({state, instance})
|
|
415
|
+
const subscription = refreshStampedToken({state, instance, key: null})
|
|
416
416
|
subscriptions.push(subscription)
|
|
417
417
|
|
|
418
418
|
await vi.advanceTimersByTimeAsync(0)
|
|
@@ -20,8 +20,8 @@ describe('subscribeToStateAndFetchCurrentUser', () => {
|
|
|
20
20
|
const clientFactory = vi.fn().mockReturnValue(mockClient)
|
|
21
21
|
const instance = createSanityInstance({projectId: 'p', dataset: 'd', auth: {clientFactory}})
|
|
22
22
|
|
|
23
|
-
const state = createStoreState(authStore.getInitialState(instance))
|
|
24
|
-
const subscription = subscribeToStateAndFetchCurrentUser({state, instance})
|
|
23
|
+
const state = createStoreState(authStore.getInitialState(instance, null))
|
|
24
|
+
const subscription = subscribeToStateAndFetchCurrentUser({state, instance, key: null})
|
|
25
25
|
|
|
26
26
|
expect(state.get()).toMatchObject({authState: {type: AuthStateType.LOGGED_OUT}})
|
|
27
27
|
|
|
@@ -52,8 +52,8 @@ describe('subscribeToStateAndFetchCurrentUser', () => {
|
|
|
52
52
|
const clientFactory = vi.fn().mockReturnValue(mockClient)
|
|
53
53
|
const instance = createSanityInstance({projectId: 'p', dataset: 'd', auth: {clientFactory}})
|
|
54
54
|
|
|
55
|
-
const state = createStoreState(authStore.getInitialState(instance))
|
|
56
|
-
const subscription = subscribeToStateAndFetchCurrentUser({state, instance})
|
|
55
|
+
const state = createStoreState(authStore.getInitialState(instance, null))
|
|
56
|
+
const subscription = subscribeToStateAndFetchCurrentUser({state, instance, key: null})
|
|
57
57
|
|
|
58
58
|
expect(state.get()).toMatchObject({authState: {type: AuthStateType.LOGGED_OUT}})
|
|
59
59
|
|
|
@@ -88,8 +88,8 @@ describe('subscribeToStateAndFetchCurrentUser', () => {
|
|
|
88
88
|
const clientFactory = vi.fn().mockReturnValue(mockClient)
|
|
89
89
|
const instance = createSanityInstance({projectId: 'p', dataset: 'd', auth: {clientFactory}})
|
|
90
90
|
|
|
91
|
-
const state = createStoreState(authStore.getInitialState(instance))
|
|
92
|
-
const subscription = subscribeToStateAndFetchCurrentUser({state, instance})
|
|
91
|
+
const state = createStoreState(authStore.getInitialState(instance, null))
|
|
92
|
+
const subscription = subscribeToStateAndFetchCurrentUser({state, instance, key: null})
|
|
93
93
|
|
|
94
94
|
expect(state.get()).toMatchObject({authState: {type: AuthStateType.LOGGED_OUT}})
|
|
95
95
|
|
|
@@ -34,9 +34,9 @@ describe('subscribeToStorageEventsAndSetToken', () => {
|
|
|
34
34
|
})
|
|
35
35
|
|
|
36
36
|
it('sets the state to logged in when a matching storage event returns a token', () => {
|
|
37
|
-
const state = createStoreState(authStore.getInitialState(instance))
|
|
37
|
+
const state = createStoreState(authStore.getInitialState(instance, null))
|
|
38
38
|
const {storageKey} = state.get().options
|
|
39
|
-
const subscription = subscribeToStorageEventsAndSetToken({state, instance})
|
|
39
|
+
const subscription = subscribeToStorageEventsAndSetToken({state, instance, key: null})
|
|
40
40
|
|
|
41
41
|
expect(state.get()).toMatchObject({
|
|
42
42
|
authState: {type: AuthStateType.LOGGED_OUT, isDestroyingSession: false},
|
|
@@ -54,10 +54,10 @@ describe('subscribeToStorageEventsAndSetToken', () => {
|
|
|
54
54
|
|
|
55
55
|
it('sets the state to logged in when a matching storage event returns null', () => {
|
|
56
56
|
vi.mocked(getTokenFromStorage).mockReturnValue('existing-token')
|
|
57
|
-
const state = createStoreState(authStore.getInitialState(instance))
|
|
57
|
+
const state = createStoreState(authStore.getInitialState(instance, null))
|
|
58
58
|
const {storageKey} = state.get().options
|
|
59
59
|
|
|
60
|
-
const subscription = subscribeToStorageEventsAndSetToken({state, instance})
|
|
60
|
+
const subscription = subscribeToStorageEventsAndSetToken({state, instance, key: null})
|
|
61
61
|
|
|
62
62
|
expect(state.get()).toMatchObject({
|
|
63
63
|
authState: {type: AuthStateType.LOGGED_IN, token: 'existing-token', currentUser: null},
|
|
@@ -39,7 +39,7 @@ describe('destroyController', () => {
|
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
// Execute action
|
|
42
|
-
destroyController({state, instance})
|
|
42
|
+
destroyController({state, instance, key: null})
|
|
43
43
|
|
|
44
44
|
// Verify controller was destroyed and state was cleared
|
|
45
45
|
expect(mockController.destroy).toHaveBeenCalled()
|
|
@@ -49,7 +49,7 @@ describe('destroyController', () => {
|
|
|
49
49
|
|
|
50
50
|
it('should do nothing if no controller exists', () => {
|
|
51
51
|
// State already has null controller, so just execute action
|
|
52
|
-
expect(() => destroyController({state, instance})).not.toThrow()
|
|
52
|
+
expect(() => destroyController({state, instance, key: null})).not.toThrow()
|
|
53
53
|
|
|
54
54
|
// State should remain unchanged
|
|
55
55
|
expect(state.get().controller).toBeNull()
|
|
@@ -49,7 +49,7 @@ describe('getOrCreateChannel', () => {
|
|
|
49
49
|
it('should create a new channel using the controller', () => {
|
|
50
50
|
const createChannelSpy = vi.spyOn(mockController, 'createChannel')
|
|
51
51
|
|
|
52
|
-
const channel = getOrCreateChannel({state, instance}, channelConfig)
|
|
52
|
+
const channel = getOrCreateChannel({state, instance, key: null}, channelConfig)
|
|
53
53
|
|
|
54
54
|
expect(createChannelSpy).toHaveBeenCalledWith(channelConfig)
|
|
55
55
|
expect(channel.on).toBeDefined()
|
|
@@ -70,17 +70,17 @@ describe('getOrCreateChannel', () => {
|
|
|
70
70
|
channels: new Map(),
|
|
71
71
|
})
|
|
72
72
|
|
|
73
|
-
expect(() => getOrCreateChannel({state, instance}, channelConfig)).toThrow(
|
|
73
|
+
expect(() => getOrCreateChannel({state, instance, key: null}, channelConfig)).toThrow(
|
|
74
74
|
'Controller must be initialized before using or creating channels',
|
|
75
75
|
)
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
it('should retrieve channel directly from store once created', () => {
|
|
79
|
-
const createdChannel = getOrCreateChannel({state, instance}, channelConfig)
|
|
79
|
+
const createdChannel = getOrCreateChannel({state, instance, key: null}, channelConfig)
|
|
80
80
|
vi.clearAllMocks() // Clear call counts
|
|
81
81
|
|
|
82
82
|
// Retrieve channel again
|
|
83
|
-
const retrievedChannel = getOrCreateChannel({state, instance}, channelConfig)
|
|
83
|
+
const retrievedChannel = getOrCreateChannel({state, instance, key: null}, channelConfig)
|
|
84
84
|
expect(retrievedChannel).toBeDefined()
|
|
85
85
|
expect(retrievedChannel).toBe(createdChannel)
|
|
86
86
|
|
|
@@ -95,10 +95,10 @@ describe('getOrCreateChannel', () => {
|
|
|
95
95
|
})
|
|
96
96
|
|
|
97
97
|
it('should throw error when trying to create channel with different options', () => {
|
|
98
|
-
getOrCreateChannel({state, instance}, channelConfig)
|
|
98
|
+
getOrCreateChannel({state, instance, key: null}, channelConfig)
|
|
99
99
|
|
|
100
100
|
expect(() =>
|
|
101
|
-
getOrCreateChannel({state, instance}, {...channelConfig, connectTo: 'window'}),
|
|
101
|
+
getOrCreateChannel({state, instance, key: null}, {...channelConfig, connectTo: 'window'}),
|
|
102
102
|
).toThrow('Channel "test" already exists with different options')
|
|
103
103
|
})
|
|
104
104
|
})
|
|
@@ -43,7 +43,7 @@ describe('getOrCreateController', () => {
|
|
|
43
43
|
const controllerSpy = vi.spyOn(comlink, 'createController')
|
|
44
44
|
const targetOrigin = 'https://test.sanity.dev'
|
|
45
45
|
|
|
46
|
-
const controller = getOrCreateController({state, instance}, targetOrigin)
|
|
46
|
+
const controller = getOrCreateController({state, instance, key: null}, targetOrigin)
|
|
47
47
|
|
|
48
48
|
expect(controllerSpy).toHaveBeenCalledWith({targetOrigin})
|
|
49
49
|
expect(controller).toBeDefined()
|
|
@@ -56,8 +56,8 @@ describe('getOrCreateController', () => {
|
|
|
56
56
|
const controllerSpy = vi.spyOn(comlink, 'createController')
|
|
57
57
|
const targetOrigin = 'https://test.sanity.dev'
|
|
58
58
|
|
|
59
|
-
const firstController = getOrCreateController({state, instance}, targetOrigin)
|
|
60
|
-
const secondController = getOrCreateController({state, instance}, targetOrigin)
|
|
59
|
+
const firstController = getOrCreateController({state, instance, key: null}, targetOrigin)
|
|
60
|
+
const secondController = getOrCreateController({state, instance, key: null}, targetOrigin)
|
|
61
61
|
|
|
62
62
|
expect(controllerSpy).toHaveBeenCalledTimes(1)
|
|
63
63
|
expect(firstController).toBe(secondController)
|
|
@@ -68,9 +68,9 @@ describe('getOrCreateController', () => {
|
|
|
68
68
|
const targetOrigin = 'https://test.sanity.dev'
|
|
69
69
|
const targetOrigin2 = 'https://test2.sanity.dev'
|
|
70
70
|
|
|
71
|
-
const firstController = getOrCreateController({state, instance}, targetOrigin)
|
|
71
|
+
const firstController = getOrCreateController({state, instance, key: null}, targetOrigin)
|
|
72
72
|
const destroySpy = vi.spyOn(firstController, 'destroy')
|
|
73
|
-
const secondController = getOrCreateController({state, instance}, targetOrigin2)
|
|
73
|
+
const secondController = getOrCreateController({state, instance, key: null}, targetOrigin2)
|
|
74
74
|
|
|
75
75
|
expect(controllerSpy).toHaveBeenCalledTimes(2)
|
|
76
76
|
expect(destroySpy).toHaveBeenCalled()
|
|
@@ -21,7 +21,7 @@ export const getOrCreateController = (
|
|
|
21
21
|
// if the target origin has changed, we'll create a new controller,
|
|
22
22
|
// but need to clean up first
|
|
23
23
|
if (controller) {
|
|
24
|
-
destroyController({state, instance})
|
|
24
|
+
destroyController({state, instance, key: undefined})
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const newController = createController({targetOrigin})
|
|
@@ -19,6 +19,7 @@ const channelConfig = {
|
|
|
19
19
|
describe('releaseChannel', () => {
|
|
20
20
|
let instance: SanityInstance
|
|
21
21
|
let store: StoreInstance<ComlinkControllerState>
|
|
22
|
+
const key = {name: 'global', projectId: 'test-project-id', dataset: 'test-dataset'}
|
|
22
23
|
|
|
23
24
|
let getOrCreateChannel: (
|
|
24
25
|
inst: SanityInstance,
|
|
@@ -29,14 +30,14 @@ describe('releaseChannel', () => {
|
|
|
29
30
|
|
|
30
31
|
beforeEach(() => {
|
|
31
32
|
instance = createSanityInstance({projectId: 'test-project-id', dataset: 'test-dataset'})
|
|
32
|
-
store = createStoreInstance(instance, comlinkControllerStore)
|
|
33
|
+
store = createStoreInstance(instance, key, comlinkControllerStore)
|
|
33
34
|
|
|
34
35
|
const bind =
|
|
35
36
|
<TParams extends unknown[], TReturn>(
|
|
36
37
|
action: StoreAction<ComlinkControllerState, TParams, TReturn>,
|
|
37
38
|
) =>
|
|
38
39
|
(inst: SanityInstance, ...params: TParams) =>
|
|
39
|
-
action({instance: inst, state: store.state}, ...params)
|
|
40
|
+
action({instance: inst, state: store.state, key}, ...params)
|
|
40
41
|
|
|
41
42
|
getOrCreateChannel = bind(unboundGetOrCreateChannel)
|
|
42
43
|
getOrCreateController = bind(unboundGetOrCreateController)
|
|
@@ -31,7 +31,7 @@ describe('comlinkControllerStore', () => {
|
|
|
31
31
|
|
|
32
32
|
// Create store state directly
|
|
33
33
|
const state = createStoreState<ComlinkControllerState>(
|
|
34
|
-
comlinkControllerStore.getInitialState(instance),
|
|
34
|
+
comlinkControllerStore.getInitialState(instance, null),
|
|
35
35
|
)
|
|
36
36
|
|
|
37
37
|
const initialState = state.get()
|
|
@@ -56,13 +56,13 @@ describe('comlinkControllerStore', () => {
|
|
|
56
56
|
vi.mocked(bindActionGlobally).mockImplementation(
|
|
57
57
|
(_storeDef, action) =>
|
|
58
58
|
(inst: SanityInstance, ...params: unknown[]) =>
|
|
59
|
-
action({instance: inst, state}, ...params),
|
|
59
|
+
action({instance: inst, state, key: {name: 'global'}}, ...params),
|
|
60
60
|
)
|
|
61
61
|
|
|
62
62
|
const {comlinkControllerStore} = await import('./comlinkControllerStore')
|
|
63
63
|
|
|
64
64
|
// Get the cleanup function from the store
|
|
65
|
-
const dispose = comlinkControllerStore.initialize?.({state, instance})
|
|
65
|
+
const dispose = comlinkControllerStore.initialize?.({state, instance, key: null})
|
|
66
66
|
|
|
67
67
|
// Run cleanup
|
|
68
68
|
dispose?.()
|
|
@@ -82,7 +82,7 @@ describe('comlinkControllerStore', () => {
|
|
|
82
82
|
})
|
|
83
83
|
|
|
84
84
|
// Get the cleanup function
|
|
85
|
-
const cleanup = comlinkControllerStore.initialize?.({state, instance})
|
|
85
|
+
const cleanup = comlinkControllerStore.initialize?.({state, instance, key: null})
|
|
86
86
|
|
|
87
87
|
// Should not throw when no controller exists
|
|
88
88
|
expect(() => cleanup?.()).not.toThrow()
|
|
@@ -40,24 +40,24 @@ describe('getOrCreateNode', () => {
|
|
|
40
40
|
})
|
|
41
41
|
|
|
42
42
|
it('should create and start a node', () => {
|
|
43
|
-
const node = getOrCreateNode({state, instance}, nodeConfig)
|
|
43
|
+
const node = getOrCreateNode({state, instance, key: null}, nodeConfig)
|
|
44
44
|
|
|
45
45
|
expect(comlink.createNode).toHaveBeenCalledWith(nodeConfig)
|
|
46
46
|
expect(node.start).toHaveBeenCalled()
|
|
47
47
|
})
|
|
48
48
|
|
|
49
49
|
it('should store the node in nodeStore', () => {
|
|
50
|
-
const node = getOrCreateNode({state, instance}, nodeConfig)
|
|
50
|
+
const node = getOrCreateNode({state, instance, key: null}, nodeConfig)
|
|
51
51
|
|
|
52
|
-
expect(getOrCreateNode({state, instance}, nodeConfig)).toBe(node)
|
|
52
|
+
expect(getOrCreateNode({state, instance, key: null}, nodeConfig)).toBe(node)
|
|
53
53
|
})
|
|
54
54
|
|
|
55
55
|
it('should throw error when trying to create node with different options', () => {
|
|
56
|
-
getOrCreateNode({state, instance}, nodeConfig)
|
|
56
|
+
getOrCreateNode({state, instance, key: null}, nodeConfig)
|
|
57
57
|
|
|
58
58
|
expect(() =>
|
|
59
59
|
getOrCreateNode(
|
|
60
|
-
{state, instance},
|
|
60
|
+
{state, instance, key: null},
|
|
61
61
|
{
|
|
62
62
|
...nodeConfig,
|
|
63
63
|
connectTo: 'window',
|
|
@@ -74,7 +74,7 @@ describe('getOrCreateNode', () => {
|
|
|
74
74
|
return statusUnsubMock
|
|
75
75
|
})
|
|
76
76
|
|
|
77
|
-
getOrCreateNode({state, instance}, nodeConfig)
|
|
77
|
+
getOrCreateNode({state, instance, key: null}, nodeConfig)
|
|
78
78
|
|
|
79
79
|
expect(mockNode.onStatus).toHaveBeenCalled()
|
|
80
80
|
expect(state.get().nodes.get(nodeConfig.name)?.statusUnsub).toBe(statusUnsubMock)
|
|
@@ -92,7 +92,7 @@ describe('getOrCreateNode', () => {
|
|
|
92
92
|
return statusUnsubMock
|
|
93
93
|
})
|
|
94
94
|
|
|
95
|
-
getOrCreateNode({state, instance}, nodeConfig)
|
|
95
|
+
getOrCreateNode({state, instance, key: null}, nodeConfig)
|
|
96
96
|
|
|
97
97
|
// Remove the node entry before triggering the status callback
|
|
98
98
|
state.get().nodes.delete(nodeConfig.name)
|
|
@@ -47,7 +47,7 @@ describe('releaseNode', () => {
|
|
|
47
47
|
expect(state.get().nodes.has('test-node')).toBe(true)
|
|
48
48
|
|
|
49
49
|
// Release the node
|
|
50
|
-
releaseNode({state, instance}, 'test-node')
|
|
50
|
+
releaseNode({state, instance, key: null}, 'test-node')
|
|
51
51
|
|
|
52
52
|
// Check node is removed
|
|
53
53
|
expect(mockNode.stop).toHaveBeenCalled()
|
|
@@ -64,7 +64,7 @@ describe('releaseNode', () => {
|
|
|
64
64
|
})
|
|
65
65
|
state.set('setup', {nodes})
|
|
66
66
|
|
|
67
|
-
releaseNode({state, instance}, 'test-node')
|
|
67
|
+
releaseNode({state, instance, key: null}, 'test-node')
|
|
68
68
|
|
|
69
69
|
expect(statusUnsub).toHaveBeenCalled()
|
|
70
70
|
})
|
|
@@ -14,7 +14,7 @@ describe('nodeStore', () => {
|
|
|
14
14
|
})
|
|
15
15
|
|
|
16
16
|
it('should have correct initial state', () => {
|
|
17
|
-
const initialState = comlinkNodeStore.getInitialState(instance)
|
|
17
|
+
const initialState = comlinkNodeStore.getInitialState(instance, null)
|
|
18
18
|
|
|
19
19
|
expect(initialState.nodes).toBeInstanceOf(Map)
|
|
20
20
|
expect(initialState.nodes.size).toBe(0)
|
|
@@ -25,16 +25,17 @@ describe('nodeStore', () => {
|
|
|
25
25
|
stop: vi.fn(),
|
|
26
26
|
} as unknown as Node<WindowMessage, FrameMessage>
|
|
27
27
|
|
|
28
|
-
const initialState = comlinkNodeStore.getInitialState(instance)
|
|
28
|
+
const initialState = comlinkNodeStore.getInitialState(instance, null)
|
|
29
29
|
initialState.nodes.set('test-node', {
|
|
30
30
|
options: {name: 'test-node', connectTo: 'parent'},
|
|
31
31
|
node: mockNode,
|
|
32
|
-
|
|
32
|
+
status: 'idle',
|
|
33
33
|
})
|
|
34
34
|
|
|
35
35
|
const cleanup = comlinkNodeStore.initialize?.({
|
|
36
36
|
instance,
|
|
37
37
|
state: createStoreState(initialState),
|
|
38
|
+
key: null,
|
|
38
39
|
})
|
|
39
40
|
|
|
40
41
|
cleanup?.()
|
|
@@ -29,15 +29,14 @@ export interface PerspectiveHandle {
|
|
|
29
29
|
* @public
|
|
30
30
|
*/
|
|
31
31
|
export interface DatasetHandle<TDataset extends string = string, TProjectId extends string = string>
|
|
32
|
-
extends ProjectHandle<TProjectId>,
|
|
33
|
-
PerspectiveHandle {
|
|
32
|
+
extends ProjectHandle<TProjectId>, PerspectiveHandle {
|
|
34
33
|
dataset?: TDataset
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
/**
|
|
38
37
|
* Identifies a specific document type within a Sanity dataset and project.
|
|
39
38
|
* Includes `projectId`, `dataset`, and `documentType`.
|
|
40
|
-
* Optionally includes a `documentId
|
|
39
|
+
* Optionally includes a `documentId` and `liveEdit` flag.
|
|
41
40
|
* @public
|
|
42
41
|
*/
|
|
43
42
|
export interface DocumentTypeHandle<
|
|
@@ -47,6 +46,12 @@ export interface DocumentTypeHandle<
|
|
|
47
46
|
> extends DatasetHandle<TDataset, TProjectId> {
|
|
48
47
|
documentId?: string
|
|
49
48
|
documentType: TDocumentType
|
|
49
|
+
/**
|
|
50
|
+
* Indicates whether this document uses liveEdit mode.
|
|
51
|
+
* When `true`, the document does not use the draft/published model and edits are applied directly to the document.
|
|
52
|
+
* @see https://www.sanity.io/docs/content-lake/drafts#ca0663a8f002
|
|
53
|
+
*/
|
|
54
|
+
liveEdit?: boolean
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
/**
|