@sanity/sdk 2.1.0 → 2.1.1

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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createClient } from "@sanity/client";
2
- import { Observable, share, map, distinctUntilChanged, skip, filter, exhaustMap, timer, from, takeWhile, switchMap, firstValueFrom, fromEvent, EMPTY, defer, asapScheduler, combineLatest, of, concatMap, withLatestFrom, concat, throwError, first as first$1, Subject, takeUntil, partition, merge, shareReplay, tap as tap$1, catchError as catchError$1, startWith as startWith$1, pairwise as pairwise$1, groupBy as groupBy$1, mergeMap as mergeMap$1, throttle, race, retry, NEVER, debounceTime as debounceTime$1, Subscription } from "rxjs";
2
+ import { Observable, share, map, distinctUntilChanged, skip, filter, exhaustMap, from, timer, switchMap, takeWhile, firstValueFrom, fromEvent, EMPTY, defer, asapScheduler, combineLatest, of, concatMap, withLatestFrom, concat, throwError, first as first$1, Subject, takeUntil, partition, merge, shareReplay, tap as tap$1, catchError as catchError$1, startWith as startWith$1, pairwise as pairwise$1, groupBy as groupBy$1, mergeMap as mergeMap$1, throttle, race, NEVER, Subscription, retry, debounceTime as debounceTime$1 } from "rxjs";
3
3
  import { devtools } from "zustand/middleware";
4
4
  import { createStore } from "zustand/vanilla";
5
5
  import { pick, omit, isEqual, isObject } from "lodash-es";
@@ -15,6 +15,7 @@ import { applyPatches, parsePatch } from "@sanity/diff-match-patch";
15
15
  import { isKeySegment, isKeyedObject } from "@sanity/types";
16
16
  import { createDocumentLoaderFromClient } from "@sanity/mutate/_unstable_store";
17
17
  import { SDK_CHANNEL_NAME, SDK_NODE_NAME } from "@sanity/message-protocol";
18
+ import { fromUrl } from "@sanity/bifur-client";
18
19
  var AuthStateType = /* @__PURE__ */ ((AuthStateType2) => (AuthStateType2.LOGGED_IN = "logged-in", AuthStateType2.LOGGING_IN = "logging-in", AuthStateType2.ERROR = "error", AuthStateType2.LOGGED_OUT = "logged-out", AuthStateType2))(AuthStateType || {});
19
20
  function getPublishedId(id) {
20
21
  const draftsPrefix = "drafts.";
@@ -86,8 +87,8 @@ function createStoreState(initialState, devToolsOptions) {
86
87
  })
87
88
  };
88
89
  }
