@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.
Files changed (127) hide show
  1. package/dist/index.d.ts +428 -325
  2. package/dist/index.js +1618 -1553
  3. package/dist/index.js.map +1 -1
  4. package/package.json +6 -7
  5. package/src/_exports/index.ts +31 -30
  6. package/src/auth/authStore.test.ts +149 -104
  7. package/src/auth/authStore.ts +51 -100
  8. package/src/auth/handleAuthCallback.test.ts +67 -34
  9. package/src/auth/handleAuthCallback.ts +8 -7
  10. package/src/auth/logout.test.ts +61 -29
  11. package/src/auth/logout.ts +26 -28
  12. package/src/auth/refreshStampedToken.test.ts +9 -9
  13. package/src/auth/refreshStampedToken.ts +62 -56
  14. package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +5 -5
  15. package/src/auth/subscribeToStateAndFetchCurrentUser.ts +45 -47
  16. package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +4 -5
  17. package/src/auth/subscribeToStorageEventsAndSetToken.ts +22 -24
  18. package/src/client/clientStore.test.ts +131 -67
  19. package/src/client/clientStore.ts +117 -116
  20. package/src/comlink/controller/actions/destroyController.test.ts +38 -13
  21. package/src/comlink/controller/actions/destroyController.ts +11 -15
  22. package/src/comlink/controller/actions/getOrCreateChannel.test.ts +56 -27
  23. package/src/comlink/controller/actions/getOrCreateChannel.ts +37 -35
  24. package/src/comlink/controller/actions/getOrCreateController.test.ts +27 -16
  25. package/src/comlink/controller/actions/getOrCreateController.ts +23 -22
  26. package/src/comlink/controller/actions/releaseChannel.test.ts +37 -13
  27. package/src/comlink/controller/actions/releaseChannel.ts +22 -21
  28. package/src/comlink/controller/comlinkControllerStore.test.ts +65 -36
  29. package/src/comlink/controller/comlinkControllerStore.ts +44 -5
  30. package/src/comlink/node/actions/getOrCreateNode.test.ts +31 -15
  31. package/src/comlink/node/actions/getOrCreateNode.ts +30 -29
  32. package/src/comlink/node/actions/releaseNode.test.ts +75 -55
  33. package/src/comlink/node/actions/releaseNode.ts +19 -21
  34. package/src/comlink/node/comlinkNodeStore.test.ts +6 -11
  35. package/src/comlink/node/comlinkNodeStore.ts +22 -5
  36. package/src/config/authConfig.ts +79 -0
  37. package/src/config/sanityConfig.ts +48 -0
  38. package/src/datasets/datasets.test.ts +2 -2
  39. package/src/datasets/datasets.ts +18 -5
  40. package/src/document/actions.test.ts +22 -10
  41. package/src/document/actions.ts +44 -56
  42. package/src/document/applyDocumentActions.test.ts +96 -36
  43. package/src/document/applyDocumentActions.ts +140 -99
  44. package/src/document/documentStore.test.ts +103 -155
  45. package/src/document/documentStore.ts +247 -237
  46. package/src/document/listen.ts +56 -55
  47. package/src/document/patchOperations.ts +0 -43
  48. package/src/document/permissions.test.ts +25 -12
  49. package/src/document/permissions.ts +11 -4
  50. package/src/document/processActions.test.ts +41 -8
  51. package/src/document/reducers.test.ts +87 -16
  52. package/src/document/reducers.ts +2 -2
  53. package/src/document/sharedListener.test.ts +34 -16
  54. package/src/document/sharedListener.ts +33 -11
  55. package/src/preview/getPreviewState.test.ts +40 -39
  56. package/src/preview/getPreviewState.ts +68 -56
  57. package/src/preview/previewConstants.ts +43 -0
  58. package/src/preview/previewQuery.test.ts +1 -1
  59. package/src/preview/previewQuery.ts +4 -5
  60. package/src/preview/previewStore.test.ts +13 -58
  61. package/src/preview/previewStore.ts +7 -21
  62. package/src/preview/resolvePreview.test.ts +33 -104
  63. package/src/preview/resolvePreview.ts +11 -21
  64. package/src/preview/subscribeToStateAndFetchBatches.test.ts +96 -97
  65. package/src/preview/subscribeToStateAndFetchBatches.ts +85 -81
  66. package/src/preview/util.ts +1 -0
  67. package/src/project/project.test.ts +3 -3
  68. package/src/project/project.ts +28 -5
  69. package/src/projection/getProjectionState.test.ts +69 -49
  70. package/src/projection/getProjectionState.ts +42 -50
  71. package/src/projection/projectionQuery.ts +1 -1
  72. package/src/projection/projectionStore.test.ts +13 -51
  73. package/src/projection/projectionStore.ts +6 -18
  74. package/src/projection/resolveProjection.test.ts +32 -127
  75. package/src/projection/resolveProjection.ts +15 -28
  76. package/src/projection/subscribeToStateAndFetchBatches.test.ts +105 -90
  77. package/src/projection/subscribeToStateAndFetchBatches.ts +94 -81
  78. package/src/projection/util.ts +2 -0
  79. package/src/projects/projects.test.ts +13 -4
  80. package/src/projects/projects.ts +6 -1
  81. package/src/query/queryStore.test.ts +10 -47
  82. package/src/query/queryStore.ts +151 -133
  83. package/src/query/queryStoreConstants.ts +2 -0
  84. package/src/store/createActionBinder.test.ts +153 -0
  85. package/src/store/createActionBinder.ts +176 -0
  86. package/src/store/createSanityInstance.test.ts +84 -0
  87. package/src/store/createSanityInstance.ts +124 -0
  88. package/src/store/createStateSourceAction.test.ts +196 -0
  89. package/src/store/createStateSourceAction.ts +260 -0
  90. package/src/store/createStoreInstance.test.ts +81 -0
  91. package/src/store/createStoreInstance.ts +80 -0
  92. package/src/store/createStoreState.test.ts +85 -0
  93. package/src/store/createStoreState.ts +92 -0
  94. package/src/store/defineStore.test.ts +18 -0
  95. package/src/store/defineStore.ts +81 -0
  96. package/src/users/reducers.test.ts +318 -0
  97. package/src/users/reducers.ts +88 -0
  98. package/src/users/types.ts +46 -4
  99. package/src/users/usersConstants.ts +4 -0
  100. package/src/users/usersStore.test.ts +350 -223
  101. package/src/users/usersStore.ts +285 -149
  102. package/src/utils/createFetcherStore.test.ts +6 -7
  103. package/src/utils/createFetcherStore.ts +150 -153
  104. package/src/{common/util.test.ts → utils/hashString.test.ts} +1 -1
  105. package/src/auth/fetchLoginUrls.test.ts +0 -163
  106. package/src/auth/fetchLoginUrls.ts +0 -74
  107. package/src/common/createLiveEventSubscriber.test.ts +0 -121
  108. package/src/common/createLiveEventSubscriber.ts +0 -55
  109. package/src/common/types.ts +0 -4
  110. package/src/instance/identity.test.ts +0 -46
  111. package/src/instance/identity.ts +0 -29
  112. package/src/instance/sanityInstance.test.ts +0 -77
  113. package/src/instance/sanityInstance.ts +0 -57
  114. package/src/instance/types.ts +0 -37
  115. package/src/preview/getPreviewProjection.ts +0 -45
  116. package/src/resources/README.md +0 -370
  117. package/src/resources/createAction.test.ts +0 -101
  118. package/src/resources/createAction.ts +0 -44
  119. package/src/resources/createResource.test.ts +0 -112
  120. package/src/resources/createResource.ts +0 -102
  121. package/src/resources/createStateSourceAction.test.ts +0 -114
  122. package/src/resources/createStateSourceAction.ts +0 -83
  123. package/src/resources/createStore.test.ts +0 -67
  124. package/src/resources/createStore.ts +0 -46
  125. package/src/store/createStore.test.ts +0 -108
  126. package/src/store/createStore.ts +0 -106
  127. /package/src/{common/util.ts → utils/hashString.ts} +0 -0
