@sanity/sdk-react 2.3.0 → 2.4.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 CHANGED
@@ -1,4 +1,11 @@
1
1
  import {ActionsResult} from '@sanity/sdk'
2
+ import {AgentGenerateOptions} from '@sanity/sdk'
3
+ import {AgentPatchOptions} from '@sanity/sdk'
4
+ import {AgentPatchResult} from '@sanity/sdk'
5
+ import {AgentPromptOptions} from '@sanity/sdk'
6
+ import {AgentPromptResult} from '@sanity/sdk'
7
+ import {AgentTransformOptions} from '@sanity/sdk'
8
+ import {AgentTranslateOptions} from '@sanity/sdk'
2
9
  import {ApplyDocumentActionsOptions} from '@sanity/sdk'
3
10
  import {AuthState} from '@sanity/sdk'
4
11
  import {CanvasResource} from '@sanity/message-protocol'
@@ -11,6 +18,7 @@ import {DocumentEvent} from '@sanity/sdk'
11
18
  import {DocumentHandle} from '@sanity/sdk'
12
19
  import {DocumentOptions} from '@sanity/sdk'
13
20
  import {DocumentPermissionsResult} from '@sanity/sdk'
21
+ import {DocumentSource} from '@sanity/sdk'
14
22
  import {FallbackProps} from 'react-error-boundary'
15
23
  import {FavoriteStatusResponse} from '@sanity/sdk'
16
24
  import {FrameMessage} from '@sanity/sdk'