89
- function createStoreInstance(instance, { name, getInitialState, initialize }) {
90
- const state = createStoreState(getInitialState(instance), {
90
+ function createStoreInstance(instance, { name, getInitialState: getInitialState2, initialize }) {
91
+ const state = createStoreState(getInitialState2(instance), {
91
92
  enabled: !!getEnv("DEV"),
92
93
  name: `${name}-${instance.config.projectId}.${instance.config.dataset}`
93
94
  }), dispose = initialize?.({ state, instance }), disposed = { current: !1 };
@@ -168,8 +169,8 @@ function createStateSourceAction(options) {
168
169
  const DEFAULT_BASE = "http://localhost", AUTH_CODE_PARAM = "sid", DEFAULT_API_VERSION$1 = "2021-06-07", REQUEST_TAG_PREFIX = "sanity.sdk.auth", REFRESH_INTERVAL = 12 * 60 * 60 * 1e3, LOCK_NAME = "sanity-token-refresh-lock";
169
170
  function getLastRefreshTime(storageArea, storageKey) {
170
171
  try {
171
- const data = storageArea?.getItem(`${storageKey}_last_refresh`);
172
- return data ? parseInt(data, 10) : 0;
172
+ const data = storageArea?.getItem(`${storageKey}_last_refresh`), parsed = data ? parseInt(data, 10) : 0;
173
+ return isNaN(parsed) ? 0 : parsed;
173
174
  } catch {
174
175
  return 0;
175
176
  }
@@ -227,6 +228,9 @@ async function acquireTokenRefreshLock(refreshFn, storageArea, storageKey) {
227
228
  return console.error("Failed to request token refresh lock:", error), !1;
228
229
  }
229
230
  }
231
+ function shouldRefreshToken(lastRefresh) {
232
+ return lastRefresh ? Date.now() - lastRefresh >= REFRESH_INTERVAL : !0;
233
+ }
230
234
  const refreshStampedToken = ({ state }) => {
231
235
  const { clientFactory, apiHost, storageArea, storageKey } = state.get().options;
232
236
  return state.observable.pipe(
@@ -256,26 +260,69 @@ const refreshStampedToken = ({ state }) => {
256
260
  authState: prev.authState.type === AuthStateType.LOGGED_IN ? { ...prev.authState, token: response.token } : prev.authState
257
261
  })), storageArea?.setItem(storageKey, JSON.stringify({ token: response.token }));
258
262
  };
259
- return storeState.dashboardContext ? timer(REFRESH_INTERVAL, REFRESH_INTERVAL).pipe(
260
- // Check if still logged in before each refresh attempt in the timer
263
+ return storeState.dashboardContext ? new Observable((subscriber) => {
264
+ const visibilityHandler = () => {
265
+ const currentState = state.get();
266
+ document.visibilityState === "visible" && currentState.authState.type === AuthStateType.LOGGED_IN && shouldRefreshToken(currentState.authState.lastTokenRefresh) && createTokenRefreshStream(
267
+ currentState.authState.token,
268
+ clientFactory,
269
+ apiHost
270
+ ).subscribe({
271
+ next: (response) => {
272
+ state.set("setRefreshStampedToken", (prev) => ({
273
+ authState: prev.authState.type === AuthStateType.LOGGED_IN ? {
274
+ ...prev.authState,
275
+ token: response.token,
276
+ lastTokenRefresh: Date.now()
277
+ } : prev.authState
278
+ })), subscriber.next(response);
279
+ },
280
+ error: (error) => subscriber.error(error)
281
+ });
282
+ }, timerSubscription = timer(REFRESH_INTERVAL, REFRESH_INTERVAL).pipe(
283
+ filter(() => document.visibilityState === "visible"),
284
+ switchMap(() => {
285
+ const currentState = state.get().authState;
286
+ if (currentState.type !== AuthStateType.LOGGED_IN)
287
+ throw new Error("User logged out before refresh could complete");
288
+ return createTokenRefreshStream(currentState.token, clientFactory, apiHost);
289
+ })
290
+ ).subscribe({
291
+ next: (response) => {
292
+ state.set("setRefreshStampedToken", (prev) => ({
293
+ authState: prev.authState.type === AuthStateType.LOGGED_IN ? {
294
+ ...prev.authState,
295
+ token: response.token,
296
+ lastTokenRefresh: Date.now()
297
+ } : prev.authState
298
+ })), subscriber.next(response);
299
+ },
300
+ error: (error) => subscriber.error(error)
301
+ });
302
+ return document.addEventListener("visibilitychange", visibilityHandler), () => {
303
+ document.removeEventListener("visibilitychange", visibilityHandler), timerSubscription.unsubscribe();
304
+ };
305
+ }).pipe(
261
306
  takeWhile(() => state.get().authState.type === AuthStateType.LOGGED_IN),
262
- // Use switchMap here: if the timer ticks again, we *do* want the latest token request
263
- switchMap(
264
- () => createTokenRefreshStream(storeState.authState.token, clientFactory, apiHost)
265
- ),
266
- // Map the successful response for the outer subscribe block
267
307
  map((response) => ({ token: response.token }))
268
308
  ) : from(acquireTokenRefreshLock(performRefresh, storageArea, storageKey)).pipe(
269
309
  filter((hasLock) => hasLock),
270
- // If acquireTokenRefreshLock *does* somehow resolve true (e.g., locks unsupported),
271
- // emit the token that triggered this exhaustMap execution.
272
- map(() => ({ token: storeState.authState.token }))
310
+ map(() => {
311
+ const currentState = state.get().authState;
312
+ if (currentState.type !== AuthStateType.LOGGED_IN)
313
+ throw new Error("User logged out before refresh could complete");
314
+ return { token: currentState.token };
315
+ })
273
316
  );
274
317
  })
275
318
  ).subscribe({
276
319
  next: (response) => {
277
320
  state.set("setRefreshStampedToken", (prev) => ({
278
- authState: prev.authState.type === AuthStateType.LOGGED_IN ? { ...prev.authState, token: response.token } : prev.authState
321
+ authState: prev.authState.type === AuthStateType.LOGGED_IN ? {
322
+ ...prev.authState,
323
+ token: response.token,
324
+ lastTokenRefresh: Date.now()
325
+ } : prev.authState
279
326
  })), storageArea?.setItem(storageKey, JSON.stringify({ token: response.token }));
280
327
  },
281
328
  error: (error) => {
@@ -1291,7 +1338,7 @@ function processMutations({
1291
1338
  throw new Error(
1292
1339
  `Cannot create document with \`_id\` \`${id}\` because another document with the same ID already exists.`
1293
1340
  );
1294
- const document = {
1341
+ const document2 = {
1295
1342
  // > `_createdAt` and `_updatedAt` may be submitted and will override
1296
1343
  // > the default which is of course the current time. This can be used
1297
1344
  // > to reconstruct a data-set with its timestamp structure intact.
@@ -1304,11 +1351,11 @@ function processMutations({
1304
1351
  _rev: transactionId,
1305
1352
  _id: id
1306
1353
  };
1307
- dataset[id] = document;
1354
+ dataset[id] = document2;
1308
1355
  continue;
1309
1356
  }
1310
1357
  if ("createOrReplace" in mutation) {
1311
- const id = getId(mutation.createOrReplace._id), prev = dataset[id], document = {
1358
+ const id = getId(mutation.createOrReplace._id), prev = dataset[id], document2 = {
1312
1359
  ...mutation.createOrReplace,
1313
1360
  // otherwise, if the mutation provided, a `_createdAt` time, use it,
1314
1361
  // otherwise default to now
@@ -1335,13 +1382,13 @@ function processMutations({
1335
1382
  _rev: transactionId,
1336
1383
  _id: id
1337
1384
  };
1338
- dataset[id] = document;
1385
+ dataset[id] = document2;
1339
1386
  continue;
1340
1387
  }
1341
1388
  if ("createIfNotExists" in mutation) {
1342
1389
  const id = getId(mutation.createIfNotExists._id);
1343
1390
  if (dataset[id]) continue;
1344
- const document = {
1391
+ const document2 = {
1345
1392
  // same logic as `create`:
1346
1393
  // prefer the user's `_createdAt` and `_updatedAt`
1347
1394
  _createdAt: now,
@@ -1350,7 +1397,7 @@ function processMutations({
1350
1397
  _rev: transactionId,
1351
1398
  _id: id
1352
1399
  };
1353
- dataset[id] = document;
1400
+ dataset[id] = document2;
1354
1401
  continue;
1355
1402
  }
1356
1403
  if ("delete" in mutation) {
@@ -1467,7 +1514,7 @@ const listen$1 = ({ state }, documentId) => {
1467
1514
  const { sharedListener, fetchDocument } = state.get();
1468
1515
  return sharedListener.events.pipe(
1469
1516
  concatMap((e3) => e3.type === "welcome" ? fetchDocument(documentId).pipe(
1470
- map((document) => ({ type: "sync", document }))
1517
+ map((document2) => ({ type: "sync", document: document2 }))
1471
1518
  ) : e3.type === "mutation" && e3.documentId === documentId ? of(e3) : EMPTY),
1472
1519
  sortListenerEvents(),
1473
1520
  withLatestFrom(
@@ -1486,7 +1533,7 @@ const listen$1 = ({ state }, documentId) => {
1486
1533
  revision: next.document?._rev,
1487
1534
  timestamp: next.document?._updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
1488
1535
  };
1489
- const [document] = Object.values(
1536
+ const [document2] = Object.values(
1490
1537
  processMutations({
1491
1538
  documents: { [documentId]: documentState.remote },
1492
1539
  mutations: next.mutations,
@@ -1497,7 +1544,7 @@ const listen$1 = ({ state }, documentId) => {
1497
1544
  return {
1498
1545
  type: "mutation",
1499
1546
  documentId,
1500
- document: document ?? null,
1547
+ document: document2 ?? null,
1501
1548
  revision: transactionId,
1502
1549
  timestamp,
1503
1550
  ...previousRev && { previousRev }
@@ -3279,8 +3326,8 @@ const documentsCache = new MultiKeyWeakMap(), actionsCache = /* @__PURE__ */ new
3279
3326
  return nestedCache.get(actionsKey) || (nestedCache.set(actionsKey, normalizedActions), normalizedActions);
3280
3327
  }
3281
3328
  );
3282
- function checkGrant$1(grantExpr, document) {
3283
- return C(grantExpr, { params: { document } }).get();
3329
+ function checkGrant$1(grantExpr, document2) {
3330
+ return C(grantExpr, { params: { document: document2 } }).get();
3284
3331
  }
3285
3332
  const enNarrowConjunction = new Intl.ListFormat("en", { style: "narrow", type: "conjunction" });
3286
3333
  function calculatePermissions(...args) {
@@ -3343,8 +3390,8 @@ const _calculatePermissions = createSelector(
3343
3390
  };
3344
3391
  }
3345
3392
  );
3346
- function checkGrant(grantExpr, document) {
3347
- return C(grantExpr, { params: { document } }).get();
3393
+ function checkGrant(grantExpr, document2) {
3394
+ return C(grantExpr, { params: { document: document2 } }).get();
3348
3395
  }
3349
3396
  class ActionError extends Error {
3350
3397
  documentId;
@@ -3782,7 +3829,7 @@ function revertOutgoingTransaction(prev) {
3782
3829
  )
3783
3830
  };
3784
3831
  }
3785
- function applyRemoteDocument(prev, { document, documentId, previousRev, revision, timestamp, type }, events) {
3832
+ function applyRemoteDocument(prev, { document: document2, documentId, previousRev, revision, timestamp, type }, events) {
3786
3833
  if (!prev.grants) return prev;
3787
3834
  const prevDocState = prev.documentStates[documentId];
3788
3835
  if (!prevDocState) return prev;
@@ -3797,13 +3844,13 @@ function applyRemoteDocument(prev, { document, documentId, previousRev, revision
3797
3844
  ...prev.documentStates,
3798
3845
  [documentId]: {
3799
3846
  ...prevDocState,
3800
- remote: document,
3847
+ remote: document2,
3801
3848
  remoteRev: revision,
3802
3849
  unverifiedRevisions
3803
3850
  }
3804
3851
  }
3805
3852
  };
3806
- let working = { ...prev.applied.at(0)?.previous, [documentId]: document };
3853
+ let working = { ...prev.applied.at(0)?.previous, [documentId]: document2 };
3807
3854
  const nextApplied = [];
3808
3855
  for (const curr of prev.applied)
3809
3856
  try {
@@ -3829,7 +3876,7 @@ function applyRemoteDocument(prev, { document, documentId, previousRev, revision
3829
3876
  ...prev.documentStates,
3830
3877
  [documentId]: {
3831
3878
  ...prevDocState,
3832
- remote: document,
3879
+ remote: document2,
3833
3880
  remoteRev: revision,
3834
3881
  local: working[documentId],
3835
3882
  unverifiedRevisions
@@ -4005,9 +4052,9 @@ const _getDocumentState = bindActionByDataset(
4005
4052
  if (error) throw error;
4006
4053
  const draftId = getDraftId(documentId), publishedId = getPublishedId$1(documentId), draft = documentStates[draftId]?.local, published = documentStates[publishedId]?.local;
4007
4054
  if (draft === void 0 || published === void 0) return;
4008
- const document = draft ?? published;
4009
- if (!path) return document;
4010
- const result = jsonMatch(document, path).next();
4055
+ const document2 = draft ?? published;
4056
+ if (!path) return document2;
4057
+ const result = jsonMatch(document2, path).next();
4011
4058
  if (result.done) return;
4012
4059
  const { value } = result.value;
4013
4060
  return value;
@@ -4291,7 +4338,356 @@ const favorites = createFetcherStore({
4291
4338
  })
4292
4339
  );
4293
4340
  }
4294
- }), getFavoritesState = favorites.getState, resolveFavoritesState = favorites.resolveState, fetch = (client, query, params, options) => defer(
4341
+ }), getFavoritesState = favorites.getState, resolveFavoritesState = favorites.resolveState, API_VERSION$1 = "vX", PROJECT_API_VERSION = "2025-07-18", USERS_STATE_CLEAR_DELAY = 5e3, DEFAULT_USERS_BATCH_SIZE = 100, getUsersKey = (instance, {
4342
+ resourceType,
4343
+ organizationId,
4344
+ batchSize = DEFAULT_USERS_BATCH_SIZE,
4345
+ projectId = instance.config.projectId,
4346
+ userId
4347
+ } = {}) => JSON.stringify({
4348
+ resourceType,
4349
+ organizationId,
4350
+ batchSize,
4351
+ projectId,
4352
+ userId
4353
+ }), parseUsersKey = (key) => JSON.parse(key), addSubscription = (subscriptionId, key) => (prev) => {
4354
+ const group = prev.users[key], subscriptions = [...group?.subscriptions ?? [], subscriptionId];
4355
+ return { ...prev, users: { ...prev.users, [key]: { ...group, subscriptions } } };
4356
+ }, removeSubscription = (subscriptionId, key) => (prev) => {
4357
+ const group = prev.users[key];
4358
+ if (!group) return prev;
4359
+ const subscriptions = group.subscriptions.filter((id) => id !== subscriptionId);
4360
+ return subscriptions.length ? { ...prev, users: { ...prev.users, [key]: { ...group, subscriptions } } } : { ...prev, users: omit(prev.users, key) };
4361
+ }, setUsersData = (key, { data, nextCursor, totalCount }) => (prev) => {
4362
+ const group = prev.users[key];
4363
+ if (!group) return prev;
4364
+ const users = [...group.users ?? [], ...data];
4365
+ return { ...prev, users: { ...prev.users, [key]: { ...group, users, totalCount, nextCursor } } };
4366
+ }, updateLastLoadMoreRequest = (timestamp, key) => (prev) => {
4367
+ const group = prev.users[key];
4368
+ return group ? { ...prev, users: { ...prev.users, [key]: { ...group, lastLoadMoreRequest: timestamp } } } : prev;
4369
+ }, setUsersError = (key, error) => (prev) => {
4370
+ const group = prev.users[key];
4371
+ return group ? { ...prev, users: { ...prev.users, [key]: { ...group, error } } } : prev;
4372
+ }, cancelRequest = (key) => (prev) => {
4373
+ const group = prev.users[key];
4374
+ return !group || group.subscriptions.length ? prev : { ...prev, users: omit(prev.users, key) };
4375
+ }, initializeRequest = (key) => (prev) => prev.users[key] ? prev : { ...prev, users: { ...prev.users, [key]: { subscriptions: [] } } }, usersStore = {
4376
+ name: "UsersStore",
4377
+ getInitialState: () => ({ users: {} }),
4378
+ initialize: (context) => {
4379
+ const subscription = listenForLoadMoreAndFetch(context);
4380
+ return () => subscription.unsubscribe();
4381
+ }
4382
+ }, errorHandler$1 = (state) => (error) => state.set("setError", { error }), listenForLoadMoreAndFetch = ({ state, instance }) => state.observable.pipe(
4383
+ map((s2) => new Set(Object.keys(s2.users))),
4384
+ distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i2) => curr.has(i2))),
4385
+ startWith$1(/* @__PURE__ */ new Set()),
4386
+ pairwise$1(),
4387
+ mergeMap$1(([curr, next]) => {
4388
+ const added = Array.from(next).filter((i2) => !curr.has(i2)), removed = Array.from(curr).filter((i2) => !next.has(i2));
4389
+ return [
4390
+ ...added.map((key) => ({ key, added: !0 })),
4391
+ ...removed.map((key) => ({ key, added: !1 }))
4392
+ ];
4393
+ }),
4394
+ groupBy$1((i2) => i2.key),
4395
+ mergeMap$1(
4396
+ (group$) => group$.pipe(
4397
+ switchMap((e3) => {
4398
+ if (!e3.added) return EMPTY;
4399
+ const { userId, batchSize, ...options } = parseUsersKey(group$.key);
4400
+ if (userId) {
4401
+ if (userId.startsWith("p"))
4402
+ return getClient(instance, {
4403
+ apiVersion: PROJECT_API_VERSION,
4404
+ // this is a global store, so we need to use the projectId from the options when we're fetching
4405
+ // users from a project subdomain
4406
+ projectId: options.projectId,
4407
+ useProjectHostname: !0
4408
+ }).observable.request({
4409
+ method: "GET",
4410
+ uri: `/users/${userId}`
4411
+ }).pipe(
4412
+ map((user) => ({
4413
+ data: [{
4414
+ sanityUserId: user.sanityUserId,
4415
+ profile: {
4416
+ id: user.id,
4417
+ displayName: user.displayName,
4418
+ familyName: user.familyName ?? void 0,
4419
+ givenName: user.givenName ?? void 0,
4420
+ middleName: user.middleName ?? void 0,
4421
+ imageUrl: user.imageUrl ?? void 0,
4422
+ createdAt: user.createdAt,
4423
+ updatedAt: user.updatedAt,
4424
+ isCurrentUser: user.isCurrentUser,
4425
+ email: user.email,
4426
+ provider: user.provider
4427
+ },
4428
+ memberships: []
4429
+ }],
4430
+ totalCount: 1,
4431
+ nextCursor: null
4432
+ })),
4433
+ catchError$1((error) => (state.set("setUsersError", setUsersError(group$.key, error)), EMPTY)),
4434
+ tap$1(
4435
+ (response) => state.set("setUsersData", setUsersData(group$.key, response))
4436
+ )
4437
+ );
4438
+ const scope = userId.startsWith("g") ? "global" : void 0, client = getClient(instance, {
4439
+ scope,
4440
+ apiVersion: API_VERSION$1
4441
+ }), resourceType2 = options.resourceType || "project", resourceId = resourceType2 === "organization" ? options.organizationId : options.projectId;
4442
+ return resourceId ? client.observable.request({
4443
+ method: "GET",
4444
+ uri: `access/${resourceType2}/${resourceId}/users/${userId}`
4445
+ }).pipe(
4446
+ map((response) => "sanityUserId" in response ? {
4447
+ data: [response],
4448
+ totalCount: 1,
4449
+ nextCursor: null
4450
+ } : response),
4451
+ catchError$1((error) => (state.set("setUsersError", setUsersError(group$.key, error)), EMPTY)),
4452
+ tap$1((response) => state.set("setUsersData", setUsersData(group$.key, response)))
4453
+ ) : throwError(() => new Error("An organizationId or a projectId is required"));
4454
+ }
4455
+ const projectId = options.projectId, resourceType = options.resourceType ?? (options.organizationId ? "organization" : projectId ? "project" : "organization"), organizationId$ = options.organizationId ? of(options.organizationId) : getDashboardOrganizationId$1(instance).observable.pipe(
4456
+ filter((i2) => typeof i2 == "string")
4457
+ ), resource$ = resourceType === "project" ? projectId ? of({ type: "project", id: projectId }) : throwError(() => new Error("Project ID required for this API.")) : organizationId$.pipe(map((id) => ({ type: "organization", id }))), client$ = getClientState(instance, {
4458
+ scope: "global",
4459
+ apiVersion: API_VERSION$1
4460
+ }).observable, loadMore$ = state.observable.pipe(
4461
+ map((s2) => s2.users[group$.key]?.lastLoadMoreRequest),
4462
+ distinctUntilChanged()
4463
+ ), cursor$ = state.observable.pipe(
4464
+ map((s2) => s2.users[group$.key]?.nextCursor),
4465
+ distinctUntilChanged(),
4466
+ filter((cursor) => cursor !== null)
4467
+ );
4468
+ return combineLatest([resource$, client$, loadMore$]).pipe(
4469
+ withLatestFrom(cursor$),
4470
+ switchMap(
4471
+ ([[resource, client], cursor]) => client.observable.request({
4472
+ method: "GET",
4473
+ uri: `access/${resource.type}/${resource.id}/users`,
4474
+ query: cursor ? { nextCursor: cursor, limit: batchSize.toString() } : { limit: batchSize.toString() }
4475
+ })
4476
+ ),
4477
+ catchError$1((error) => (state.set("setUsersError", setUsersError(group$.key, error)), EMPTY)),
4478
+ tap$1((response) => state.set("setUsersData", setUsersData(group$.key, response)))
4479
+ );
4480
+ })
4481
+ )
4482
+ )
4483
+ ).subscribe({ error: errorHandler$1(state) }), getUsersState = bindActionGlobally(
4484
+ usersStore,
4485
+ createStateSourceAction({
4486
+ selector: createSelector(
4487
+ [
4488
+ ({ instance, state }, options) => state.error ?? state.users[getUsersKey(instance, options)]?.error,
4489
+ ({ instance, state }, options) => state.users[getUsersKey(instance, options)]?.users,
4490
+ ({ instance, state }, options) => state.users[getUsersKey(instance, options)]?.totalCount,
4491
+ ({ instance, state }, options) => state.users[getUsersKey(instance, options)]?.nextCursor
4492
+ ],
4493
+ (error, data, totalCount, nextCursor) => {
4494
+ if (error) throw error;
4495
+ if (!(data === void 0 || totalCount === void 0 || nextCursor === void 0))
4496
+ return { data, totalCount, hasMore: nextCursor !== null };
4497
+ }
4498
+ ),
4499
+ onSubscribe: ({ instance, state }, options) => {
4500
+ const subscriptionId = insecureRandomId(), key = getUsersKey(instance, options);
4501
+ return state.set("addSubscription", addSubscription(subscriptionId, key)), () => {
4502
+ setTimeout(
4503
+ () => state.set("removeSubscription", removeSubscription(subscriptionId, key)),
4504
+ USERS_STATE_CLEAR_DELAY
4505
+ );
4506
+ };
4507
+ }
4508
+ })
4509
+ ), resolveUsers = bindActionGlobally(
4510
+ usersStore,
4511
+ async ({ state, instance }, { signal, ...options }) => {
4512
+ const key = getUsersKey(instance, options), { getCurrent } = getUsersState(instance, options), aborted$ = signal ? new Observable((observer) => {
4513
+ const cleanup = () => {
4514
+ signal.removeEventListener("abort", listener);
4515
+ }, listener = () => {
4516
+ observer.error(new DOMException("The operation was aborted.", "AbortError")), observer.complete(), cleanup();
4517
+ };
4518
+ return signal.addEventListener("abort", listener), cleanup;
4519
+ }).pipe(
4520
+ catchError$1((error) => {
4521
+ throw error instanceof Error && error.name === "AbortError" && state.set("cancelRequest", cancelRequest(key)), error;
4522
+ })
4523
+ ) : NEVER;
4524
+ state.set("initializeRequest", initializeRequest(key));
4525
+ const resolved$ = state.observable.pipe(
4526
+ map(getCurrent),
4527
+ first$1((i2) => i2 !== void 0)
4528
+ );
4529
+ return firstValueFrom(race([resolved$, aborted$]));
4530
+ }
4531
+ ), loadMoreUsers = bindActionGlobally(
4532
+ usersStore,
4533
+ async ({ state, instance }, options) => {
4534
+ const key = getUsersKey(instance, options), users = getUsersState(instance, options), usersState = users.getCurrent();
4535
+ if (!usersState)
4536
+ throw new Error("Users not loaded for specified resource. Please call resolveUsers first.");
4537
+ if (!usersState.hasMore)
4538
+ throw new Error("No more users available to load for this resource.");
4539
+ const promise = firstValueFrom(
4540
+ users.observable.pipe(
4541
+ filter((i2) => i2 !== void 0),
4542
+ skip(1)
4543
+ )
4544
+ ), timestamp = (/* @__PURE__ */ new Date()).toISOString();
4545
+ return state.set("updateLastLoadMoreRequest", updateLastLoadMoreRequest(timestamp, key)), await promise;
4546
+ }
4547
+ ), getUserState = bindActionGlobally(
4548
+ usersStore,
4549
+ ({ instance }, { userId, ...options }) => getUsersState(instance, { userId, ...options }).observable.pipe(
4550
+ map((res) => res?.data[0]),
4551
+ distinctUntilChanged((a2, b2) => a2?.profile.updatedAt === b2?.profile.updatedAt)
4552
+ )
4553
+ ), resolveUser = bindActionGlobally(
4554
+ usersStore,
4555
+ async ({ instance }, { signal, ...options }) => (await resolveUsers(instance, {
4556
+ signal,
4557
+ ...options
4558
+ }))?.data[0]
4559
+ );
4560
+ function getBifurClient(client, token$) {
4561
+ const bifurVersionedClient = client.withConfig({ apiVersion: "2022-06-30" }), { dataset, url: baseUrl, requestTagPrefix = "sanity.studio" } = bifurVersionedClient.config(), urlWithTag = `${`${baseUrl.replace(/\/+$/, "")}/socket/${dataset}`.replace(/^http/, "ws")}?tag=${requestTagPrefix}`;
4562
+ return fromUrl(urlWithTag, { token$ });
4563
+ }
4564
+ const handleIncomingMessage = (event) => {
4565
+ switch (event.type) {
4566
+ case "rollCall":
4567
+ return {
4568
+ type: "rollCall",
4569
+ userId: event.i,
4570
+ sessionId: event.session
4571
+ };
4572
+ case "state": {
4573
+ const { sessionId, locations } = event.m;
4574
+ return {
4575
+ type: "state",
4576
+ userId: event.i,
4577
+ sessionId,
4578
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4579
+ locations
4580
+ };
4581
+ }
4582
+ case "disconnect":
4583
+ return {
4584
+ type: "disconnect",
4585
+ userId: event.i,
4586
+ sessionId: event.m.session,
4587
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
4588
+ };
4589
+ default:
4590
+ throw new Error(`Got unknown presence event: ${JSON.stringify(event)}`);
4591
+ }
4592
+ }, createBifurTransport = (options) => {
4593
+ const { client, token$, sessionId } = options, bifur = getBifurClient(client, token$), incomingEvents$ = bifur.listen("presence").pipe(map$1(handleIncomingMessage)), dispatchMessage = (message) => {
4594
+ switch (message.type) {
4595
+ case "rollCall":
4596
+ return bifur.request("presence_rollcall", { session: sessionId });
4597
+ case "state":
4598
+ return bifur.request("presence_announce", {
4599
+ data: { locations: message.locations, sessionId }
4600
+ });
4601
+ case "disconnect":
4602
+ return bifur.request("presence_disconnect", { session: sessionId });
4603
+ default:
4604
+ return EMPTY;
4605
+ }
4606
+ };
4607
+ return typeof window < "u" && fromEvent(window, "beforeunload").pipe(switchMap$1(() => dispatchMessage({ type: "disconnect" }))).subscribe(), [incomingEvents$.pipe(share$1()), dispatchMessage];
4608
+ }, getInitialState = () => ({
4609
+ locations: /* @__PURE__ */ new Map(),
4610
+ users: {}
4611
+ }), presenceStore = {
4612
+ name: "presence",
4613
+ getInitialState,
4614
+ initialize: (context) => {
4615
+ const { instance, state } = context, sessionId = crypto.randomUUID(), client = getClient(instance, {
4616
+ apiVersion: "2022-06-30"
4617
+ }), token$ = getTokenState(instance).observable.pipe(distinctUntilChanged()), [incomingEvents$, dispatch] = createBifurTransport({
4618
+ client,
4619
+ token$,
4620
+ sessionId
4621
+ }), subscription = new Subscription();
4622
+ return subscription.add(
4623
+ incomingEvents$.subscribe((event) => {
4624
+ "sessionId" in event && event.sessionId === sessionId || (event.type === "state" ? state.set("presence/state", (prevState) => {
4625
+ const newLocations = new Map(prevState.locations);
4626
+ return newLocations.set(event.sessionId, {
4627
+ userId: event.userId,
4628
+ locations: event.locations
4629
+ }), {
4630
+ ...prevState,
4631
+ locations: newLocations
4632
+ };
4633
+ }) : event.type === "disconnect" && state.set("presence/disconnect", (prevState) => {
4634
+ const newLocations = new Map(prevState.locations);
4635
+ return newLocations.delete(event.sessionId), { ...prevState, locations: newLocations };
4636
+ }));
4637
+ })
4638
+ ), dispatch({ type: "rollCall" }).subscribe(), () => {
4639
+ dispatch({ type: "disconnect" }).subscribe(), subscription.unsubscribe();
4640
+ };
4641
+ }
4642
+ }, selectLocations = (state) => state.locations, selectUsers = (state) => state.users, selectPresence = createSelector(
4643
+ selectLocations,
4644
+ selectUsers,
4645
+ (locations, users) => Array.from(locations.entries()).map(([sessionId, { userId, locations: locs }]) => ({
4646
+ user: users[userId] || {
4647
+ id: userId,
4648
+ displayName: "Unknown user",
4649
+ name: "Unknown user",
4650
+ email: ""
4651
+ },
4652
+ sessionId,
4653
+ locations: locs
4654
+ }))
4655
+ ), getPresence = bindActionByDataset(
4656
+ presenceStore,
4657
+ createStateSourceAction({
4658
+ selector: (context) => selectPresence(context.state),
4659
+ onSubscribe: (context) => {
4660
+ const subscription = context.state.observable.pipe(
4661
+ map(
4662
+ (state) => Array.from(state.locations.values()).map((l2) => l2.userId).filter((id) => !!id)
4663
+ ),
4664
+ distinctUntilChanged((a2, b2) => a2.length === b2.length && a2.every((v2, i2) => v2 === b2[i2]))
4665
+ ).pipe(
4666
+ switchMap((userIds) => {
4667
+ if (userIds.length === 0)
4668
+ return of([]);
4669
+ const userObservables = userIds.map(
4670
+ (userId) => getUserState(context.instance, {
4671
+ userId,
4672
+ resourceType: "project",
4673
+ projectId: context.instance.config.projectId
4674
+ }).pipe(filter((v2) => !!v2))
4675
+ );
4676
+ return combineLatest(userObservables);
4677
+ })
4678
+ ).subscribe((users) => {
4679
+ users && context.state.set("presence/users", (prevState) => ({
4680
+ ...prevState,
4681
+ users: {
4682
+ ...prevState.users,
4683
+ ...users.reduce((acc, user) => (user && (acc[user.profile.id] = user), acc), {})
4684
+ }
4685
+ }));
4686
+ });
4687
+ return () => subscription.unsubscribe();
4688
+ }
4689
+ })
4690
+ ), fetch = (client, query, params, options) => defer(
4295
4691
  () => client.observable.fetch(query, params, {
4296
4692
  tag: options.tag,
4297
4693
  filterResponse: !0
@@ -4452,7 +4848,7 @@ const DEFAULT_PERSPECTIVE = "drafts", optionsCache = /* @__PURE__ */ new Map(),
4452
4848
  subscription.unsubscribe();
4453
4849
  };
4454
4850
  }
4455
- }, errorHandler$1 = (state) => (error) => state.set("setError", { error }), listenForNewSubscribersAndFetch = ({ state, instance }) => state.observable.pipe(
4851
+ }, errorHandler = (state) => (error) => state.set("setError", { error }), listenForNewSubscribersAndFetch = ({ state, instance }) => state.observable.pipe(
4456
4852
  map((s2) => new Set(Object.keys(s2.queries))),
4457
4853
  distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i2) => curr.has(i2))),
4458
4854
  startWith$1(/* @__PURE__ */ new Set()),
@@ -4506,7 +4902,7 @@ const DEFAULT_PERSPECTIVE = "drafts", optionsCache = /* @__PURE__ */ new Map(),
4506
4902
  })
4507
4903
  )
4508
4904
  )
4509
- ).subscribe({ error: errorHandler$1(state) }), listenToLiveClientAndSetLastLiveEventIds = ({
4905
+ ).subscribe({ error: errorHandler(state) }), listenToLiveClientAndSetLastLiveEventIds = ({
4510
4906
  state,
4511
4907
  instance
4512
4908
  }) => {
@@ -4535,7 +4931,7 @@ const DEFAULT_PERSPECTIVE = "drafts", optionsCache = /* @__PURE__ */ new Map(),
4535
4931
  })
4536
4932
  );
4537
4933
  })
4538
- ).subscribe({ error: errorHandler$1(state) });
4934
+ ).subscribe({ error: errorHandler(state) });
4539
4935
  };
4540
4936
  function getQueryState(...args) {
4541
4937
  return _getQueryState(...args);
@@ -5020,159 +5416,16 @@ const _resolveProjection = bindActionByDataset(
5020
5416
  filter((state) => !!state?.data)
5021
5417
  )
5022
5418
  )
5023
- ), API_VERSION$1 = "v2025-02-19", projects = createFetcherStore({
5419
+ ), API_VERSION = "v2025-02-19", projects = createFetcherStore({
5024
5420
  name: "Projects",
5025
5421
  getKey: () => "projects",
5026
5422
  fetcher: (instance) => () => getClientState(instance, {
5027
- apiVersion: API_VERSION$1,
5423
+ apiVersion: API_VERSION,
5028
5424
  scope: "global"
5029
5425
  }).observable.pipe(
5030
5426
  switchMap((client) => client.observable.projects.list({ includeMembers: !1 }))
5031
5427
  )
5032
- }), getProjectsState = projects.getState, resolveProjects = projects.resolveState, API_VERSION = "vX", USERS_STATE_CLEAR_DELAY = 5e3, DEFAULT_USERS_BATCH_SIZE = 100, getUsersKey = (instance, {
5033
- resourceType,
5034
- organizationId,
5035
- batchSize = DEFAULT_USERS_BATCH_SIZE,
5036
- projectId = instance.config.projectId
5037
- } = {}) => JSON.stringify({ resourceType, organizationId, batchSize, projectId }), parseUsersKey = (key) => JSON.parse(key), addSubscription = (subscriptionId, key) => (prev) => {
5038
- const group = prev.users[key], subscriptions = [...group?.subscriptions ?? [], subscriptionId];
5039
- return { ...prev, users: { ...prev.users, [key]: { ...group, subscriptions } } };
5040
- }, removeSubscription = (subscriptionId, key) => (prev) => {
5041
- const group = prev.users[key];
5042
- if (!group) return prev;
5043
- const subscriptions = group.subscriptions.filter((id) => id !== subscriptionId);
5044
- return subscriptions.length ? { ...prev, users: { ...prev.users, [key]: { ...group, subscriptions } } } : { ...prev, users: omit(prev.users, key) };
5045
- }, setUsersData = (key, { data, nextCursor, totalCount }) => (prev) => {
5046
- const group = prev.users[key];
5047
- if (!group) return prev;
5048
- const users = [...group.users ?? [], ...data];
5049
- return { ...prev, users: { ...prev.users, [key]: { ...group, users, totalCount, nextCursor } } };
5050
- }, updateLastLoadMoreRequest = (timestamp, key) => (prev) => {
5051
- const group = prev.users[key];
5052
- return group ? { ...prev, users: { ...prev.users, [key]: { ...group, lastLoadMoreRequest: timestamp } } } : prev;
5053
- }, setUsersError = (key, error) => (prev) => {
5054
- const group = prev.users[key];
5055
- return group ? { ...prev, users: { ...prev.users, [key]: { ...group, error } } } : prev;
5056
- }, cancelRequest = (key) => (prev) => {
5057
- const group = prev.users[key];
5058
- return !group || group.subscriptions.length ? prev : { ...prev, users: omit(prev.users, key) };
5059
- }, initializeRequest = (key) => (prev) => prev.users[key] ? prev : { ...prev, users: { ...prev.users, [key]: { subscriptions: [] } } }, usersStore = {
5060
- name: "UsersStore",
5061
- getInitialState: () => ({ users: {} }),
5062
- initialize: (context) => {
5063
- const subscription = listenForLoadMoreAndFetch(context);
5064
- return () => subscription.unsubscribe();
5065
- }
5066
- }, errorHandler = (state) => (error) => state.set("setError", { error }), listenForLoadMoreAndFetch = ({ state, instance }) => state.observable.pipe(
5067
- map((s2) => new Set(Object.keys(s2.users))),
5068
- distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i2) => curr.has(i2))),
5069
- startWith$1(/* @__PURE__ */ new Set()),
5070
- pairwise$1(),
5071
- mergeMap$1(([curr, next]) => {
5072
- const added = Array.from(next).filter((i2) => !curr.has(i2)), removed = Array.from(curr).filter((i2) => !next.has(i2));
5073
- return [
5074
- ...added.map((key) => ({ key, added: !0 })),
5075
- ...removed.map((key) => ({ key, added: !1 }))
5076
- ];
5077
- }),
5078
- groupBy$1((i2) => i2.key),
5079
- mergeMap$1(
5080
- (group$) => group$.pipe(
5081
- switchMap((e3) => {
5082
- if (!e3.added) return EMPTY;
5083
- const { batchSize, ...options } = parseUsersKey(group$.key), projectId = options.projectId ?? instance.config.projectId, resourceType = options.resourceType ?? (options.organizationId ? "organization" : projectId ? "project" : "organization"), organizationId$ = options.organizationId ? of(options.organizationId) : getDashboardOrganizationId$1(instance).observable.pipe(
5084
- filter((i2) => typeof i2 == "string")
5085
- ), resource$ = resourceType === "project" ? projectId ? of({ type: "project", id: projectId }) : throwError(() => new Error("Project ID required for this API.")) : organizationId$.pipe(map((id) => ({ type: "organization", id }))), client$ = getClientState(instance, {
5086
- scope: "global",
5087
- apiVersion: API_VERSION
5088
- }).observable, loadMore$ = state.observable.pipe(
5089
- map((s2) => s2.users[group$.key]?.lastLoadMoreRequest),
5090
- distinctUntilChanged()
5091
- ), cursor$ = state.observable.pipe(
5092
- map((s2) => s2.users[group$.key]?.nextCursor),
5093
- distinctUntilChanged(),
5094
- filter((cursor) => cursor !== null)
5095
- );
5096
- return combineLatest([resource$, client$, loadMore$]).pipe(
5097
- withLatestFrom(cursor$),
5098
- switchMap(
5099
- ([[resource, client], cursor]) => client.observable.request({
5100
- method: "GET",
5101
- uri: `access/${resource.type}/${resource.id}/users`,
5102
- query: cursor ? { nextCursor: cursor, limit: batchSize.toString() } : { limit: batchSize.toString() }
5103
- })
5104
- ),
5105
- catchError$1((error) => (state.set("setUsersError", setUsersError(group$.key, error)), EMPTY)),
5106
- tap$1((response) => state.set("setUsersData", setUsersData(group$.key, response)))
5107
- );
5108
- })
5109
- )
5110
- )
5111
- ).subscribe({ error: errorHandler(state) }), getUsersState = bindActionGlobally(
5112
- usersStore,
5113
- createStateSourceAction({
5114
- selector: createSelector(
5115
- [
5116
- ({ instance, state }, options) => state.error ?? state.users[getUsersKey(instance, options)]?.error,
5117
- ({ instance, state }, options) => state.users[getUsersKey(instance, options)]?.users,
5118
- ({ instance, state }, options) => state.users[getUsersKey(instance, options)]?.totalCount,
5119
- ({ instance, state }, options) => state.users[getUsersKey(instance, options)]?.nextCursor
5120
- ],
5121
- (error, data, totalCount, nextCursor) => {
5122
- if (error) throw error;
5123
- if (!(data === void 0 || totalCount === void 0 || nextCursor === void 0))
5124
- return { data, totalCount, hasMore: nextCursor !== null };
5125
- }
5126
- ),
5127
- onSubscribe: ({ instance, state }, options) => {
5128
- const subscriptionId = insecureRandomId(), key = getUsersKey(instance, options);
5129
- return state.set("addSubscription", addSubscription(subscriptionId, key)), () => {
5130
- setTimeout(
5131
- () => state.set("removeSubscription", removeSubscription(subscriptionId, key)),
5132
- USERS_STATE_CLEAR_DELAY
5133
- );
5134
- };
5135
- }
5136
- })
5137
- ), resolveUsers = bindActionGlobally(
5138
- usersStore,
5139
- async ({ state, instance }, { signal, ...options }) => {
5140
- const key = getUsersKey(instance, options), { getCurrent } = getUsersState(instance, options), aborted$ = signal ? new Observable((observer) => {
5141
- const cleanup = () => {
5142
- signal.removeEventListener("abort", listener);
5143
- }, listener = () => {
5144
- observer.error(new DOMException("The operation was aborted.", "AbortError")), observer.complete(), cleanup();
5145
- };
5146
- return signal.addEventListener("abort", listener), cleanup;
5147
- }).pipe(
5148
- catchError$1((error) => {
5149
- throw error instanceof Error && error.name === "AbortError" && state.set("cancelRequest", cancelRequest(key)), error;
5150
- })
5151
- ) : NEVER;
5152
- state.set("initializeRequest", initializeRequest(key));
5153
- const resolved$ = state.observable.pipe(
5154
- map(getCurrent),
5155
- first$1((i2) => i2 !== void 0)
5156
- );
5157
- return firstValueFrom(race([resolved$, aborted$]));
5158
- }
5159
- ), loadMoreUsers = bindActionGlobally(
5160
- usersStore,
5161
- async ({ state, instance }, options) => {
5162
- const key = getUsersKey(instance, options), users = getUsersState(instance, options), usersState = users.getCurrent();
5163
- if (!usersState)
5164
- throw new Error("Users not loaded for specified resource. Please call resolveUsers first.");
5165
- if (!usersState.hasMore)
5166
- throw new Error("No more users available to load for this resource.");
5167
- const promise = firstValueFrom(
5168
- users.observable.pipe(
5169
- filter((i2) => i2 !== void 0),
5170
- skip(1)
5171
- )
5172
- ), timestamp = (/* @__PURE__ */ new Date()).toISOString();
5173
- return state.set("updateLastLoadMoreRequest", updateLastLoadMoreRequest(timestamp, key)), await promise;
5174
- }
5175
- ), WILDCARD_TOKEN = "*", NEGATION_TOKEN = "-", TOKEN_REGEX = /(?:[^\s"]+|"[^"]*")+/g;
5428
+ }), getProjectsState = projects.getState, resolveProjects = projects.resolveState, WILDCARD_TOKEN = "*", NEGATION_TOKEN = "-", TOKEN_REGEX = /(?:[^\s"]+|"[^"]*")+/g;
5176
5429
  function isNegationToken(token) {
5177
5430
  return typeof token < "u" && token.trim().startsWith(NEGATION_TOKEN);
5178
5431
  }
@@ -5195,7 +5448,60 @@ function createGroqSearchFilter(query) {
5195
5448
  `${finalIncrementalToken}${WILDCARD_TOKEN}`
5196
5449
  ), `[@] match text::query("${processedTokens.join(" ").replace(/"/g, '\\"')}")`;
5197
5450
  }
5198
- var version = "2.1.0";
5451
+ function defineIntent(intent) {
5452
+ if (!intent.id)
5453
+ throw new Error("Intent must have an id");
5454
+ if (!intent.action)
5455
+ throw new Error("Intent must have an action");
5456
+ if (!intent.title)
5457
+ throw new Error("Intent must have a title");
5458
+ if (!Array.isArray(intent.filters))
5459
+ throw new Error("Intent must have a filters array");
5460
+ if (intent.filters.length === 0)
5461
+ throw new Error(
5462
+ "Intent must have at least one filter. If you want to match everything, use {types: ['*']}"
5463
+ );
5464
+ return intent.filters.forEach((filter2, index) => {
5465
+ validateFilter(filter2, index);
5466
+ }), intent;
5467
+ }
5468
+ function validateFilter(filter2, index) {
5469
+ const filterContext = `Filter at index ${index}`;
5470
+ if (!filter2 || typeof filter2 != "object")
5471
+ throw new Error(`${filterContext} must be an object`);
5472
+ if (filter2.types === void 0)
5473
+ throw new Error(
5474
+ `${filterContext} must have a types property. Use ['*'] to match all document types.`
5475
+ );
5476
+ if (filter2.projectId !== void 0) {
5477
+ if (typeof filter2.projectId != "string")
5478
+ throw new Error(`${filterContext}: projectId must be a string`);
5479
+ if (filter2.projectId.trim() === "")
5480
+ throw new Error(`${filterContext}: projectId cannot be empty`);
5481
+ }
5482
+ if (filter2.dataset !== void 0) {
5483
+ if (typeof filter2.dataset != "string")
5484
+ throw new Error(`${filterContext}: dataset must be a string`);
5485
+ if (filter2.dataset.trim() === "")
5486
+ throw new Error(`${filterContext}: dataset cannot be empty`);
5487
+ if (filter2.projectId === void 0)
5488
+ throw new Error(`${filterContext}: dataset cannot be specified without projectId`);
5489
+ }
5490
+ if (!Array.isArray(filter2.types))
5491
+ throw new Error(`${filterContext}: types must be an array`);
5492
+ if (filter2.types.length === 0)
5493
+ throw new Error(`${filterContext}: types array cannot be empty`);
5494
+ if (filter2.types.forEach((type, typeIndex) => {
5495
+ if (typeof type != "string")
5496
+ throw new Error(`${filterContext}: types[${typeIndex}] must be a string`);
5497
+ if (type.trim() === "")
5498
+ throw new Error(`${filterContext}: types[${typeIndex}] cannot be empty`);
5499
+ }), filter2.types.includes("*") && filter2.types.length > 1)
5500
+ throw new Error(
5501
+ `${filterContext}: when using wildcard '*', it must be the only type in the array`
5502
+ );
5503
+ }
5504
+ var version = "2.1.1";
5199
5505
  const CORE_SDK_VERSION = getEnv("PKG_VERSION") || `${version}-development`;
5200
5506
  export {
5201
5507
  AuthStateType,
@@ -5208,6 +5514,7 @@ export {
5208
5514
  createGroqSearchFilter,
5209
5515
  createProjectHandle,
5210
5516
  createSanityInstance,
5517
+ defineIntent,
5211
5518
  deleteDocument,
5212
5519
  destroyController,
5213
5520
  discardDocument,
@@ -5232,6 +5539,7 @@ export {
5232
5539
  getPathDepth,
5233
5540
  getPermissionsState,
5234
5541
  getPerspectiveState,
5542
+ getPresence,
5235
5543
  getPreviewState,
5236
5544
  getProjectState,
5237
5545
  getProjectionState,
@@ -5239,6 +5547,7 @@ export {
5239
5547
  getQueryKey,
5240
5548
  getQueryState,
5241
5549
  getTokenState,
5550
+ getUserState,
5242
5551
  getUsersKey,
5243
5552
  getUsersState,
5244
5553
  handleAuthCallback,
@@ -5261,6 +5570,7 @@ export {
5261
5570
  resolveProjection,
5262
5571
  resolveProjects,
5263
5572
  resolveQuery,
5573
+ resolveUser,
5264
5574
  resolveUsers,
5265
5575
  setAuthToken,
5266
5576
  slicePath2 as slicePath,