@@ -1,179 +1,315 @@
1
1
  import {createSelector} from 'reselect'
2
+ import {
3
+ catchError,
4
+ combineLatest,
5
+ distinctUntilChanged,
6
+ EMPTY,
7
+ filter,
8
+ first,
9
+ firstValueFrom,
10
+ groupBy,
11
+ map,
12
+ mergeMap,
13
+ NEVER,
14
+ Observable,
15
+ of,
16
+ pairwise,
17
+ race,
18
+ skip,
19
+ startWith,
20
+ switchMap,
21
+ tap,
22
+ throwError,
23
+ withLatestFrom,
24
+ } from 'rxjs'
2
25
 
3
- import {getClient} from '../client/clientStore'
4
- import {type SanityInstance} from '../instance/types'
5
- import {createAction} from '../resources/createAction'
6
- import {createResource} from '../resources/createResource'
7
- import {createStateSourceAction} from '../resources/createStateSourceAction'
8
- import {createStore} from '../resources/createStore'
9
- import {type ResourceType, type SanityUser} from './types'
10
-
11
- const API_VERSION = 'vX'
26
+ import {getDashboardOrganizationId} from '../auth/authStore'
27
+ import {getClientState} from '../client/clientStore'
28
+ import {bindActionGlobally} from '../store/createActionBinder'
29
+ import {createStateSourceAction, type SelectorContext} from '../store/createStateSourceAction'
30
+ import {type StoreState} from '../store/createStoreState'
31
+ import {defineStore, type StoreContext} from '../store/defineStore'
32
+ import {insecureRandomId} from '../utils/ids'
33
+ import {
34
+ addSubscription,
35
+ cancelRequest,
36
+ getUsersKey,
37
+ initializeRequest,
38
+ parseUsersKey,
39
+ removeSubscription,
40
+ setUsersData,
41
+ setUsersError,
42
+ updateLastLoadMoreRequest,
43
+ } from './reducers'
44
+ import {
45
+ type GetUsersOptions,
46
+ type ResolveUsersOptions,
47
+ type SanityUserResponse,
48
+ type UsersStoreState,
49
+ } from './types'
50
+ import {API_VERSION, USERS_STATE_CLEAR_DELAY} from './usersConstants'
12
51
 