@@ -142,6 +150,26 @@ declare interface DashboardResource {
142
150
 
143
151
  export {DatasetsResponse}
144
152
 
153
+ /**
154
+ * Return type for the useDispatchIntent hook
155
+ * @beta
156
+ */
157
+ declare interface DispatchIntent {
158
+ dispatchIntent: () => void
159
+ }
160
+
161
+ /**
162
+ * Document handle that optionally includes a source (e.g., media library source)
163
+ * or projectId and dataset for traditional dataset sources
164
+ * (but now marked optional since it's valid to just use a source)
165
+ * @beta
166
+ */
167
+ declare interface DocumentHandleWithSource extends Omit<DocumentHandle, 'projectId' | 'dataset'> {
168
+ source?: DocumentSource
169
+ projectId?: string
170
+ dataset?: string
171
+ }
172
+
145
173
  declare interface DocumentInteractionHistory {
146
174
  recordEvent: (eventType: 'viewed' | 'edited' | 'created' | 'deleted') => void
147
175
  }
@@ -156,8 +184,8 @@ export declare interface DocumentsOptions<
156
184
  TDocumentType extends string = string,
157
185
  TDataset extends string = string,
158
186
  TProjectId extends string = string,
159
- > extends DatasetHandle<TDataset, TProjectId>,
160
- Pick<QueryOptions, 'perspective' | 'params'> {
187
+ >
188
+ extends DatasetHandle<TDataset, TProjectId>, Pick<QueryOptions, 'perspective' | 'params'> {
161
189
  /**
162
190
  * Filter documents by their `_type`. Can be a single type or an array of types.
163
191
  */
@@ -269,6 +297,12 @@ export declare interface NavigateToStudioResult {
269
297
  navigateToStudioDocument: () => void
270
298
  }
271
299
 
300
+ declare interface Observer<T> {
301
+ next?: (value: T) => void
302
+ error?: (err: unknown) => void
303
+ complete?: () => void
304
+ }
305
+
272
306
  /**
273
307
  * Configuration options for the usePaginatedDocuments hook
274
308
  *
@@ -569,6 +603,19 @@ declare interface StudioWorkspacesResult {
569
603
  error: string | null
570
604
  }
571
605
 
606
+ declare interface Subscribable<T> {
607
+ subscribe(observer: Observer<T>): Subscription
608
+ subscribe(
609
+ next: (value: T) => void,
610
+ error?: (err: unknown) => void,
611
+ complete?: () => void,
612
+ ): Subscription
613
+ }
614
+
615
+ declare interface Subscription {
616
+ unsubscribe(): void
617
+ }
618
+
572
619
  declare type Updater<TValue> = TValue | ((currentValue: TValue) => TValue)
573
620
 
574
621
  /**
@@ -595,6 +642,70 @@ declare type UseActiveReleases = {
595
642
  */
596
643
  export declare const useActiveReleases: UseActiveReleases
597
644
 
645
+ /**
646
+ * @alpha
647
+ * Generates content for a document (or specific fields) via Sanity Agent Actions.
648
+ * - Uses instruction templates with `$variables` and supports `instructionParams` (constants, fields, documents, GROQ queries).
649
+ * - Can target specific paths/fields; supports image generation when targeting image fields.
650
+ * - Supports optional `temperature`, `async`, `noWrite`, and `conditionalPaths`.
651
+ *
652
+ * Returns a stable callback that triggers the action and yields a Subscribable stream.
653
+ */
654
+ export declare const useAgentGenerate: () => (
655
+ options: AgentGenerateOptions,
656
+ ) => Subscribable<unknown>
657
+
658
+ /**
659
+ * @alpha
660
+ * Schema-aware patching with Sanity Agent Actions.
661
+ * - Validates provided paths/values against the document schema and merges object values safely.
662
+ * - Prevents duplicate keys and supports array appends (including after a specific keyed item).
663
+ * - Accepts `documentId` or `targetDocument` (mutually exclusive).
664
+ * - Optional `async`, `noWrite`, `conditionalPaths`.
665
+ *
666
+ * Returns a stable callback that triggers the action and resolves a Promise with the patch result.
667
+ */
668
+ export declare const useAgentPatch: () => (options: AgentPatchOptions) => Promise<AgentPatchResult>
669
+
670
+ /**
671
+ * @alpha
672
+ * Prompts the LLM using the same instruction template format as other actions.
673
+ * - `format`: 'string' or 'json' (instruction must contain the word "json" for JSON responses).
674
+ * - Optional `temperature`.
675
+ *
676
+ * Returns a stable callback that triggers the action and resolves a Promise with the prompt result.
677
+ */
678
+ export declare const useAgentPrompt: () => (
679
+ options: AgentPromptOptions,
680
+ ) => Promise<AgentPromptResult>
681
+
682
+ /**
683
+ * @alpha
684
+ * Transforms an existing document or selected fields using Sanity Agent Actions.
685
+ * - Accepts `instruction` and `instructionParams` (constants, fields, documents, GROQ queries).
686
+ * - Can write to the same or a different `targetDocument` (create/edit), and target specific paths.
687
+ * - Supports per-path image transform instructions and image description operations.
688
+ * - Optional `temperature`, `async`, `noWrite`, `conditionalPaths`.
689
+ *
690
+ * Returns a stable callback that triggers the action and yields a Subscribable stream.
691
+ */
692
+ export declare const useAgentTransform: () => (
693
+ options: AgentTransformOptions,
694
+ ) => Subscribable<unknown>
695
+
696
+ /**
697
+ * @alpha
698
+ * Translates documents or fields using Sanity Agent Actions.
699
+ * - Configure `fromLanguage`/`toLanguage`, optional `styleGuide`, and `protectedPhrases`.
700
+ * - Can write into a different `targetDocument`, and/or store language in a field.
701
+ * - Optional `temperature`, `async`, `noWrite`, `conditionalPaths`.
702
+ *
703
+ * Returns a stable callback that triggers the action and yields a Subscribable stream.
704
+ */
705
+ export declare const useAgentTranslate: () => (
706
+ options: AgentTranslateOptions,
707
+ ) => Subscribable<unknown>
708
+
598
709
  /**
599
710
  * @public
600
711
  */
@@ -702,6 +813,37 @@ declare interface UseApplyDocumentActions {
702
813
  * )
703
814
  * }
704
815
  * ```
816
+ *
817
+ * @example Create a document with initial field values
818
+ * ```tsx
819
+ * import {
820
+ * createDocument,
821
+ * createDocumentHandle,
822
+ * useApplyDocumentActions
823
+ * } from '@sanity/sdk-react'
824
+ *
825
+ * function CreateArticleButton() {
826
+ * const apply = useApplyDocumentActions()
827
+ *
828
+ * const handleCreateArticle = () => {
829
+ * const newDocHandle = createDocumentHandle({
830
+ * documentId: crypto.randomUUID(),
831
+ * documentType: 'article'
832
+ * })
833
+ *
834
+ * // Create document with initial values in one action
835
+ * apply(
836
+ * createDocument(newDocHandle, {
837
+ * title: 'New Article',
838
+ * author: 'John Doe',
839
+ * publishedAt: new Date().toISOString(),
840
+ * })
841
+ * )
842
+ * }
843
+ *
844
+ * return <button onClick={handleCreateArticle}>Create Article</button>
845
+ * }
846
+ * ```
705
847
  */
706
848
  export declare const useApplyDocumentActions: UseApplyDocumentActions
707
849
 
@@ -762,7 +904,7 @@ export declare const useAuthToken: () => string | null
762
904
  * @public
763
905
  * @function
764
906
  */
765
- export declare const useClient: (x: ClientOptions) => SanityClient
907
+ export declare const useClient: (options: ClientOptions) => SanityClient
766
908
 
767
909
  declare type UseCurrentUser = {
768
910
  /**
@@ -894,6 +1036,70 @@ declare type UseDatasets = {
894
1036
  */
895
1037
  export declare const useDatasets: UseDatasets
896
1038
 
1039
+ /**
1040
+ * @beta
1041
+ *
1042
+ * A hook for dispatching intent messages to the Dashboard with a document handle.
1043
+ * This allows applications to signal their intent to pass the referenced document to other applications that have registered the ability to perform specific actions on that document.
1044
+ *
1045
+ * @param params - Object containing:
1046
+ * - `action` - Action to perform (currently only 'edit' is supported). Will prompt a picker if multiple handlers are available.
1047
+ * - `intentId` - Specific ID of the intent to dispatch. Either `action` or `intentId` is required.
1048
+ * - `documentHandle` - The document handle containing document ID, type, and either:
1049
+ * - `projectId` and `dataset` for traditional dataset sources, like `{documentId: '123', documentType: 'book', projectId: 'abc123', dataset: 'production'}`
1050
+ * - `source` for media library, canvas, or dataset sources, like `{documentId: '123', documentType: 'sanity.asset', source: mediaLibrarySource('ml123')}` or `{documentId: '123', documentType: 'sanity.canvas.document', source: canvasSource('canvas123')}`
1051
+ * - `paremeters` - Optional parameters to include in the dispatch; will be passed to the resolved intent handler
1052
+ * @returns An object containing:
1053
+ * - `dispatchIntent` - Function to dispatch the intent message
1054
+ *
1055
+ * @example
1056
+ * ```tsx
1057
+ * import {useDispatchIntent} from '@sanity/sdk-react'
1058
+ * import {Button} from '@sanity/ui'
1059
+ * import {Suspense} from 'react'
1060
+ *
1061
+ * function DispatchIntentButton({documentId, documentType, projectId, dataset}) {
1062
+ * const {dispatchIntent} = useDispatchIntent({
1063
+ * action: 'edit',
1064
+ * documentHandle: {documentId, documentType, projectId, dataset},
1065
+ * })
1066
+ *
1067
+ * return (
1068
+ * <Button
1069
+ * onClick={() => dispatchIntent()}
1070
+ * text="Dispatch Intent"
1071
+ * />
1072
+ * )
1073
+ * }
1074
+ *
1075
+ * // Wrap the component with Suspense since the hook may suspend
1076
+ * function MyDocumentAction({documentId, documentType, projectId, dataset}) {
1077
+ * return (
1078
+ * <Suspense fallback={<Button text="Loading..." disabled />}>
1079
+ * <DispatchIntentButton
1080
+ * documentId={documentId}
1081
+ * documentType={documentType}
1082
+ * projectId={projectId}
1083
+ * dataset={dataset}
1084
+ * />
1085
+ * </Suspense>
1086
+ * )
1087
+ * }
1088
+ * ```
1089
+ */
1090
+ export declare function useDispatchIntent(params: UseDispatchIntentParams): DispatchIntent
1091
+
1092
+ /**
1093
+ * Parameters for the useDispatchIntent hook
1094
+ * @beta
1095
+ */
1096
+ declare interface UseDispatchIntentParams {
1097
+ action?: 'edit'
1098
+ intentId?: string
1099
+ documentHandle: DocumentHandleWithSource
1100
+ parameters?: Record<string, unknown>
1101
+ }
1102
+
897
1103
  declare interface UseDocument {
898
1104
  /** @internal */
899
1105
  <TDocumentType extends string, TDataset extends string, TProjectId extends string = string>(
@@ -2499,7 +2705,7 @@ export declare function useUser(options: GetUserOptions): UserResult
2499
2705
  * <address>{user.profile.email}</address>
2500
2706
  * </figure>
2501
2707
  * ))}
2502
- * {hasMore && <button onClick={loadMore}>{isPending ? 'Loading...' : 'Load More'</button>}
2708
+ * {hasMore && <button onClick={loadMore}>{isPending ? 'Loading...' : 'Load More'}</button>}
2503
2709
  * </div>
2504
2710
  * )
2505
2711
  * ```
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { c } from "react-compiler-runtime";
3
3
  import { ClientError, CorsOriginError } from "@sanity/client";
4
- import { getAuthState, getNodeState, getIsInDashboardState, setAuthToken, AuthStateType, getLoginUrlState, observeOrganizationVerificationState, handleAuthCallback, logout, getCorsErrorProjectId, createSanityInstance, getTokenState, getCurrentUserState, getDashboardOrganizationId, getClientState, getOrCreateController, getOrCreateChannel, releaseChannel, getFavoritesState, resolveFavoritesState, resolveDatasets, getDatasetsState, applyDocumentActions, resolveDocument, getDocumentState, subscribeDocumentEvents, getPermissionsState, getDocumentSyncStatus, editDocument, getQueryKey, parseQueryKey, getQueryState, resolveQuery, createGroqSearchFilter, getPresence, getPreviewState, resolvePreview, getProjectionState, resolveProjection, resolveProject, getProjectState, resolveProjects, getProjectsState, getActiveReleasesState, getPerspectiveState, getUsersKey, parseUsersKey, getUsersState, resolveUsers, loadMoreUsers } from "@sanity/sdk";
4
+ import { getAuthState, getNodeState, getIsInDashboardState, setAuthToken, AuthStateType, getLoginUrlState, observeOrganizationVerificationState, handleAuthCallback, logout, isProjectUserNotFoundClientError, getClientErrorApiDescription, getClientErrorApiBody, getCorsErrorProjectId, createSanityInstance, agentGenerate, agentTransform, agentTranslate, agentPrompt, agentPatch, getTokenState, getCurrentUserState, getDashboardOrganizationId, getClientState, getOrCreateController, getOrCreateChannel, releaseChannel, getFavoritesState, resolveFavoritesState, resolveDatasets, getDatasetsState, applyDocumentActions, resolveDocument, getDocumentState, subscribeDocumentEvents, getPermissionsState, getDocumentSyncStatus, editDocument, getQueryKey, parseQueryKey, getQueryState, resolveQuery, createGroqSearchFilter, getPresence, getPreviewState, resolvePreview, getProjectionState, resolveProjection, resolveProject, getProjectState, resolveProjects, getProjectsState, getActiveReleasesState, getPerspectiveState, getUsersKey, parseUsersKey, getUsersState, resolveUsers, loadMoreUsers } from "@sanity/sdk";
5
5
  export * from "@sanity/sdk";
6
- import { createContext, useContext, useSyncExternalStore, useRef, useEffect, useState, Suspense, useMemo, useCallback, useInsertionEffect, useTransition } from "react";
6
+ import { createContext, useContext, useSyncExternalStore, useRef, useEffect, useState, Suspense, useCallback, useMemo, useInsertionEffect, useTransition } from "react";
7
7
  import { ErrorBoundary } from "react-error-boundary";
8
8
  import { SDK_CHANNEL_NAME, SDK_NODE_NAME } from "@sanity/message-protocol";
9
9
  import { firstValueFrom, filter, identity, Observable, startWith, distinctUntilChanged, switchMap, EMPTY } from "rxjs";
@@ -142,7 +142,9 @@ const ComlinkTokenRefreshProvider = (t0) => {
142
142
  children
143
143
  } = t0, instance = useSanityInstance();
144
144
  let t1;
145
- if (t1 = getIsInDashboardState(instance).getCurrent(), t1) {
145
+ t1 = getIsInDashboardState(instance).getCurrent();
146
+ const isInDashboard = t1, studioModeEnabled = !!instance.config.studioMode?.enabled;
147
+ if (isInDashboard && !studioModeEnabled) {
146
148
  let t2;
147
149
  return $[0] !== children ? (t2 = /* @__PURE__ */ jsx(DashboardTokenRefresh, { children }), $[0] = children, $[1] = t2) : t2 = $[1], t2;
148
150
  }
@@ -295,13 +297,13 @@ function _temp$5(replacementLocation) {
295
297
  }
296
298
  const useLogOut = createCallbackHook(logout);
297
299
  function LoginError(t0) {
298
- const $ = c(17), {
300
+ const $ = c(18), {
299
301
  error,
300
302
  resetErrorBoundary
301
303
  } = t0;
302
304
  if (!(error instanceof AuthError || error instanceof ConfigurationError || error instanceof ClientError))
303
305
  throw error;
304
- const logout2 = useLogOut(), authState = useAuthState(), [authErrorMessage, setAuthErrorMessage] = useState("Please try again or contact support if the problem persists.");
306
+ const logout2 = useLogOut(), authState = useAuthState(), [authErrorMessage, setAuthErrorMessage] = useState("Please try again or contact support if the problem persists."), [showRetryCta, setShowRetryCta] = useState(!0);
305
307
  let t1;
306
308
  $[0] !== logout2 || $[1] !== resetErrorBoundary ? (t1 = async () => {
307
309
  await logout2(), resetErrorBoundary();
@@ -311,24 +313,28 @@ function LoginError(t0) {
311
313
  $[3] !== authState.type || $[4] !== error || $[5] !== handleRetry ? (t2 = () => {
312
314
  if (error instanceof ClientError) {
313
315
  if (error.statusCode === 401)
314
- handleRetry();
316
+ if (isProjectUserNotFoundClientError(error)) {
317
+ const description = getClientErrorApiDescription(error);
318
+ description && setAuthErrorMessage(description), setShowRetryCta(!1);
319
+ } else
320
+ setShowRetryCta(!0), handleRetry();
315
321
  else if (error.statusCode === 404) {
316
- const errorMessage = error.response.body.message || "";
317
- errorMessage.startsWith("Session with sid") && errorMessage.endsWith("not found") ? setAuthErrorMessage("The session ID is invalid or expired.") : setAuthErrorMessage("The login link is invalid or expired. Please try again.");
322
+ const errorMessage = getClientErrorApiBody(error)?.message || "";
323
+ errorMessage.startsWith("Session with sid") && errorMessage.endsWith("not found") ? setAuthErrorMessage("The session ID is invalid or expired.") : setAuthErrorMessage("The login link is invalid or expired. Please try again."), setShowRetryCta(!0);
318
324
  }
319
325
  }
320
- authState.type !== AuthStateType.ERROR && error instanceof ConfigurationError && setAuthErrorMessage(error.message);
326
+ authState.type !== AuthStateType.ERROR && error instanceof ConfigurationError && (setAuthErrorMessage(error.message), setShowRetryCta(!0));
321
327
  }, $[3] = authState.type, $[4] = error, $[5] = handleRetry, $[6] = t2) : t2 = $[6];
322
328
  let t3;
323
329
  $[7] !== authState || $[8] !== error || $[9] !== handleRetry ? (t3 = [authState, handleRetry, error], $[7] = authState, $[8] = error, $[9] = handleRetry, $[10] = t3) : t3 = $[10], useEffect(t2, t3);
324
330
  const t4 = error instanceof AuthError ? "Authentication Error" : "Configuration Error";
325
331
  let t5;
326
- $[11] !== handleRetry ? (t5 = {
332
+ $[11] !== handleRetry || $[12] !== showRetryCta ? (t5 = showRetryCta ? {
327
333
  text: "Retry",
328
334
  onClick: handleRetry
329
- }, $[11] = handleRetry, $[12] = t5) : t5 = $[12];
335
+ } : void 0, $[11] = handleRetry, $[12] = showRetryCta, $[13] = t5) : t5 = $[13];
330
336
  let t6;
331
- return $[13] !== authErrorMessage || $[14] !== t4 || $[15] !== t5 ? (t6 = /* @__PURE__ */ jsx(Error$1, { heading: t4, description: authErrorMessage, cta: t5 }), $[13] = authErrorMessage, $[14] = t4, $[15] = t5, $[16] = t6) : t6 = $[16], t6;
337
+ return $[14] !== authErrorMessage || $[15] !== t4 || $[16] !== t5 ? (t6 = /* @__PURE__ */ jsx(Error$1, { heading: t4, description: authErrorMessage, cta: t5 }), $[14] = authErrorMessage, $[15] = t4, $[16] = t5, $[17] = t6) : t6 = $[17], t6;
332
338
  }
333
339
  if (isInIframe() && !document.querySelector("[data-sanity-core]")) {
334
340
  const parsedUrl = new URL(window.location.href), mode = new URLSearchParams(parsedUrl.hash.slice(1)).get("mode"), script = document.createElement("script");
@@ -353,7 +359,7 @@ function AuthBoundary(t0) {
353
359
  return $[7] !== FallbackComponent || $[8] !== t4 ? (t5 = /* @__PURE__ */ jsx(ComlinkTokenRefreshProvider, { children: /* @__PURE__ */ jsx(ErrorBoundary, { FallbackComponent, children: t4 }) }), $[7] = FallbackComponent, $[8] = t4, $[9] = t5) : t5 = $[9], t5;
354
360
  }
355
361
  function AuthSwitch(t0) {
356
- const $ = c(13);
362
+ const $ = c(14);
357
363
  let children, projectIds, props, t1, t2;
358
364
  $[0] !== t0 ? ({
359
365
  CallbackComponent: t1,
@@ -362,11 +368,11 @@ function AuthSwitch(t0) {
362
368
  projectIds,
363
369
  ...props
364
370
  } = t0, $[0] = t0, $[1] = children, $[2] = projectIds, $[3] = props, $[4] = t1, $[5] = t2) : (children = $[1], projectIds = $[2], props = $[3], t1 = $[4], t2 = $[5]);
365
- const CallbackComponent = t1 === void 0 ? LoginCallback : t1, verifyOrganization = t2 === void 0 ? !0 : t2, authState = useAuthState(), orgError = useVerifyOrgProjects(!verifyOrganization, projectIds), isLoggedOut = authState.type === AuthStateType.LOGGED_OUT && !authState.isDestroyingSession, loginUrl = useLoginUrl();
371
+ const CallbackComponent = t1 === void 0 ? LoginCallback : t1, verifyOrganization = t2 === void 0 ? !0 : t2, authState = useAuthState(), studioModeEnabled = useSanityInstance().config.studioMode?.enabled, disableVerifyOrg = !verifyOrganization || studioModeEnabled || authState.type !== AuthStateType.LOGGED_IN, orgError = useVerifyOrgProjects(disableVerifyOrg, projectIds), isLoggedOut = authState.type === AuthStateType.LOGGED_OUT && !authState.isDestroyingSession, loginUrl = useLoginUrl();
366
372
  let t3, t4;
367
- if ($[6] !== isLoggedOut || $[7] !== loginUrl ? (t3 = () => {
368
- isLoggedOut && !isInIframe() && (window.location.href = loginUrl);
369
- }, t4 = [isLoggedOut, loginUrl], $[6] = isLoggedOut, $[7] = loginUrl, $[8] = t3, $[9] = t4) : (t3 = $[8], t4 = $[9]), useEffect(t3, t4), verifyOrganization && orgError)
373
+ if ($[6] !== isLoggedOut || $[7] !== loginUrl || $[8] !== studioModeEnabled ? (t3 = () => {
374
+ isLoggedOut && !isInIframe() && !studioModeEnabled && (window.location.href = loginUrl);
375
+ }, t4 = [isLoggedOut, loginUrl, studioModeEnabled], $[6] = isLoggedOut, $[7] = loginUrl, $[8] = studioModeEnabled, $[9] = t3, $[10] = t4) : (t3 = $[9], t4 = $[10]), useEffect(t3, t4), verifyOrganization && orgError)
370
376
  throw new ConfigurationError({
371
377
  message: orgError
372
378
  });
@@ -375,7 +381,7 @@ function AuthSwitch(t0) {
375
381
  throw new AuthError(authState.error);
376
382
  case AuthStateType.LOGGING_IN: {
377
383
  let t5;
378
- return $[10] !== CallbackComponent || $[11] !== props ? (t5 = /* @__PURE__ */ jsx(CallbackComponent, { ...props }), $[10] = CallbackComponent, $[11] = props, $[12] = t5) : t5 = $[12], t5;
384
+ return $[11] !== CallbackComponent || $[12] !== props ? (t5 = /* @__PURE__ */ jsx(CallbackComponent, { ...props }), $[11] = CallbackComponent, $[12] = props, $[13] = t5) : t5 = $[13], t5;
379
385
  }
380
386
  case AuthStateType.LOGGED_IN:
381
387
  return children;
@@ -447,7 +453,15 @@ function SanityApp(t0) {
447
453
  function _temp$4() {
448
454
  console.warn("Redirecting to core", REDIRECT_URL), window.location.replace(REDIRECT_URL);
449
455
  }
450
- const useAuthToken = createStateSourceHook(getTokenState), useCurrentUser = createStateSourceHook(getCurrentUserState);
456
+ const useAgentGenerate = createCallbackHook(agentGenerate), useAgentTransform = createCallbackHook(agentTransform), useAgentTranslate = createCallbackHook(agentTranslate);
457
+ function promptAdapter(instance, options) {
458
+ return firstValueFrom(agentPrompt(instance, options));
459
+ }
460
+ const useAgentPrompt = createCallbackHook(promptAdapter);
461
+ function patchAdapter(instance, options) {
462
+ return firstValueFrom(agentPatch(instance, options));
463
+ }
464
+ const useAgentPatch = createCallbackHook(patchAdapter), useAuthToken = createStateSourceHook(getTokenState), useCurrentUser = createStateSourceHook(getCurrentUserState);
451
465
  function useDashboardOrganizationId() {
452
466
  const $ = c(2), instance = useSanityInstance();
453
467
  let t0, t1;
@@ -459,8 +473,12 @@ function useDashboardOrganizationId() {
459
473
  return useSyncExternalStore(subscribe, getCurrent);
460
474
  }
461
475
  const useClient = createStateSourceHook({
462
- getState: getClientState,
463
- getConfig: identity
476
+ getState: (instance, options) => {
477
+ if (!options || typeof options != "object")
478
+ throw new Error('useClient() requires a configuration object with at least an "apiVersion" property. Example: useClient({ apiVersion: "2024-11-12" })');
479
+ return getClientState(instance, options);
480
+ },
481
+ getConfig: (options) => options
464
482
  });
465
483
  function useFrameConnection(options) {
466
484
  const $ = c(12), {
@@ -524,6 +542,84 @@ function useDashboardNavigate(navigateFn) {
524
542
  }
525
543
  }, $[0] = navigateFn, $[1] = t0) : t0 = $[1], useWindowConnection(t0);
526
544
  }
545
+ const SOURCE_ID = "__sanity_internal_sourceId", isDocumentHandleWithSource = (documentHandle) => "source" in documentHandle;
546
+ function getResourceIdFromDocumentHandle(documentHandle) {
547
+ let source;
548
+ const {
549
+ projectId,
550
+ dataset
551
+ } = documentHandle;
552
+ isDocumentHandleWithSource(documentHandle) && (source = documentHandle.source);
553
+ let resourceId = projectId + "." + dataset, resourceType;
554
+ if (source) {
555
+ const sourceId = source[SOURCE_ID];
556
+ if (Array.isArray(sourceId))
557
+ (sourceId[0] === "media-library" || sourceId[0] === "canvas") && (resourceType = sourceId[0], resourceId = sourceId[1]);
558
+ else if (sourceId && typeof sourceId == "object" && "projectId" in sourceId) {
559
+ const datasetSource = sourceId;
560
+ resourceId = `${datasetSource.projectId}.${datasetSource.dataset}`;
561
+ }
562
+ }
563
+ return {
564
+ id: resourceId,
565
+ type: resourceType
566
+ };
567
+ }
568
+ function useDispatchIntent(params) {
569
+ const {
570
+ action,
571
+ intentId,
572
+ documentHandle,
573
+ parameters
574
+ } = params, {
575
+ sendMessage
576
+ } = useWindowConnection({
577
+ name: SDK_NODE_NAME,
578
+ connectTo: SDK_CHANNEL_NAME
579
+ });
580
+ return {
581
+ dispatchIntent: useCallback(() => {
582
+ try {
583
+ if (!action && !intentId)
584
+ throw new Error("useDispatchIntent: Either `action` or `intentId` must be provided.");
585
+ const {
586
+ projectId,
587
+ dataset,
588
+ source
589
+ } = documentHandle;
590
+ if (action && intentId && console.warn("useDispatchIntent: Both `action` and `intentId` were provided. Using `intentId` and ignoring `action`."), !source && (!projectId || !dataset))
591
+ throw new Error("useDispatchIntent: Either `source` or both `projectId` and `dataset` must be provided in documentHandle.");
592
+ const resource = getResourceIdFromDocumentHandle(documentHandle), message = {
593
+ type: "dashboard/v1/events/intents/dispatch-intent",
594
+ data: {
595
+ ...action && !intentId ? {
596
+ action
597
+ } : {},
598
+ ...intentId ? {
599
+ intentId
600
+ } : {},
601
+ document: {
602
+ id: documentHandle.documentId,
603
+ type: documentHandle.documentType
604
+ },
605
+ resource: {
606
+ id: resource.id,
607
+ ...resource.type ? {
608
+ type: resource.type
609
+ } : {}
610
+ },
611
+ ...parameters && Object.keys(parameters).length > 0 ? {
612
+ parameters
613
+ } : {}
614
+ }
615
+ };
616
+ sendMessage(message.type, message.data);
617
+ } catch (error) {
618
+ throw console.error("Failed to dispatch intent:", error), error;
619
+ }
620
+ }, [action, intentId, documentHandle, parameters, sendMessage])
621
+ };
622
+ }
527
623
  function useManageFavorite({
528
624
  documentId,
529
625
  documentType,
@@ -1123,35 +1219,27 @@ function useDocumentPreview(t0) {
1123
1219
  return currentState;
1124
1220
  }, $[9] = docHandle, $[10] = instance, $[11] = stateSource, $[12] = t3) : t3 = $[12], useSyncExternalStore(subscribe, t3);
1125
1221
  }
1126
- function useDocumentProjection(t0) {
1127
- const $ = c(12);
1128
- let docHandle, projection, ref;
1129
- $[0] !== t0 ? ({
1130
- ref,
1131
- projection,
1132
- ...docHandle
1133
- } = t0, $[0] = t0, $[1] = docHandle, $[2] = projection, $[3] = ref) : (docHandle = $[1], projection = $[2], ref = $[3]);
1134
- const instance = useSanityInstance(docHandle);
1135
- let stateSource, t1;
1136
- if ($[4] !== docHandle || $[5] !== instance || $[6] !== projection ? (stateSource = getProjectionState(instance, {
1222
+ function useDocumentProjection({
1223
+ ref,
1224
+ projection,
1225
+ ...docHandle
1226
+ }) {
1227
+ const instance = useSanityInstance(docHandle), normalizedProjection = useMemo(() => projection.trim(), [projection]), stateSource = useMemo(() => getProjectionState(instance, {
1137
1228
  ...docHandle,
1138
- projection
1139
- }), t1 = stateSource.getCurrent()?.data, $[4] = docHandle, $[5] = instance, $[6] = projection, $[7] = stateSource, $[8] = t1) : (stateSource = $[7], t1 = $[8]), t1 === null)
1229
+ projection: normalizedProjection
1230
+ }), [instance, normalizedProjection, docHandle]);
1231
+ if (stateSource.getCurrent()?.data === null)
1140
1232
  throw resolveProjection(instance, {
1141
1233
  ...docHandle,
1142
- projection
1234
+ projection: normalizedProjection
1143
1235
  });
1144
- let t2;
1145
- return $[9] !== ref || $[10] !== stateSource ? (t2 = (onStoreChanged) => {
1236
+ const subscribe = useCallback((onStoreChanged) => {
1146
1237
  const subscription = new Observable((observer) => {
1147
1238
  if (typeof IntersectionObserver > "u" || typeof HTMLElement > "u") {
1148
1239
  observer.next(!0);
1149
1240
  return;
1150
1241
  }
1151
- const intersectionObserver = new IntersectionObserver((t3) => {
1152
- const [entry] = t3;
1153
- return observer.next(entry.isIntersecting);
1154
- }, {
1242
+ const intersectionObserver = new IntersectionObserver(([entry]) => observer.next(entry.isIntersecting), {
1155
1243
  rootMargin: "0px",
1156
1244
  threshold: 0
1157
1245
  });
@@ -1160,7 +1248,8 @@ function useDocumentProjection(t0) {
1160
1248
  next: onStoreChanged
1161
1249
  });
1162
1250
  return () => subscription.unsubscribe();
1163
- }, $[9] = ref, $[10] = stateSource, $[11] = t2) : t2 = $[11], useSyncExternalStore(t2, stateSource.getCurrent);
1251
+ }, [stateSource, ref]);
1252
+ return useSyncExternalStore(subscribe, stateSource.getCurrent);
1164
1253
  }
1165
1254
  const useProject = createStateSourceHook({
1166
1255
  // remove `undefined` since we're suspending when that is the case
@@ -1231,7 +1320,7 @@ function useUsers(options) {
1231
1320
  loadMore
1232
1321
  };
1233
1322
  }
1234
- var version = "2.3.0";
1323
+ var version = "2.4.0";
1235
1324
  function getEnv(key) {
1236
1325
  if (typeof import.meta < "u" && import.meta.env)
1237
1326
  return import.meta.env[key];
@@ -1249,6 +1338,11 @@ export {
1249
1338
  SDKProvider,
1250
1339
  SanityApp,
1251
1340
  useActiveReleases,
1341
+ useAgentGenerate,
1342
+ useAgentPatch,
1343
+ useAgentPrompt,
1344
+ useAgentTransform,
1345
+ useAgentTranslate,
1252
1346
  useApplyDocumentActions,
1253
1347
  useAuthState,
1254
1348
  useAuthToken,
@@ -1257,6 +1351,7 @@ export {
1257
1351
  useDashboardNavigate,
1258
1352
  useDashboardOrganizationId,
1259
1353
  useDatasets,
1354
+ useDispatchIntent,
1260
1355
  useDocument,
1261
1356
  useDocumentEvent,
1262
1357
  useDocumentPermissions,