13
52
  /**
14
- * @public
53
+ * The users store resource that manages user data fetching and state.
54
+ *
55
+ * This store handles fetching, caching, and managing user data. It provides functionality for
56
+ * retrieving users associated with specific resources and supports pagination through the
57
+ * `loadMoreUsers` action.
58
+ *
59
+ * @internal
15
60
  */
16
- export interface SanityUserResponse {
17
- data: SanityUser[]
18
- totalCount: number
19
- nextCursor: string | null
20
- }
61
+ const usersStore = defineStore<UsersStoreState>({
62
+ name: 'UsersStore',
63
+ getInitialState: () => ({users: {}}),
64
+ initialize: (context) => {
65
+ const subscription = listenForLoadMoreAndFetch(context)
66
+ return () => subscription.unsubscribe()
67
+ },
68
+ })
69
+
70
+ const errorHandler =
71
+ (state: StoreState<{error?: unknown}>) =>
72
+ (error: unknown): void =>
73
+ state.set('setError', {error})
21
74
 
22
75
  /**
23
- * @public
76
+ * Internal action that listens for new user subscriptions and load more requests.
77
+ * Fetches user data when new subscriptions are added or when loadMoreUsers is called.
24
78
  */
25
- export interface UsersStoreState {
26
- users: SanityUser[]
27
- totalCount: number
28
- nextCursor: string | null
29
- hasMore: boolean
30
- initialFetchCompleted: boolean
31
- options: {
32
- resourceType: ResourceType
33
- resourceId: string
34
- /**
35
- * The maximum number of users to fetch. [Default: 100]
36
- */
37
- limit?: number
38
- }
79
+ const listenForLoadMoreAndFetch = ({state, instance}: StoreContext<UsersStoreState>) => {
80
+ return state.observable
81
+ .pipe(
82
+ map((s) => new Set(Object.keys(s.users))),
83
+ distinctUntilChanged((curr, next) => {
84
+ if (curr.size !== next.size) return false
85
+ return Array.from(next).every((i) => curr.has(i))
86
+ }),
87
+ startWith(new Set<string>()),
88
+ pairwise(),
89
+ mergeMap(([curr, next]) => {
90
+ const added = Array.from(next).filter((i) => !curr.has(i))
91
+ const removed = Array.from(curr).filter((i) => !next.has(i))
92
+
93
+ return [
94
+ ...added.map((key) => ({key, added: true})),
95
+ ...removed.map((key) => ({key, added: false})),
96
+ ]
97
+ }),
98
+ groupBy((i) => i.key),
99
+ mergeMap((group$) =>
100
+ group$.pipe(
101
+ switchMap((e) => {
102
+ if (!e.added) return EMPTY
103
+ const {batchSize, ...options} = parseUsersKey(group$.key)
104
+
105
+ const projectId = options.projectId ?? instance.config.projectId
106
+
107
+ // the resource type this request will use
108
+ // If resourceType is explicitly provided, use it
109
+ // Otherwise, infer from context: organization if organizationId exists,
110
+ // project if projectId exists, or default to organization
111
+ const resourceType =
112
+ options.resourceType ??
113
+ (options.organizationId ? 'organization' : projectId ? 'project' : 'organization')
114
+
115
+ const organizationId$ = options.organizationId
116
+ ? of(options.organizationId)
117
+ : getDashboardOrganizationId(instance).observable.pipe(
118
+ filter((i) => typeof i === 'string'),
119
+ )
120
+
121
+ const resource$: Observable<{
122
+ type: 'project' | 'organization'
123
+ id: string
124
+ }> =
125
+ resourceType === 'project'
126
+ ? projectId
127
+ ? of({type: 'project', id: projectId})
128
+ : throwError(() => new Error('Project ID required for this API.'))
129
+ : organizationId$.pipe(map((id) => ({type: 'organization', id})))
130
+
131
+ const client$ = getClientState(instance, {
132
+ scope: 'global',
133
+ apiVersion: API_VERSION,
134
+ }).observable
135
+
136
+ const loadMore$ = state.observable.pipe(
137
+ map((s) => s.users[group$.key]?.lastLoadMoreRequest),
138
+ distinctUntilChanged(),
139
+ )
140
+
141
+ const cursor$ = state.observable.pipe(
142
+ map((s) => s.users[group$.key]?.nextCursor),
143
+ distinctUntilChanged(),
144
+ filter((cursor) => cursor !== null),
145
+ )
146
+
147
+ return combineLatest([resource$, client$, loadMore$]).pipe(
148
+ withLatestFrom(cursor$),
149
+ switchMap(([[resource, client], cursor]) =>
150
+ client.observable.request<SanityUserResponse>({
151
+ method: 'GET',
152
+ uri: `access/${resource.type}/${resource.id}/users`,
153
+ query: cursor
154
+ ? {nextCursor: cursor, limit: batchSize.toString()}
155
+ : {limit: batchSize.toString()},
156
+ }),
157
+ ),
158
+ catchError((error) => {
159
+ state.set('setUsersError', setUsersError(group$.key, error))
160
+ return EMPTY
161
+ }),
162
+ tap((response) => state.set('setUsersData', setUsersData(group$.key, response))),
163
+ )
164
+ }),
165
+ ),
166
+ ),
167
+ )
168
+ .subscribe({error: errorHandler(state)})
39
169
  }
40
170
 
41
171
  /**
42
- * @internal
172
+ * Returns the state source for users associated with a specific resource.
173
+ *
174
+ * This function returns a state source that represents the current list of users for a given
175
+ * resource. Subscribing to the state source will instruct the SDK to fetch the users (if not
176
+ * already fetched) and will load more from this state source as well. When the last subscriber is
177
+ * removed, the users state is automatically cleaned up from the store after a delay.
178
+ *
179
+ * Note: This functionality is for advanced users who want to build their own framework
180
+ * integrations. Our SDK also provides a React integration for convenient usage.
181
+ *
182
+ * @beta
43
183
  */
44
- const usersStore = createResource<UsersStoreState>({
45
- name: 'users',
46
- getInitialState: () => ({
47
- users: [],
48
- totalCount: 0,
49
- nextCursor: null,
50
- hasMore: false,
51
- initialFetchCompleted: false,
52
- options: {
53
- resourceType: '' as ResourceType,
54
- resourceId: '',
55
- limit: 100,
184
+ export const getUsersState = bindActionGlobally(
185
+ usersStore,
186
+ createStateSourceAction({
187
+ selector: createSelector(
188
+ [
189
+ ({instance, state}: SelectorContext<UsersStoreState>, options?: GetUsersOptions) =>
190
+ state.error ?? state.users[getUsersKey(instance, options)]?.error,
191
+ ({instance, state}: SelectorContext<UsersStoreState>, options: GetUsersOptions) =>
192
+ state.users[getUsersKey(instance, options)]?.users,
193
+ ({instance, state}: SelectorContext<UsersStoreState>, options: GetUsersOptions) =>
194
+ state.users[getUsersKey(instance, options)]?.totalCount,
195
+ ({instance, state}: SelectorContext<UsersStoreState>, options: GetUsersOptions) =>
196
+ state.users[getUsersKey(instance, options)]?.nextCursor,
197
+ ],
198
+ (error, data, totalCount, nextCursor) => {
199
+ if (error) throw error
200
+ if (data === undefined || totalCount === undefined || nextCursor === undefined) {
201
+ return undefined
202
+ }
203
+
204
+ return {data, totalCount, hasMore: nextCursor !== null}
205
+ },
206
+ ),
207
+ onSubscribe: ({instance, state}, options?: GetUsersOptions) => {
208
+ const subscriptionId = insecureRandomId()
209
+ const key = getUsersKey(instance, options)
210
+ state.set('addSubscription', addSubscription(subscriptionId, key))
211
+ return () => {
212
+ setTimeout(
213
+ () => state.set('removeSubscription', removeSubscription(subscriptionId, key)),
214
+ USERS_STATE_CLEAR_DELAY,
215
+ )
216
+ }
56
217
  },
57
218
  }),
58
- initialize() {
59
- return () => {}
60
- },
61
- })
62
-
63
- /**
64
- * @public
65
- */
66
- const getState = createStateSourceAction(
67
- usersStore,
68
- createSelector(
69
- [
70
- (state: UsersStoreState) => state.users,
71
- (state: UsersStoreState) => state.totalCount,
72
- (state: UsersStoreState) => state.nextCursor,
73
- (state: UsersStoreState) => state.hasMore,
74
- (state: UsersStoreState) => state.initialFetchCompleted,
75
- (state: UsersStoreState) => state.options,
76
- ],
77
- (users, totalCount, nextCursor, hasMore, initialFetchCompleted, options) => ({
78
- users,
79
- totalCount,
80
- nextCursor,
81
- hasMore,
82
- options,
83
- initialFetchCompleted,
84
- }),
85
- ),
86
219
  )
87
220
 
88
- interface FetchUsersParams {
89
- resourceType: 'organization' | 'project'
90
- resourceId: string
91
- nextCursor?: string | null
92
- limit?: number
93
- }
94
-
95
221
  /**
96
- * @internal
222
+ * Resolves the users for a specific resource without registering a lasting subscriber.
223
+ *
224
+ * This function fetches the users for a given resource and returns a promise that resolves with
225
+ * the users result. Unlike `getUsersState`, which registers subscribers to keep the data live and
226
+ * performs automatic cleanup, `resolveUsers` does not track subscribers. This makes it ideal for
227
+ * use with React Suspense, where the returned promise is thrown to delay rendering until the users
228
+ * result becomes available. Once the promise resolves, it is expected that a real subscriber will
229
+ * be added via `getUsersState` to manage ongoing updates.
230
+ *
231
+ * Additionally, an optional AbortSignal can be provided to cancel the request and immediately
232
+ * clear the associated state if there are no active subscribers.
233
+ *
234
+ * @beta
97
235
  */
98
- const fetchUsers = (instance: SanityInstance, params: FetchUsersParams) => {
99
- const {resourceType, resourceId, nextCursor, limit = 100} = params
100
- const client = getClient(instance, {scope: 'global', apiVersion: API_VERSION})
101
-
102
- return client.request<SanityUserResponse>({
103
- method: 'GET',
104
- uri: `access/${resourceType}/${resourceId}/users`,
105
- query: nextCursor ? {nextCursor, limit: limit.toString()} : {limit: limit.toString()},
106
- tag: 'users',
107
- })
108
- }
236
+ export const resolveUsers = bindActionGlobally(
237
+ usersStore,
238
+ async ({state, instance}, {signal, ...options}: ResolveUsersOptions) => {
239
+ const key = getUsersKey(instance, options)
240
+ const {getCurrent} = getUsersState(instance, options)
109
241
 
110
- const loadMore = createAction(usersStore, ({state, instance}) => {
111
- return async function () {
112
- const {users, nextCursor, options} = state.get()
113
- const {resourceType, resourceId, limit} = options
242
+ const aborted$ = signal
243
+ ? new Observable<never>((observer) => {
244
+ const cleanup = () => {
245
+ signal.removeEventListener('abort', listener)
246
+ }
114
247
 
115
- if (!resourceType || !resourceId) {
116
- throw new Error('Resource type and ID are required to load more users')
117
- }
248
+ const listener = () => {
249
+ observer.error(new DOMException('The operation was aborted.', 'AbortError'))
250
+ observer.complete()
251
+ cleanup()
252
+ }
253
+ signal.addEventListener('abort', listener)
118
254
 
119
- const response = await fetchUsers(instance, {resourceType, resourceId, nextCursor, limit})
255
+ return cleanup
256
+ }).pipe(
257
+ catchError((error) => {
258
+ if (error instanceof Error && error.name === 'AbortError') {
259
+ state.set('cancelRequest', cancelRequest(key))
260
+ }
261
+ throw error
262
+ }),
263
+ )
264
+ : NEVER
120
265
 
121
- const allUsers = [...users, ...response.data]
122
- const hasMore = allUsers.length < response.totalCount
266
+ state.set('initializeRequest', initializeRequest(key))
123
267
 
124
- state.set('loadMore', {
125
- users: allUsers,
126
- totalCount: response.totalCount,
127
- nextCursor: response.nextCursor,
128
- hasMore,
129
- })
130
- }
131
- })
268
+ const resolved$ = state.observable.pipe(
269
+ map(getCurrent),
270
+ first((i) => i !== undefined),
271
+ )
132
272
 
133
- const resolveUsers = createAction(usersStore, ({state, instance}) => {
134
- return async function () {
135
- const {options} = state.get()
136
- const {resourceType, resourceId, limit} = options
273
+ return firstValueFrom(race([resolved$, aborted$]))
274
+ },
275
+ )
137
276
 
138
- if (!resourceType || !resourceId) {
139
- throw new Error('Resource type and ID are required to resolve users')
277
+ /**
278
+ * Loads more users for a specific resource.
279
+ *
280
+ * This function triggers a request to fetch the next page of users for a given resource. It
281
+ * requires that users have already been loaded for the resource (via `resolveUsers` or
282
+ * `getUsersState`), and that there are more users available to load (as indicated by the `hasMore`
283
+ * property).
284
+ *
285
+ * The function returns a promise that resolves when the next page of users has been loaded.
286
+ *
287
+ * @beta
288
+ */
289
+ export const loadMoreUsers = bindActionGlobally(
290
+ usersStore,
291
+ async ({state, instance}, options?: GetUsersOptions) => {
292
+ const key = getUsersKey(instance, options)
293
+ const users = getUsersState(instance, options)
294
+ const usersState = users.getCurrent()
295
+ if (!usersState) {
296
+ throw new Error('Users not loaded for specified resource. Please call resolveUsers first.')
140
297
  }
141
298
 
142
- const response = await fetchUsers(instance, {resourceType, resourceId, limit})
143
-
144
- const hasMore = response.data.length < response.totalCount
145
-
146
- state.set('resolveUsers', {
147
- users: response.data,
148
- totalCount: response.totalCount,
149
- nextCursor: response.nextCursor,
150
- hasMore,
151
- initialFetchCompleted: true,
152
- })
299
+ if (!usersState.hasMore) {
300
+ throw new Error('No more users available to load for this resource.')
301
+ }
153
302
 
154
- return response
155
- }
156
- })
303
+ const promise = firstValueFrom(
304
+ users.observable.pipe(
305
+ filter((i) => i !== undefined),
306
+ skip(1),
307
+ ),
308
+ )
157
309
 
158
- const setOptions = createAction(usersStore, ({state}) => {
159
- return function (options: {resourceType: 'organization' | 'project'; resourceId: string}) {
160
- state.set('options', {
161
- ...state.get(),
162
- options: {
163
- ...state.get().options,
164
- resourceType: options.resourceType,
165
- resourceId: options.resourceId,
166
- },
167
- })
168
- }
169
- })
310
+ const timestamp = new Date().toISOString()
311
+ state.set('updateLastLoadMoreRequest', updateLastLoadMoreRequest(timestamp, key))
170
312
 
171
- /**
172
- * @public
173
- */
174
- export const createUsersStore = createStore(usersStore, {
175
- getState,
176
- loadMore,
177
- resolveUsers,
178
- setOptions,
179
- })
313
+ return await promise
314
+ },
315
+ )
@@ -2,8 +2,7 @@ import {delay, firstValueFrom, of, throwError} from 'rxjs'
2
2
  import {filter, skip} from 'rxjs/operators'
3
3
  import {beforeEach, describe, expect, it, vi} from 'vitest'
4
4
 
5
- import {createSanityInstance} from '../instance/sanityInstance'
6
- import {type SanityInstance} from '../instance/types'
5
+ import {createSanityInstance, type SanityInstance} from '../store/createSanityInstance'
7
6
  import {createFetcherStore} from './createFetcherStore'
8
7
 
9
8
  describe('createFetcherStore', () => {
@@ -22,7 +21,7 @@ describe('createFetcherStore', () => {
22
21
  const store = createFetcherStore({
23
22
  name: 'test',
24
23
  fetcher: () => (param: number) => of(`data-${param}`).pipe(delay(100)),
25
- getKey: (param: number) => `key-${param}`,
24
+ getKey: (_instance, param: number) => `key-${param}`,
26
25
  })
27
26
 
28
27
  const stateSource = store.getState(instance, 1)
@@ -44,7 +43,7 @@ describe('createFetcherStore', () => {
44
43
  const store = createFetcherStore({
45
44
  name: 'test-throttle',
46
45
  fetcher: () => fetchSpy,
47
- getKey: (param: number) => `key-${param}`,
46
+ getKey: (_instance, param: number) => `key-${param}`,
48
47
  fetchThrottleInternal: 1000,
49
48
  })
50
49
 
@@ -85,7 +84,7 @@ describe('createFetcherStore', () => {
85
84
  const store = createFetcherStore({
86
85
  name: 'test-expiration',
87
86
  fetcher: () => fetchSpy,
88
- getKey: (param: number) => `key-${param}`,
87
+ getKey: (_instance, param: number) => `key-${param}`,
89
88
  stateExpirationDelay: 1000,
90
89
  })
91
90
 
@@ -116,7 +115,7 @@ describe('createFetcherStore', () => {
116
115
  const store = createFetcherStore({
117
116
  name: 'test-throttle',
118
117
  fetcher: () => fetchSpy,
119
- getKey: (param: number) => `key-${param}`,
118
+ getKey: (_instance, param: number) => `key-${param}`,
120
119
  fetchThrottleInternal: 1000,
121
120
  })
122
121
 
@@ -151,7 +150,7 @@ describe('createFetcherStore', () => {
151
150
  const store = createFetcherStore({
152
151
  name: 'test-params',
153
152
  fetcher: () => (param: number) => of(`data-${param}`),
154
- getKey: (param: number) => `key-${param}`,
153
+ getKey: (_instance, param: number) => `key-${param}`,
155
154
  })
156
155
 
157
156
  const stateSource1 = store.getState(instance, 1)