@sanity/sdk 0.0.0-alpha.7 → 0.0.0-alpha.8

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
@@ -169,6 +169,7 @@ export declare interface ClientOptions {
169
169
  */
170
170
  export declare interface ClientState {
171
171
  defaultClient: SanityClient
172
+ defaultGlobalClient: SanityClient
172
173
  clients: Map<string, SanityClient>
173
174
  }
174
175
 
@@ -325,6 +326,12 @@ export declare const getCurrentUserState: ResourceAction<
325
326
  StateSource<CurrentUser | null>
326
327
  >
327
328
 
329
+ /**
330
+ * Retrieves the global, project-less client.
331
+ * @public
332
+ */
333
+ export declare const getGlobalClient: ResourceAction<ClientState, [], SanityClient>
334
+
328
335
  /**
329
336
  * @public
330
337
  */
package/dist/index.js CHANGED
@@ -254,6 +254,8 @@ const subscribeToStorageEventsAndSetToken = createInternalAction(
254
254
  ), getAuthState = createStateSourceAction(authStore, ({ authState }) => authState), receiveToken = (prev, token) => {
255
255
  const newDefaultClient = prev.defaultClient.withConfig({
256
256
  token
257
+ }), newGlobalClient = prev.defaultGlobalClient.withConfig({
258
+ token
257
259
  }), updatedClients = new Map(
258
260
  Array.from(prev.clients.entries()).map(([version, client]) => [
259
261
  version,
@@ -262,6 +264,7 @@ const subscribeToStorageEventsAndSetToken = createInternalAction(
262
264
  );
263
265
  return {
264
266
  defaultClient: newDefaultClient,
267
+ defaultGlobalClient: newGlobalClient,
265
268
  clients: updatedClients
266
269
  };
267
270
  }, subscribeToAuthEvents = createInternalAction(
@@ -278,9 +281,17 @@ const subscribeToStorageEventsAndSetToken = createInternalAction(
278
281
  useCdn: !1,
279
282
  apiVersion: DEFAULT_API_VERSION,
280
283
  ...config?.auth?.apiHost ? { apiHost: config.auth.apiHost } : {}
284
+ }), defaultGlobalClient = createClient({
285
+ token: config?.auth?.token,
286
+ useCdn: !1,
287
+ apiVersion: "vX",
288
+ // Many global APIs are only available under this version, we may need to support other versions in the future
289
+ useProjectHostname: !1,
290
+ ...config?.auth?.apiHost ? { apiHost: config.auth.apiHost } : {}
281
291
  }), clients = /* @__PURE__ */ new Map();
282
- return clients.set(DEFAULT_API_VERSION, defaultClient), {
292
+ return clients.set(DEFAULT_API_VERSION, defaultClient), clients.set("global-vX", defaultGlobalClient), {
283
293
  defaultClient,
294
+ defaultGlobalClient,
284
295
  clients
285
296
  };
286
297
  },
@@ -301,7 +312,10 @@ const subscribeToStorageEventsAndSetToken = createInternalAction(
301
312
  return newMap.set(apiVersion, client), state.set("createClient", {
302
313
  clients: newMap
303
314
  }), client;
304
- }), getSubscribableClient = createAction(clientStore, ({ instance, state }) => (options) => {
315
+ }), getGlobalClient = createAction(
316
+ clientStore,
317
+ ({ state }) => () => state.get().defaultGlobalClient
318
+ ), getSubscribableClient = createAction(clientStore, ({ instance, state }) => (options) => {
305
319
  const initialClient = getClient(instance, options), client$ = state.observable.pipe(
306
320
  map(() => getClient(instance, options)),
307
321
  startWith(initialClient),
@@ -960,6 +974,7 @@ export {
960
974
  getAuthState,
961
975
  getClient,
962
976
  getCurrentUserState,
977
+ getGlobalClient,
963
978
  getLoginUrlsState,
964
979
  getOrCreateChannel,
965
980
  getOrCreateController,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils/getEnv.ts","../src/resources/createResource.ts","../src/instance/identity.ts","../src/instance/sanityInstance.ts","../src/resources/createAction.ts","../src/resources/createStore.ts","../src/resources/createStateSourceAction.ts","../src/auth/authStateType.ts","../src/auth/authConstants.ts","../src/auth/subscribeToStateAndFetchCurrentUser.ts","../src/auth/utils.ts","../src/auth/subscribeToStorageEventsAndSetToken.ts","../src/auth/authStore.ts","../src/client/actions/subscribeToAuthEvents.ts","../src/client/clientStore.ts","../src/client/actions/getClient.ts","../src/client/actions/getSubscribableClient.ts","../src/documentList/documentListConstants.ts","../src/documentList/subscribeToLiveClientAndSetLastLiveEventId.ts","../src/documentList/subscribeToStateAndFetchResults.ts","../src/documentList/documentListStore.ts","../src/auth/fetchLoginUrls.ts","../src/auth/handleCallback.ts","../src/auth/logout.ts","../src/schema/schemaManager.ts","../src/preview/util.ts","../src/preview/subscribeToLiveAndSetLastLiveEventId.ts","../src/schema/getSchemaState.ts","../src/preview/getProjectionForSchemaType.ts","../src/preview/previewQuery.ts","../src/preview/subscribeToStateAndFetchBatches.ts","../src/preview/previewStore.ts","../src/preview/getPreviewState.ts","../src/preview/resolvePreview.ts","../src/comlink/controller/comlinkControllerStore.ts","../src/comlink/controller/actions/destroyController.ts","../src/comlink/controller/actions/getOrCreateChannel.ts","../src/comlink/controller/actions/getOrCreateController.ts","../src/comlink/controller/actions/releaseChannel.ts","../src/comlink/node/comlinkNodeStore.ts","../src/comlink/node/actions/getOrCreateNode.ts","../src/comlink/node/actions/releaseNode.ts"],"sourcesContent":["// Local type declaration for Remix\ntype WindowWithEnv = Window &\n typeof globalThis & {\n ENV?: Record<string, unknown>\n }\n\ntype KnownEnvVar = 'DEV'\n\nexport function getEnv(key: KnownEnvVar): unknown {\n if (typeof import.meta !== 'undefined' && import.meta.env) {\n // Vite environment variables\n return (import.meta.env as unknown as Record<string, unknown>)[key]\n } else if (typeof process !== 'undefined' && process.env) {\n // Node.js or server-side environment variables\n return process.env[key]\n } else if (typeof window !== 'undefined' && (window as WindowWithEnv).ENV) {\n // Remix-style client-side environment variables\n return (window as WindowWithEnv).ENV?.[key]\n }\n return undefined\n}\n","import {Observable} from 'rxjs'\nimport {devtools, type DevtoolsOptions} from 'zustand/middleware'\nimport {createStore} from 'zustand/vanilla'\n\nimport {type SanityInstance, type SdkIdentity} from '../instance/types'\nimport {getEnv} from '../utils/getEnv'\n\nconst resourceCache = new WeakMap<SdkIdentity, Map<string, InitializedResource<unknown>>>()\n\ntype Teardown = () => void\n\nexport interface Resource<TState> {\n name: string\n getInitialState(instance: SanityInstance): TState\n initialize?: (\n this: {instance: SanityInstance; state: ResourceState<TState>},\n instance: SanityInstance,\n ) => Teardown\n}\n\nexport function createResource<TState>(resource: Resource<TState>): Resource<TState> {\n return resource\n}\n\n/**\n * @public\n */\nexport type ResourceState<TState> = {\n get: () => TState\n set: (name: string, state: Partial<TState> | ((s: TState) => Partial<TState>)) => void\n observable: Observable<TState>\n}\n\ninterface InitializedResource<TState> {\n state: ResourceState<TState>\n dispose: () => void\n}\n\nexport function createResourceState<TState>(\n initialState: TState,\n devToolsOptions?: DevtoolsOptions,\n): ResourceState<TState> {\n const store = createStore<TState>()(devtools(() => initialState, devToolsOptions))\n return {\n get: store.getState,\n set: (actionKey, updatedState) => store.setState(updatedState, false, actionKey),\n observable: new Observable((observer) => {\n const emit = () => observer.next(store.getState())\n emit()\n return store.subscribe(emit)\n }),\n }\n}\n\nexport function initializeResource<TState>(\n instance: SanityInstance,\n resource: Resource<TState>,\n): InitializedResource<TState> {\n const initialState = resource.getInitialState(instance)\n const state = createResourceState(initialState, {\n name: resource.name,\n enabled: !!getEnv('DEV'),\n })\n const dispose = resource.initialize?.call({instance, state}, instance) ?? (() => {})\n\n return {state, dispose}\n}\n\nexport function getOrCreateResource<TState>(\n instance: SanityInstance,\n resource: Resource<TState>,\n): InitializedResource<TState> {\n if (!resourceCache.has(instance.identity)) {\n resourceCache.set(instance.identity, new Map())\n }\n const initializedResources = resourceCache.get(instance.identity)!\n const cached = initializedResources.get(resource.name)\n if (cached) return cached as InitializedResource<TState>\n\n const result = initializeResource(instance, resource)\n initializedResources.set(resource.name, result)\n return result\n}\n\nexport function disposeResources(identity: SdkIdentity): void {\n const resources = resourceCache.get(identity)\n if (!resources) return\n\n for (const resource of resources.values()) {\n resource.dispose()\n }\n}\n","import {type SdkIdentity} from './types'\n\n/**\n * thoughtLevel 2 - Primarily what we want is to have an object that we can bind stores/memoizations to, but let the things that depend on it (eg projectId, dataset) be internals that can't be overwritten by accident/intentionally\n * @public\n */\nexport function getSdkIdentity({\n projectId,\n dataset,\n}: {\n projectId: string\n dataset: string\n}): SdkIdentity {\n const id = generateId()\n return Object.freeze({\n id,\n projectId,\n dataset,\n })\n}\n\nfunction generateId() {\n return Array.from({length: 8}, () =>\n Math.floor(Math.random() * 16)\n .toString(16)\n .padStart(2, '0'),\n ).join('')\n}\n","import {disposeResources} from '../resources/createResource'\nimport {getSdkIdentity} from './identity'\nimport {type SanityConfig, type SanityInstance, type SdkIdentity} from './types'\n\n/**\n * Returns a new instance of dependencies required for SanitySDK.\n *\n * @public\n *\n * @param config - The configuration for this instance\n *\n * @returns A new \"instance\" of a Sanity SDK, used to bind resources/configuration to it\n */\nexport function createSanityInstance({\n projectId = '',\n dataset = '',\n ...config\n}: SanityConfig): SanityInstance {\n const identity = getSdkIdentity({projectId, dataset})\n return {\n identity,\n config,\n dispose: () => disposeResources(identity),\n }\n}\n\nconst resourceStorage = new WeakMap<SdkIdentity, Map<string, unknown>>()\n\nfunction getResource(instance: SanityInstance, key: string) {\n const instanceMap = resourceStorage.get(instance.identity)\n return instanceMap?.get(key)\n}\n\nfunction setResource(instance: SanityInstance, key: string, value: unknown) {\n let instanceMap = resourceStorage.get(instance.identity)\n if (!instanceMap) {\n instanceMap = new Map()\n resourceStorage.set(instance.identity, instanceMap)\n }\n instanceMap.set(key, value)\n}\n\n/**\n * This is an internal function that retrieves or creates a Zustand store resource.\n * @internal\n */\nexport function getOrCreateResource<T>(instance: SanityInstance, key: string, creator: () => T): T {\n const cached = getResource(instance, key)\n\n if (cached) {\n return cached as T\n }\n\n const resource = creator()\n setResource(instance, key, resource)\n return resource\n}\n","import {type SanityInstance} from '../instance/types'\nimport {getOrCreateResource, type Resource, type ResourceState} from './createResource'\n\n/** @public */\nexport interface ActionContext<TState> {\n instance: SanityInstance\n state: ResourceState<TState>\n}\n\ntype ResourceActionDefinition<TState, TParams extends unknown[], TReturn> = (options: {\n instance: SanityInstance\n state: ResourceState<TState>\n}) => (this: ActionContext<TState>, ...args: TParams) => TReturn\n\n/**\n * @public\n */\nexport type ResourceAction<TState, TParams extends unknown[], TReturn> = (\n dependencies: SanityInstance | ActionContext<TState>,\n ...params: TParams\n) => TReturn\n\nexport function createAction<TState, TParams extends unknown[], TReturn>(\n resource: Resource<TState>,\n actionDefinition: ResourceActionDefinition<TState, TParams, TReturn>,\n): ResourceAction<TState, TParams, TReturn> {\n return (dependencies: SanityInstance | ActionContext<TState>, ...args: TParams): TReturn => {\n const instance = 'state' in dependencies ? dependencies.instance : dependencies\n const {state} =\n 'state' in dependencies ? dependencies : getOrCreateResource(dependencies, resource)\n const actionContext = {instance, state}\n return actionDefinition(actionContext).bind(actionContext)(...args)\n }\n}\n\n/**\n * @internal\n */\nexport function createInternalAction<TState, TParams extends unknown[], TReturn>(\n actionDefinition: ResourceActionDefinition<TState, TParams, TReturn>,\n) {\n return (actionContext: ActionContext<TState>, ...args: TParams): TReturn => {\n return actionDefinition(actionContext).bind(actionContext)(...args)\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {noop} from 'lodash-es'\n\nimport {type SanityInstance} from '../instance/types'\nimport {type ActionContext, type ResourceAction} from './createAction'\nimport {initializeResource, type Resource} from './createResource'\n\n/**\n * @public\n */\nexport type BoundResourceAction<TParams extends unknown[], TReturn> = (\n ...params: TParams\n) => TReturn\n\ntype BoundActions<TActions extends {[key: string]: ResourceAction<any, any, any>}> = {\n [K in keyof TActions]: TActions[K] extends ResourceAction<any, infer TParams, infer TReturn>\n ? BoundResourceAction<TParams, TReturn>\n : never\n}\n\ntype StoreFactory<TActions extends {[key: string]: ResourceAction<any, any, any>}> = (\n instance: SanityInstance | ActionContext<any>,\n) => {\n dispose: () => void\n} & BoundActions<TActions>\n\nexport function createStore<\n TState,\n TActions extends {[key: string]: ResourceAction<any, any, any>},\n>(resource: Resource<TState>, actions: TActions): StoreFactory<TActions> {\n return function storeFactory(dependencies: SanityInstance | ActionContext<TState>) {\n const instance = 'instance' in dependencies ? dependencies.instance : dependencies\n const {state, dispose} =\n 'state' in dependencies\n ? {state: dependencies.state, dispose: noop}\n : initializeResource(instance, resource)\n const boundActions = Object.entries(actions).reduce<\n Record<string, BoundResourceAction<unknown[], unknown>>\n >((acc, [key, action]) => {\n acc[key] = action.bind(null, {state, instance})\n return acc\n }, {}) as BoundActions<TActions>\n\n return {dispose, ...boundActions}\n }\n}\n","import {filter, map, Observable, pairwise} from 'rxjs'\n\nimport {createAction, type ResourceAction} from './createAction'\nimport {type Resource} from './createResource'\n\n/**\n * @public\n */\nexport interface StateSource<T> {\n subscribe: (onStoreChanged: () => void) => () => void\n getCurrent: () => T\n observable: Observable<T>\n}\n\nexport function createStateSourceAction<TState, TParams extends unknown[], TReturn>(\n resource: Resource<TState>,\n selector: (state: TState, ...params: TParams) => TReturn,\n): ResourceAction<TState, TParams, StateSource<TReturn>> {\n return createAction(resource, ({state}) => {\n return function (...args: TParams): StateSource<TReturn> {\n const getCurrent = () => selector(state.get(), ...args)\n\n const subscribe = (onStoreChanged: () => void) => {\n const subscription = state.observable\n .pipe(\n // this is similar to `distinctUntilChanged` expect that it doesn't\n // emit until the first change from `getCurrent`\n map(getCurrent),\n pairwise(),\n filter(([prev, curr]) => prev !== curr),\n map(([_, curr]) => curr),\n )\n .subscribe({next: onStoreChanged})\n\n return () => subscription.unsubscribe()\n }\n\n const observable = new Observable<TReturn>((observer) => {\n const emitCurrent = () => observer.next(getCurrent())\n emitCurrent()\n return subscribe(emitCurrent)\n })\n\n return {\n getCurrent,\n subscribe,\n observable,\n }\n }\n })\n}\n","/**\n * Represents the various states the authentication type can be in.\n *\n * @public\n */\nexport enum AuthStateType {\n LOGGED_IN = 'logged-in',\n LOGGING_IN = 'logging-in',\n ERROR = 'error',\n LOGGED_OUT = 'logged-out',\n}\n","export const DEFAULT_BASE = 'http://localhost'\nexport const AUTH_CODE_PARAM = 'sid'\nexport const DEFAULT_API_VERSION = '2021-06-07'\nexport const REQUEST_TAG_PREFIX = 'sdk.auth'\n","import {type CurrentUser} from '@sanity/types'\nimport {distinctUntilChanged, filter, map, switchMap} from 'rxjs'\n\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {DEFAULT_API_VERSION, REQUEST_TAG_PREFIX} from './authConstants'\nimport {AuthStateType} from './authStateType'\nimport {type AuthState, type AuthStoreState} from './authStore'\n\nexport const subscribeToStateAndFetchCurrentUser = createInternalAction(\n ({state, instance}: ActionContext<AuthStoreState>) => {\n const {projectId, dataset} = instance.identity\n const {clientFactory, apiHost, authScope} = state.get().options\n\n const currentUser$ = state.observable\n .pipe(\n map(({authState}) => authState),\n filter(\n (authState): authState is Extract<AuthState, {type: AuthStateType.LOGGED_IN}> =>\n authState.type === AuthStateType.LOGGED_IN && !authState.currentUser,\n ),\n map((authState) => authState.token),\n distinctUntilChanged(),\n )\n .pipe(\n map((token) =>\n clientFactory({\n projectId,\n dataset,\n apiVersion: DEFAULT_API_VERSION,\n requestTagPrefix: REQUEST_TAG_PREFIX,\n useProjectHostname: authScope === 'project',\n token,\n ignoreBrowserTokenWarning: true,\n ...(apiHost && {apiHost}),\n }),\n ),\n switchMap((client) =>\n client.observable.request<CurrentUser>({uri: '/users/me', method: 'GET'}),\n ),\n )\n\n return function () {\n return currentUser$.subscribe({\n next: (currentUser) => {\n state.set('setCurrentUser', (prev) => ({\n authState:\n prev.authState.type === AuthStateType.LOGGED_IN\n ? {...prev.authState, currentUser}\n : prev.authState,\n }))\n },\n error: (error) => {\n state.set('setError', {authState: {type: AuthStateType.ERROR, error}})\n },\n })\n }\n },\n)\n","import {EMPTY, fromEvent, Observable} from 'rxjs'\n\nimport {AUTH_CODE_PARAM, DEFAULT_BASE} from './authConstants'\n\nexport function getAuthCode(callbackUrl: string | undefined, locationHref: string): string | null {\n const loc = new URL(locationHref, DEFAULT_BASE)\n const callbackLocation = callbackUrl ? new URL(callbackUrl, DEFAULT_BASE) : undefined\n const callbackLocationMatches = callbackLocation\n ? loc.pathname.toLowerCase().startsWith(callbackLocation.pathname.toLowerCase())\n : true\n\n // for stamped tokens, the authCode is not in the hash, it is in the query params\n const authCode =\n new URLSearchParams(loc.hash.slice(1)).get(AUTH_CODE_PARAM) ||\n new URLSearchParams(loc.search).get(AUTH_CODE_PARAM)\n\n return authCode && callbackLocationMatches ? authCode : null\n}\n\n/**\n * Attempts to retrieve a token from the configured storage.\n * If invalid or not present, returns null.\n */\nexport function getTokenFromStorage(\n storageArea: Storage | undefined,\n storageKey: string,\n): string | null {\n if (!storageArea) return null\n const item = storageArea.getItem(storageKey)\n if (item === null) return null\n\n try {\n const parsed: unknown = JSON.parse(item)\n if (\n typeof parsed !== 'object' ||\n parsed === null ||\n !('token' in parsed) ||\n typeof parsed.token !== 'string'\n ) {\n throw new Error('Invalid stored auth data structure')\n }\n return parsed.token\n } catch {\n storageArea.removeItem(storageKey)\n return null\n }\n}\n\n/**\n * Creates an observable stream of storage events. If not in a browser environment,\n * returns an EMPTY observable.\n */\nexport function getStorageEvents(): Observable<StorageEvent> {\n const isBrowser = typeof window !== 'undefined' && typeof window.addEventListener === 'function'\n\n if (!isBrowser) {\n return EMPTY\n }\n\n return fromEvent<StorageEvent>(window, 'storage')\n}\n\n/**\n * Returns a default storage instance (localStorage) if available.\n * If not available or an error occurs, returns undefined.\n */\nexport function getDefaultStorage(): Storage | undefined {\n try {\n if (typeof localStorage !== 'undefined' && typeof localStorage.getItem === 'function') {\n return localStorage\n }\n return undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Returns the default location to use.\n * Tries accessing `location.href`, falls back to a default base if not available or on error.\n */\nexport function getDefaultLocation(): string {\n try {\n if (typeof location === 'undefined') return DEFAULT_BASE\n if (typeof location.href === 'string') return location.href\n return DEFAULT_BASE\n } catch {\n return DEFAULT_BASE\n }\n}\n","import {defer, distinctUntilChanged, filter, map} from 'rxjs'\n\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {AuthStateType} from './authStateType'\nimport {type AuthStoreState} from './authStore'\nimport {getStorageEvents, getTokenFromStorage} from './utils'\n\nexport const subscribeToStorageEventsAndSetToken = createInternalAction(\n ({state}: ActionContext<AuthStoreState>) => {\n const {storageArea, storageKey} = state.get().options\n\n const tokenFromStorage$ = defer(getStorageEvents).pipe(\n filter(\n (e): e is StorageEvent & {newValue: string} =>\n e.storageArea === storageArea && e.key === storageKey,\n ),\n map(() => getTokenFromStorage(storageArea, storageKey)),\n distinctUntilChanged(),\n )\n\n return function () {\n return tokenFromStorage$.subscribe((token) => {\n state.set('updateTokenFromStorageEvent', {\n authState: token\n ? {type: AuthStateType.LOGGED_IN, token, currentUser: null}\n : {type: AuthStateType.LOGGED_OUT, isDestroyingSession: false},\n })\n })\n }\n },\n)\n","import {type ClientConfig, createClient, type SanityClient} from '@sanity/client'\nimport {type CurrentUser} from '@sanity/types'\n\nimport {createResource} from '../resources/createResource'\nimport {createStateSourceAction} from '../resources/createStateSourceAction'\nimport {AuthStateType} from './authStateType'\nimport {subscribeToStateAndFetchCurrentUser} from './subscribeToStateAndFetchCurrentUser'\nimport {subscribeToStorageEventsAndSetToken} from './subscribeToStorageEventsAndSetToken'\nimport {getAuthCode, getDefaultLocation, getDefaultStorage, getTokenFromStorage} from './utils'\n\n/**\n * Represents the various states the authentication can be in.\n *\n * @public\n */\nexport type AuthState = LoggedInAuthState | LoggedOutAuthState | LoggingInAuthState | ErrorAuthState\n\n/**\n * Logged-in state from the auth state.\n * @public\n */\nexport type LoggedInAuthState = {\n type: AuthStateType.LOGGED_IN\n token: string\n currentUser: CurrentUser | null\n}\n\n/**\n * Logged-out state from the auth state.\n * @public\n */\nexport type LoggedOutAuthState = {type: AuthStateType.LOGGED_OUT; isDestroyingSession: boolean}\n\n/**\n * Logging-in state from the auth state.\n * @public\n */\nexport type LoggingInAuthState = {type: AuthStateType.LOGGING_IN; isExchangingToken: boolean}\n\n/**\n * Error state from the auth state.\n * @public\n */\nexport type ErrorAuthState = {type: AuthStateType.ERROR; error: unknown}\n\n/**\n * Configuration for an authentication provider\n * @public\n */\nexport interface AuthProvider {\n /**\n * Unique identifier for the auth provider (e.g., 'google', 'github')\n */\n name: string\n\n /**\n * Display name for the auth provider in the UI\n */\n title: string\n\n /**\n * Complete authentication URL including callback and token parameters\n */\n url: string\n\n /**\n * Optional URL for direct sign-up flow\n */\n signUpUrl?: string\n}\n\n/**\n * Configuration options for creating an auth store.\n *\n * @public\n */\nexport interface AuthConfig {\n /**\n * The initial location href to use when handling auth callbacks.\n * Defaults to the current window location if available.\n */\n initialLocationHref?: string\n\n /**\n * Factory function to create a SanityClient instance.\n * Defaults to the standard Sanity client factory if not provided.\n */\n clientFactory?: (config: ClientConfig) => SanityClient\n\n /**\n * Custom authentication providers to use instead of or in addition to the default ones.\n * Can be an array of providers or a function that takes the default providers and returns\n * a modified array or a Promise resolving to one.\n */\n providers?: AuthProvider[] | ((prev: AuthProvider[]) => AuthProvider[] | Promise<AuthProvider[]>)\n\n /**\n * The API hostname for requests. Usually leave this undefined, but it can be set\n * if using a custom domain or CNAME for the API endpoint.\n */\n apiHost?: string\n\n /**\n * Storage implementation to persist authentication state.\n * Defaults to `localStorage` if available.\n */\n storageArea?: Storage\n\n /**\n * A callback URL for your application.\n * If none is provided, the auth API will redirect back to the current location (`location.href`).\n * When handling callbacks, this URL's pathname is checked to ensure it matches the callback.\n */\n callbackUrl?: string\n\n /**\n * A static authentication token to use instead of handling the OAuth flow.\n * When provided, the auth store will remain in a logged-in state with this token,\n * ignoring any storage or callback handling.\n */\n token?: string\n\n /**\n * The authentication scope.\n * If set to 'project', requests are scoped to the project-level.\n * If set to 'global', requests are scoped to the user access level.\n * Defaults to 'project'.\n */\n authScope?: 'project' | 'global'\n}\n\n/**\n * @public\n */\nexport interface AuthStoreState {\n authState: AuthState\n providers?: AuthProvider[]\n options: {\n initialLocationHref: string\n clientFactory: (config: ClientConfig) => SanityClient\n customProviders: AuthConfig['providers']\n authScope: 'project' | 'global'\n storageKey: string\n storageArea: Storage | undefined\n apiHost: string | undefined\n callbackUrl: string | undefined\n providedToken: string | undefined\n }\n}\n\nexport const authStore = createResource<AuthStoreState>({\n name: 'Auth',\n getInitialState(instance) {\n const {\n apiHost,\n callbackUrl,\n providers: customProviders,\n authScope = 'project',\n token: providedToken,\n clientFactory = createClient,\n initialLocationHref = getDefaultLocation(),\n storageArea = getDefaultStorage(),\n } = instance.config.auth ?? {}\n const {projectId, dataset} = instance.identity\n\n const storageKey = `__sanity_auth_token_${projectId}_${dataset}`\n\n let authState: AuthState\n\n const token = getTokenFromStorage(storageArea, storageKey)\n\n if (providedToken) {\n authState = {type: AuthStateType.LOGGED_IN, token: providedToken, currentUser: null}\n } else if (getAuthCode(callbackUrl, initialLocationHref)) {\n authState = {type: AuthStateType.LOGGING_IN, isExchangingToken: false}\n } else if (token) {\n authState = {type: AuthStateType.LOGGED_IN, token, currentUser: null}\n } else {\n authState = {type: AuthStateType.LOGGED_OUT, isDestroyingSession: false}\n }\n\n return {\n authState,\n options: {\n apiHost,\n authScope,\n callbackUrl,\n customProviders,\n providedToken,\n clientFactory,\n initialLocationHref,\n storageKey,\n storageArea,\n },\n }\n },\n initialize() {\n const stateSubscription = subscribeToStateAndFetchCurrentUser(this)\n const storageEventsSubscription = subscribeToStorageEventsAndSetToken(this)\n\n return () => {\n stateSubscription.unsubscribe()\n storageEventsSubscription.unsubscribe()\n }\n },\n})\n\n/**\n * @public\n */\nexport const getCurrentUserState = createStateSourceAction(authStore, ({authState}) =>\n authState.type === AuthStateType.LOGGED_IN ? authState.currentUser : null,\n)\n\n/**\n * @public\n */\nexport const getTokenState = createStateSourceAction(authStore, ({authState}) =>\n authState.type === AuthStateType.LOGGED_IN ? authState.token : null,\n)\n/**\n * @public\n */\nexport const getLoginUrlsState = createStateSourceAction(\n authStore,\n ({providers}) => providers ?? null,\n)\n\n/**\n * @public\n */\nexport const getAuthState = createStateSourceAction(authStore, ({authState}) => authState)\n","import {getTokenState} from '../../auth/authStore'\nimport {type ActionContext, createInternalAction} from '../../resources/createAction'\nimport {type ClientState} from '../clientStore'\n\nconst receiveToken = (prev: ClientState, token: string | undefined): ClientState => {\n const newDefaultClient = prev.defaultClient.withConfig({\n token,\n })\n const updatedClients = new Map(\n Array.from(prev.clients.entries()).map(([version, client]) => [\n version,\n client.withConfig({token}),\n ]),\n )\n\n return {\n defaultClient: newDefaultClient,\n clients: updatedClients,\n }\n}\n\n/**\n * Updates the client store state when a token is received.\n * @internal\n */\nexport const subscribeToAuthEvents = createInternalAction(\n ({instance, state}: ActionContext<ClientState>) => {\n return () => {\n return getTokenState(instance).observable.subscribe((newToken) => {\n state.set('receiveToken', (prev) => receiveToken(prev, newToken ?? undefined))\n })\n }\n },\n)\n","import {createClient, type SanityClient} from '@sanity/client'\n\nimport {type SanityInstance} from '../instance/types'\nimport {createResource, type Resource} from '../resources/createResource'\nimport {subscribeToAuthEvents} from './actions/subscribeToAuthEvents'\n\nconst DEFAULT_API_VERSION = '2024-11-12'\n\n/**\n * States tracked by the client store\n * @public\n */\nexport interface ClientState {\n defaultClient: SanityClient\n clients: Map<string, SanityClient>\n}\n\nexport const clientStore: Resource<ClientState> = createResource({\n name: 'clientStore',\n\n getInitialState: (instance: SanityInstance) => {\n const {identity, config} = instance\n const defaultClient = createClient({\n projectId: identity.projectId,\n dataset: identity.dataset,\n token: config?.auth?.token,\n useCdn: false,\n apiVersion: DEFAULT_API_VERSION,\n ...(config?.auth?.apiHost ? {apiHost: config.auth.apiHost} : {}),\n })\n\n const clients = new Map<string, SanityClient>()\n clients.set(DEFAULT_API_VERSION, defaultClient)\n\n return {\n defaultClient,\n clients,\n }\n },\n\n initialize() {\n const authEventSubscription = subscribeToAuthEvents(this)\n return () => {\n authEventSubscription.unsubscribe()\n }\n },\n})\n","import {type SanityClient} from '@sanity/client'\n\nimport {createAction} from '../../resources/createAction'\nimport {clientStore} from '../clientStore'\n\n/**\n * Options used when retrieving a client via getOrCreateClient.\n * @public\n */\nexport interface ClientOptions {\n apiVersion?: string\n}\n\n/**\n * Retrieves a memoized client based on the API version,\n * or creates a new one if it doesn't exist.\n * @public\n */\nexport const getClient = createAction(clientStore, ({state}) => {\n return (options: ClientOptions = {}): SanityClient => {\n const {apiVersion} = options\n\n if (!apiVersion) {\n throw new Error('Missing required `apiVersion` option')\n }\n\n const cached = state.get().clients.get(apiVersion)\n if (cached) {\n return cached\n }\n\n // Create new client with specified API version\n const client = state.get().defaultClient.withConfig(options)\n const newMap = new Map(state.get().clients)\n newMap.set(apiVersion, client)\n\n // Update state with new client\n state.set('createClient', {\n clients: newMap,\n })\n\n return client\n }\n})\n","import {type SanityClient} from '@sanity/client'\nimport {distinctUntilChanged, map, startWith, type Subscribable} from 'rxjs'\n\nimport {createAction} from '../../resources/createAction'\nimport {clientStore} from '../clientStore'\nimport {type ClientOptions, getClient} from './getClient'\n\n/**\n * Provides a stream of clients, based on the current state of the store.\n * (For example, when a user logs in, this will emit an authorized client.)\n * @public\n */\nexport const getSubscribableClient = createAction(clientStore, ({instance, state}) => {\n return (options: ClientOptions): Subscribable<SanityClient> => {\n const initialClient = getClient(instance, options)\n\n const client$ = state.observable.pipe(\n map(() => getClient(instance, options)),\n startWith(initialClient),\n // as we add more things that can change client configuration,\n // we might want to add more checks here\n distinctUntilChanged((prev, curr) => prev.config().token === curr.config().token),\n )\n\n return {\n subscribe: client$.subscribe.bind(client$),\n }\n }\n})\n","export const API_VERSION = 'vX'\nexport const PAGE_SIZE = 25\n","import {type SanityClient} from '@sanity/client'\nimport {filter, map, Observable, switchMap, withLatestFrom} from 'rxjs'\n\nimport {getSubscribableClient} from '../client/actions/getSubscribableClient'\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {API_VERSION} from './documentListConstants'\nimport {type DocumentListState} from './documentListStore'\n\nexport const subscribeToLiveClientAndSetLastLiveEventId = createInternalAction(\n ({state, instance}: ActionContext<DocumentListState>) => {\n const liveEventMessage$ = new Observable<SanityClient>((observer) =>\n getSubscribableClient(instance, {apiVersion: API_VERSION}).subscribe(observer),\n ).pipe(\n switchMap((client) =>\n client.live.events({includeDrafts: !!client.config().token, tag: 'sdk.document-list'}),\n ),\n filter((e) => e.type === 'message'),\n withLatestFrom(state.observable.pipe(map(({syncTags}) => syncTags))),\n )\n\n return function () {\n return liveEventMessage$.subscribe(([event, syncTags]) => {\n if (event.tags.some((tag) => syncTags.includes(tag))) {\n state.set('updateEventIdFromLiveContentApi', {lastLiveEventId: event.id})\n }\n })\n }\n },\n)\n","import {type SanityClient} from '@sanity/client'\nimport {isEqual, pick} from 'lodash-es'\nimport {\n debounceTime,\n distinctUntilChanged,\n map,\n Observable,\n switchMap,\n tap,\n withLatestFrom,\n} from 'rxjs'\n\nimport {getSubscribableClient} from '../client/actions/getSubscribableClient'\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {API_VERSION} from './documentListConstants'\nimport {type DocumentHandle, type DocumentListState} from './documentListStore'\n\nexport interface DocumentListQueryResult {\n count: number\n results: DocumentHandle[]\n}\n\nexport const subscribeToStateAndFetchResults = createInternalAction(\n ({state, instance}: ActionContext<DocumentListState>) => {\n return function () {\n const client$ = new Observable<SanityClient>((observer) =>\n getSubscribableClient(instance, {apiVersion: API_VERSION}).subscribe(observer),\n )\n\n const fetchInput$ = state.observable.pipe(\n map((s) => pick(s, 'options', 'limit', 'lastLiveEventId')),\n distinctUntilChanged(isEqual as <T>(a: T, b: T) => boolean),\n )\n\n return fetchInput$\n .pipe(\n withLatestFrom(client$),\n debounceTime(0),\n tap(() => {\n state.set('setPending', {isPending: true})\n }),\n switchMap(([{options, limit, lastLiveEventId}, client]) => {\n const filter = options.filter ? `[${options.filter}]` : ''\n const order = options.sort\n ? `| order(${options.sort\n .map((ordering) =>\n [ordering.field, ordering.direction.toLowerCase()]\n .map((str) => str.trim())\n .filter(Boolean)\n .join(' '),\n )\n .join(',')})`\n : ''\n\n const resultsQuery = `*${filter}${order}[0...$__limit]{_id, _type}`\n const countQuery = `count(*${filter})`\n\n return client.observable.fetch<DocumentListQueryResult>(\n `{\"count\":${countQuery},\"results\":${resultsQuery}}`,\n {__limit: limit},\n {\n filterResponse: false,\n returnQuery: false,\n lastLiveEventId,\n tag: 'sdk.document-list',\n perspective: 'previewDrafts',\n },\n )\n }),\n )\n .subscribe({\n next: ({syncTags, result: {count, results}}) => {\n state.set('updateFromFetch', {\n syncTags,\n results,\n count,\n isPending: false,\n })\n },\n })\n }\n },\n)\n","import {type SyncTag} from '@sanity/client'\nimport {type SortOrderingItem} from '@sanity/types'\nimport {createSelector} from 'reselect'\n\nimport {createAction} from '../resources/createAction'\nimport {createResource} from '../resources/createResource'\nimport {createStateSourceAction} from '../resources/createStateSourceAction'\nimport {createStore} from '../resources/createStore'\nimport {PAGE_SIZE} from './documentListConstants'\nimport {subscribeToLiveClientAndSetLastLiveEventId} from './subscribeToLiveClientAndSetLastLiveEventId'\nimport {subscribeToStateAndFetchResults} from './subscribeToStateAndFetchResults'\n\n/**\n * Configuration options for filtering and sorting documents in a document list.\n * @public\n */\nexport interface DocumentListOptions {\n /** GROQ filter expression to query specific documents */\n filter?: string\n /** Array of sort ordering specifications to determine the order of results */\n sort?: SortOrderingItem[]\n /** The Content Lake perspective to use for this list. Defaults to `previewDrafts`. */\n perspective?: string\n}\n\n/**\n * Represents an identifier to a Sanity document, containing its `_id` to pull\n * the document from content lake and its `_type` to look up its schema type.\n * @public\n */\nexport interface DocumentHandle {\n _id: string\n _type: string\n}\n\n/**\n * @public\n */\nexport interface DocumentListState {\n options: DocumentListOptions\n lastLiveEventId?: string\n syncTags: SyncTag[]\n limit: number\n count: number\n results: DocumentHandle[]\n isPending: boolean\n}\n\nconst documentList = createResource<DocumentListState>({\n name: 'documentList',\n getInitialState: () => ({\n limit: PAGE_SIZE,\n options: {perspective: 'previewDrafts'},\n results: [],\n syncTags: [],\n isPending: false,\n count: 0,\n }),\n initialize() {\n const stateSubscription = subscribeToStateAndFetchResults(this)\n const liveClientSubscription = subscribeToLiveClientAndSetLastLiveEventId(this)\n\n return () => {\n stateSubscription.unsubscribe()\n liveClientSubscription.unsubscribe()\n }\n },\n})\n\nconst getState = createStateSourceAction(\n documentList,\n createSelector(\n [\n (state: DocumentListState) => state.results,\n (state: DocumentListState) => state.count,\n (state: DocumentListState) => state.isPending,\n ],\n (results, count, isPending) => ({\n results,\n isPending,\n count,\n hasMore: results.length < count,\n }),\n ),\n)\n\nconst setOptions = createAction(documentList, ({state}) => {\n return function (options: DocumentListOptions) {\n state.set('setOptions', (prev) => ({\n options: {\n ...prev.options,\n ...options,\n },\n }))\n }\n})\n\nconst loadMore = createAction(documentList, ({state}) => {\n return function () {\n state.set('loadMore', (prev) => ({limit: prev.limit + PAGE_SIZE}))\n }\n})\n\n/**\n * @public\n */\nexport const createDocumentListStore = createStore(documentList, {\n getState,\n loadMore,\n setOptions,\n})\n","import {type AuthProvider} from '@sanity/client'\n\nimport {createAction} from '../resources/createAction'\nimport {DEFAULT_API_VERSION, REQUEST_TAG_PREFIX} from './authConstants'\nimport {authStore} from './authStore'\nimport {getDefaultLocation} from './utils'\n\n/**\n * @public\n */\nexport const fetchLoginUrls = createAction(authStore, ({state, instance}) => {\n const {projectId, dataset} = instance.identity\n const {callbackUrl, clientFactory, apiHost, authScope, customProviders} = state.get().options\n const client = clientFactory({\n projectId,\n dataset,\n apiVersion: DEFAULT_API_VERSION,\n requestTagPrefix: REQUEST_TAG_PREFIX,\n useProjectHostname: authScope === 'project',\n ...(apiHost && {apiHost}),\n })\n\n return async function () {\n const cachedProviders = state.get().providers\n if (cachedProviders) return cachedProviders\n\n const {providers: defaultProviders} = await client.request<{providers: AuthProvider[]}>({\n uri: '/auth/providers',\n tag: 'fetch-providers',\n })\n\n let providers: AuthProvider[]\n\n if (typeof customProviders === 'function') {\n providers = await customProviders(defaultProviders)\n } else if (!customProviders?.length) {\n providers = defaultProviders\n } else {\n const customProviderUrls = new Set(customProviders.map((p) => p.url))\n providers = defaultProviders\n .filter((official) => !customProviderUrls.has(official.url))\n .concat(customProviders)\n }\n\n const configuredProviders = providers.map((provider) => {\n const url = new URL(provider.url)\n const origin = new URL(\n callbackUrl\n ? new URL(callbackUrl, new URL(getDefaultLocation()).origin).toString()\n : getDefaultLocation(),\n )\n\n // `getDefaultLocation()` may be populated with an `sid` from a previous\n // failed login attempt and should be omitted from the next login URL\n const hashParams = new URLSearchParams(origin.hash.slice(1))\n hashParams.delete('sid')\n origin.hash = hashParams.toString()\n origin.searchParams.delete('sid')\n origin.searchParams.delete('url')\n\n // similarly, the origin may be populated with an `error` query param if\n // the auth provider redirects back to the application. this should also\n // be omitted from the origin sent\n origin.searchParams.delete('error')\n\n url.searchParams.set('origin', origin.toString())\n url.searchParams.set('withSid', 'true')\n url.searchParams.set('type', 'stampedToken')\n if (authScope === 'project') {\n url.searchParams.set('projectId', projectId)\n }\n\n return {...provider, url: url.toString()}\n })\n\n state.set('fetchedLoginUrls', {providers: configuredProviders})\n\n return configuredProviders\n }\n})\n","import {createAction} from '../resources/createAction'\nimport {DEFAULT_API_VERSION, REQUEST_TAG_PREFIX} from './authConstants'\nimport {AuthStateType} from './authStateType'\nimport {authStore} from './authStore'\nimport {getAuthCode, getDefaultLocation} from './utils'\n\n/**\n * @public\n */\nexport const handleCallback = createAction(authStore, ({state, instance}) => {\n const {projectId, dataset} = instance.identity\n const {providedToken, callbackUrl, clientFactory, apiHost, authScope, storageArea, storageKey} =\n state.get().options\n\n return async function (locationHref: string = getDefaultLocation()) {\n // If a token is provided, no need to handle callback\n if (providedToken) return false\n\n // Don't handle the callback if already in flight.\n const {authState} = state.get()\n if (authState.type === AuthStateType.LOGGING_IN && authState.isExchangingToken) return false\n\n // If there is no matching `authCode` then we can't handle the callback\n const authCode = getAuthCode(callbackUrl, locationHref)\n if (!authCode) return false\n\n // Otherwise, start the exchange\n state.set('exchangeSessionForToken', {\n authState: {type: AuthStateType.LOGGING_IN, isExchangingToken: true},\n })\n\n try {\n const client = clientFactory({\n projectId,\n dataset,\n apiVersion: DEFAULT_API_VERSION,\n requestTagPrefix: REQUEST_TAG_PREFIX,\n useProjectHostname: authScope === 'project',\n ...(apiHost && {apiHost}),\n })\n\n const {token} = await client.request<{token: string; label: string}>({\n method: 'GET',\n uri: '/auth/fetch',\n query: {sid: authCode},\n tag: 'fetch-token',\n })\n\n storageArea?.setItem(storageKey, JSON.stringify({token}))\n state.set('setToken', {authState: {type: AuthStateType.LOGGED_IN, token, currentUser: null}})\n\n const loc = new URL(locationHref)\n loc.hash = ''\n loc.searchParams.delete('sid')\n loc.searchParams.delete('url')\n return loc.toString()\n } catch (error) {\n state.set('exchangeSessionForTokenError', {authState: {type: AuthStateType.ERROR, error}})\n return false\n }\n }\n})\n","import {createAction} from '../resources/createAction'\nimport {DEFAULT_API_VERSION, REQUEST_TAG_PREFIX} from './authConstants'\nimport {AuthStateType} from './authStateType'\nimport {authStore} from './authStore'\n\n/**\n * @public\n */\nexport const logout = createAction(authStore, ({state, instance}) => {\n const {projectId, dataset} = instance.identity\n const {clientFactory, apiHost, authScope, providedToken, storageArea, storageKey} =\n state.get().options\n\n return async function () {\n // If a token is statically provided, logout does nothing\n if (providedToken) return\n\n const {authState} = state.get()\n\n // If we already have an inflight request, no-op\n if (authState.type === AuthStateType.LOGGED_OUT && authState.isDestroyingSession) return\n const token = authState.type === AuthStateType.LOGGED_IN && authState.token\n\n try {\n if (token) {\n state.set('loggingOut', {\n authState: {type: AuthStateType.LOGGED_OUT, isDestroyingSession: true},\n })\n\n const client = clientFactory({\n token,\n projectId,\n dataset,\n requestTagPrefix: REQUEST_TAG_PREFIX,\n apiVersion: DEFAULT_API_VERSION,\n useProjectHostname: authScope === 'project',\n ...(apiHost && {apiHost}),\n })\n\n await client.request<void>({uri: '/auth/logout', method: 'POST'})\n }\n } finally {\n state.set('logoutSuccess', {\n authState: {type: AuthStateType.LOGGED_OUT, isDestroyingSession: false},\n })\n storageArea?.removeItem(storageKey)\n }\n }\n})\n","import {Schema as SchemaConstructor} from '@sanity/schema'\nimport {type Schema, type SchemaTypeDefinition} from '@sanity/types'\n\nimport {createResource} from '../resources/createResource'\n\n/**\n * @public\n */\nexport interface SchemaConfig {\n types: SchemaTypeDefinition[]\n}\n\n/**\n * @public\n */\nexport interface SchemaManagerState {\n schema: Schema\n}\n\nexport const schemaManager = createResource<SchemaManagerState>({\n name: 'schemaManager',\n getInitialState(instance) {\n const {config} = instance\n const schema = SchemaConstructor.compile({\n name: 'default',\n types: config.schema?.types ?? [],\n })\n\n // TODO: check for schema errors and warn on schema warnings\n\n return {schema}\n },\n})\n","import {getEnv} from '../utils/getEnv'\nimport {type PreviewValue, type ValuePending} from './previewStore'\n\nexport const PREVIEW_TAG = 'sdk.preview'\nexport const STABLE_EMPTY_PREVIEW: ValuePending<PreviewValue> = {results: null, isPending: false}\nexport const STABLE_ERROR_PREVIEW: ValuePending<PreviewValue> = {\n results: {\n title: 'Preview Error',\n ...(!!getEnv('DEV') && {subtitle: 'Check the console for more details'}),\n },\n isPending: false,\n}\n\nexport function getPublishedId(id: string): string {\n const draftsPrefix = 'drafts.'\n return id.startsWith(draftsPrefix) ? id.slice(draftsPrefix.length) : id\n}\n\nexport function getDraftId(id: string): string {\n const draftsPrefix = 'drafts.'\n return id.startsWith(draftsPrefix) ? id : `${draftsPrefix}${id}`\n}\n\nexport function randomId(): string {\n return Array.from({length: 8}, () =>\n Math.floor(Math.random() * 16)\n .toString(16)\n .padStart(2, '0'),\n ).join('')\n}\n\nexport function hashString(str: string): string {\n // Using a large prime number for the hash\n const PRIME = 31\n // Using a max 32-bit integer to prevent overflow\n const MOD = 2147483647\n\n let hash = 0\n\n // Process chunks of the string to reduce complexity\n for (let i = 0; i < str.length; i++) {\n // Rolling hash computation\n hash = (hash * PRIME + str.charCodeAt(i)) % MOD\n }\n\n // Ensure we return a positive hash\n return Math.abs(hash).toString(16).padStart(8, '0')\n}\n","import {type SanityClient} from '@sanity/client'\nimport {combineLatest, distinctUntilChanged, filter, map, Observable, switchMap} from 'rxjs'\n\nimport {getSubscribableClient} from '../client/actions/getSubscribableClient'\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {type PreviewStoreState} from './previewStore'\nimport {PREVIEW_TAG} from './util'\n\nexport const subscribeToLiveAndSetLastLiveEventId = createInternalAction(\n ({instance, state}: ActionContext<PreviewStoreState>) => {\n const client$ = new Observable<SanityClient>((observer) =>\n getSubscribableClient(instance, {apiVersion: 'vX'}).subscribe(observer),\n )\n const syncTags$ = state.observable.pipe(\n map((i) => i.syncTags),\n distinctUntilChanged(),\n )\n\n return function () {\n const messageEvents$ = client$.pipe(\n switchMap((client) =>\n client.live\n .events({includeDrafts: !!client.config().token, tag: PREVIEW_TAG})\n .pipe(filter((e): e is Extract<typeof e, {type: 'message'}> => e.type === 'message')),\n ),\n )\n\n return combineLatest([messageEvents$, syncTags$]).subscribe({\n next: ([event, currentSyncTags]) => {\n for (const tag of event.tags) {\n if (currentSyncTags[tag]) {\n state.set('setLastLiveEventId', {lastLiveEventId: event.id})\n return\n }\n }\n },\n })\n }\n },\n)\n","import {createStateSourceAction} from '../resources/createStateSourceAction'\nimport {schemaManager} from './schemaManager'\n\nexport const getSchemaState = createStateSourceAction(schemaManager, (state) => state.schema)\n","import {type ReferenceSchemaType, type Schema, type SchemaType} from '@sanity/types'\n\nexport function getProjectionForSchemaType(schema: Schema, schemaTypeName: string): string {\n const schemaType = schema.get(schemaTypeName)\n if (!schemaType) {\n throw new Error(`Could not find type \\`${schemaTypeName}\\` in the provided schema.`)\n }\n\n return `{${Object.entries(schemaType.preview?.select ?? {})\n .map(([key, path]) => {\n return `${JSON.stringify(key)}:${getGroqFromPath(schema, schemaType, path)}`\n })\n .join(',')}}`\n}\n\nfunction isReferenceType(\n type: SchemaType | undefined,\n visited = new Set<SchemaType>(),\n): type is ReferenceSchemaType {\n if (!type) return false\n if (visited.has(type)) return false\n visited.add(type)\n\n if (type.name === 'reference') return true\n return isReferenceType(type.type, visited)\n}\n\ntype PathSegment =\n | {type: 'attribute'; name: string}\n | {type: 'element'; index: number}\n | {type: 'deref'}\n\nfunction printPath(segments: PathSegment[]): string {\n return segments.reduce((acc, segment) => {\n if (segment.type === 'deref') return `${acc}->`\n if (segment.type === 'element') return `${acc}[${segment.index}]`\n if (acc.endsWith('->')) return `${acc}${segment.name}`\n return [acc, segment.name].filter(Boolean).join('.')\n }, '')\n}\n\nconst cache = new WeakMap<SchemaType, Map<string, string>>()\n\nfunction getGroqFromPath(schema: Schema, node: SchemaType, path: string): string {\n const cached = cache.get(node)?.get(path)\n if (cached) return cached\n\n const possiblePaths = Array.from(\n new Set(resolveAllPaths(schema, node, path.split('.')).map(printPath)),\n )\n if (!possiblePaths.length) {\n // TODO: bubble this instead of warning\n // eslint-disable-next-line no-console\n console.warn(`Could not resolve path \\`${path}\\` from schema type \\`${node.name}\\`.`)\n return 'null'\n }\n\n const result =\n possiblePaths.length === 1 ? possiblePaths[0] : `coalesce(${possiblePaths.join(',')})`\n\n if (!cache.has(node)) {\n cache.set(node, new Map())\n }\n const mapByPaths = cache.get(node)!\n mapByPaths.set(path, result)\n\n return result\n}\n\nfunction resolveAllPaths(schema: Schema, schemaType: SchemaType, path: string[]): PathSegment[][] {\n const [name, ...rest] = path\n if (name?.startsWith('_')) {\n return [\n [\n {type: 'attribute', name},\n ...rest.map(\n (next): PathSegment =>\n /\\d+/.test(next)\n ? {type: 'element', index: parseInt(next, 10)}\n : {type: 'attribute', name: next},\n ),\n ],\n ]\n } else if (!name) {\n return [[]]\n } else if (isReferenceType(schemaType)) {\n return schemaType.to.flatMap((referenceType) =>\n resolveAllPaths(schema, referenceType, path).map((nextPath): PathSegment[] => [\n {type: 'deref'},\n ...nextPath,\n ]),\n )\n } else if (schemaType.jsonType === 'object') {\n const fieldType = schemaType.fields.find((field) => field.name === name)?.type\n if (!fieldType) return []\n\n return resolveAllPaths(schema, fieldType, rest).map((nextPath): PathSegment[] => [\n {type: 'attribute', name},\n ...nextPath,\n ])\n } else if (schemaType.jsonType === 'array') {\n const index = parseInt(name, 10)\n return schemaType.of.flatMap((itemType) =>\n resolveAllPaths(schema, itemType, rest).map((nextPath): PathSegment[] => [\n {type: 'element', index},\n ...nextPath,\n ]),\n )\n } else {\n return []\n }\n}\n","import {type Schema} from '@sanity/types'\n\nimport {getProjectionForSchemaType} from './getProjectionForSchemaType'\nimport {\n type PreviewQueryResult,\n type PreviewStoreState,\n type PreviewValue,\n type ValuePending,\n} from './previewStore'\nimport {\n getDraftId,\n getPublishedId,\n hashString,\n STABLE_EMPTY_PREVIEW,\n STABLE_ERROR_PREVIEW,\n} from './util'\n\ninterface ProcessPreviewQueryOptions {\n projectId: string\n dataset: string\n schema: Schema\n ids: Set<string>\n documentTypes: {[TDocumentId in string]?: string}\n results: PreviewQueryResult[]\n}\n\nfunction defaultPrepare(value: Record<string, unknown>): PreviewValue {\n let title\n let subtitle\n\n if ('title' in value) {\n if (typeof value['title'] === 'string') {\n title = value['title']\n }\n }\n\n if ('subtitle' in value) {\n if (typeof value['subtitle'] === 'string') {\n subtitle = value['subtitle']\n }\n }\n\n return {title: title ?? 'Untitled', subtitle}\n}\n\nfunction hasImageAsset<T>(value: unknown): value is T & {asset: {_ref: string}} {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'asset' in value &&\n typeof (value as {asset: unknown}).asset === 'object' &&\n typeof (value as {asset: {_ref: unknown}}).asset?._ref === 'string'\n )\n}\n\nfunction assetIdToUrl(assetId: string, projectId: string, dataset: string) {\n const pattern = /^image-(?<assetName>[A-Za-z0-9]+)-(?<dimensions>\\d+x\\d+)-(?<format>[a-z]+)$/\n const match = assetId.match(pattern)\n if (!match?.groups) {\n throw new Error(\n `Invalid asset ID \\`${assetId}\\`. Expected: image-{assetName}-{width}x{height}-{format}`,\n )\n }\n\n const {assetName, dimensions, format} = match.groups\n return `https://cdn.sanity.io/images/${projectId}/${dataset}/${assetName}-${dimensions}.${format}`\n}\n\nexport function normalizeMedia(\n media: unknown,\n projectId: string,\n dataset: string,\n): PreviewValue['media'] {\n if (!media) return null\n if (!hasImageAsset(media)) return null\n return {type: 'image-asset', url: assetIdToUrl(media.asset._ref, projectId, dataset)}\n}\n\ninterface PreparePreviewForSchemaTypeOptions {\n projectId: string\n dataset: string\n schema: Schema\n schemaTypeName: string\n selectResult: PreviewQueryResult['select']\n}\n\nexport function preparePreviewForSchemaType({\n projectId,\n dataset,\n schema,\n schemaTypeName,\n selectResult,\n}: PreparePreviewForSchemaTypeOptions): Omit<PreviewValue, 'status'> {\n const schemaType = schema.get(schemaTypeName)\n if (!schemaType) {\n throw new Error(\n `Could not find schema type \\`${schemaTypeName}\\` in schema \\`${schema.name}\\`.`,\n )\n }\n const prepare = (schemaType.preview?.prepare ?? defaultPrepare) as (val: unknown) => PreviewValue\n\n try {\n const result = prepare(selectResult)\n return {...result, media: normalizeMedia(result.media, projectId, dataset)}\n } catch (e) {\n const message =\n typeof e === 'object' && e && 'message' in e && typeof e.message === 'string'\n ? e.message\n : 'Unknown error.'\n\n throw new Error(`Failed to prepare preview: ${message}`, {cause: e})\n }\n}\n\nexport function processPreviewQuery({\n projectId,\n dataset,\n schema,\n ids,\n documentTypes,\n results,\n}: ProcessPreviewQueryOptions): PreviewStoreState['values'] {\n const resultMap = results.reduce<{[TDocumentId in string]?: PreviewQueryResult}>((acc, next) => {\n acc[next._id] = next\n return acc\n }, {})\n\n return Object.fromEntries(\n Array.from(ids).map((id): [string, ValuePending<PreviewValue>] => {\n const publishedId = getPublishedId(id)\n const draftId = getDraftId(id)\n\n const draftResult = resultMap[draftId]\n const publishedResult = resultMap[publishedId]\n const documentType = documentTypes[publishedId]\n if (!documentType) return [id, STABLE_EMPTY_PREVIEW]\n\n const selectResult = draftResult?.select ?? publishedResult?.select\n if (!selectResult) return [id, STABLE_EMPTY_PREVIEW]\n\n try {\n const preview = preparePreviewForSchemaType({\n projectId,\n dataset,\n schema,\n schemaTypeName: documentType,\n selectResult,\n })\n const status: PreviewValue['status'] = {\n ...(draftResult?._updatedAt && {lastEditedDraftAt: draftResult._updatedAt}),\n ...(publishedResult?._updatedAt && {lastEditedPublishedAt: publishedResult._updatedAt}),\n }\n\n return [id, {results: {...preview, status}, isPending: false}]\n } catch (e) {\n // TODO: replace this with bubbling the error\n // eslint-disable-next-line no-console\n console.warn(e)\n return [id, STABLE_ERROR_PREVIEW]\n }\n }),\n )\n}\n\ntype ProjectionMap = Record<string, {projection: string; documentTypes: Set<string>}>\n\ninterface CreatePreviewQueryResult {\n query: string\n params: Record<string, string[]>\n}\n\nexport function createPreviewQuery(\n documentIds: Set<string>,\n documentTypes: {[TDocumentId in string]?: string},\n schema: Schema,\n): CreatePreviewQueryResult {\n const documentIdsByDocumentType = Array.from(documentIds).reduce<Record<string, Set<string>>>(\n (acc, id) => {\n const documentType = documentTypes[id]\n if (!documentType) return acc\n\n const ids = acc[documentType] ?? new Set()\n ids.add(id)\n acc[documentType] = ids\n\n return acc\n },\n {},\n )\n\n const projections = Object.keys(documentIdsByDocumentType)\n .map((documentType) => {\n const projection = getProjectionForSchemaType(schema, documentType)\n const projectionHash = hashString(projection)\n return {documentType, projection, projectionHash}\n })\n .reduce<ProjectionMap>((acc, {documentType, projection, projectionHash}) => {\n const obj = acc[projectionHash] ?? {documentTypes: new Set(), projection}\n obj.documentTypes.add(documentType)\n\n acc[projectionHash] = obj\n return acc\n }, {})\n\n const query = `[${Object.entries(projections)\n .map(([projectionHash, {projection}]) => {\n return `...*[_id in $__ids_${projectionHash}]{_id,_type,_updatedAt,\"select\":${projection}}`\n })\n .join(',')}]`\n\n const params = Object.fromEntries(\n Object.entries(projections).map(([projectionHash, value]) => {\n const idsInProjection = Array.from(\n Array.from(value.documentTypes)\n .map((documentType) => documentIdsByDocumentType[documentType] ?? new Set<string>())\n .reduce((acc, next) => {\n for (const i of next) acc.add(i)\n return acc\n }, new Set<string>()),\n ).flatMap((id) => [getPublishedId(id), getDraftId(id)])\n\n return [`__ids_${projectionHash}`, Array.from(idsInProjection)]\n }),\n )\n\n return {query, params}\n}\n","import {type SanityClient, type SyncTag} from '@sanity/client'\nimport {\n combineLatest,\n debounceTime,\n distinctUntilChanged,\n EMPTY,\n map,\n Observable,\n pairwise,\n startWith,\n switchMap,\n tap,\n withLatestFrom,\n} from 'rxjs'\n\nimport {getSubscribableClient} from '../client/actions/getSubscribableClient'\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {getSchemaState} from '../schema/getSchemaState'\nimport {createPreviewQuery, processPreviewQuery} from './previewQuery'\nimport {type PreviewQueryResult, type PreviewStoreState} from './previewStore'\nimport {PREVIEW_TAG} from './util'\n\nconst BATCH_DEBOUNCE_TIME = 50\n\nexport const subscribeToStateAndFetchBatches = createInternalAction(\n ({state, instance}: ActionContext<PreviewStoreState>) => {\n return function () {\n const client$ = new Observable<SanityClient>((observer) =>\n getSubscribableClient(instance, {apiVersion: 'vX'}).subscribe(observer),\n )\n const schema$ = getSchemaState(instance).observable\n const documentTypes$ = state.observable.pipe(\n map((i) => i.documentTypes),\n distinctUntilChanged(),\n )\n const lastLiveEventId$ = state.observable.pipe(\n map((i) => i.lastLiveEventId),\n distinctUntilChanged(),\n )\n\n const newSubscriberIds$ = state.observable.pipe(\n map(({subscriptions}) => new Set(Object.keys(subscriptions))),\n distinctUntilChanged((a, b) =>\n a.size !== b.size ? false : Array.from(a).every((i) => b.has(i)),\n ),\n debounceTime(BATCH_DEBOUNCE_TIME),\n startWith(new Set<string>()),\n pairwise(),\n tap(([prevIds, currIds]) => {\n // for all new subscriptions, set their values to pending\n const newIds = [...currIds].filter((element) => !prevIds.has(element))\n state.set('updatingPending', (prev) => {\n const pendingValues = newIds.reduce<PreviewStoreState['values']>((acc, id) => {\n const prevValue = prev.values[id]\n const value = prevValue?.results ? prevValue.results : null\n acc[id] = {results: value, isPending: true}\n return acc\n }, {})\n return {values: {...prev.values, ...pendingValues}}\n })\n }),\n withLatestFrom(documentTypes$),\n map(([[, ids], documentTypes]) => ({ids, documentTypes})),\n )\n\n return combineLatest([newSubscriberIds$, lastLiveEventId$, client$, schema$])\n .pipe(\n switchMap(([{ids, documentTypes}, lastLiveEventId, client, schema]) => {\n if (!ids.size) return EMPTY\n const {query, params} = createPreviewQuery(ids, documentTypes, schema)\n\n return client.observable\n .fetch<PreviewQueryResult[]>(query, params, {\n filterResponse: false,\n returnQuery: false,\n tag: PREVIEW_TAG,\n lastLiveEventId,\n })\n .pipe(map((response) => ({...response, ids, schema, documentTypes})))\n }),\n map(({ids, result, syncTags, documentTypes, schema}) => ({\n syncTags,\n values: processPreviewQuery({\n projectId: instance.identity.projectId,\n dataset: instance.identity.dataset,\n ids,\n documentTypes,\n results: result,\n schema,\n }),\n })),\n )\n .subscribe({\n next: ({syncTags = [], values}) => {\n state.set('updateResult', (prev) => ({\n values: {...prev.values, ...values},\n syncTags: syncTags.reduce<Record<SyncTag, true>>((acc, next) => {\n acc[next] = true\n return acc\n }, {}),\n }))\n },\n })\n }\n },\n)\n","import {type SyncTag} from '@sanity/client'\n\nimport {createResource} from '../resources/createResource'\nimport {subscribeToLiveAndSetLastLiveEventId} from './subscribeToLiveAndSetLastLiveEventId'\nimport {subscribeToStateAndFetchBatches} from './subscribeToStateAndFetchBatches'\n\nexport interface PreviewQueryResult {\n _id: string\n _type: string\n _updatedAt: string\n select: Record<string, unknown>\n}\n\n/**\n * Represents the set of values displayed as a preview for a given Sanity document.\n * This includes a primary title, a secondary subtitle, and optional media associated\n * with the document.\n *\n * @public\n */\nexport interface PreviewValue {\n /**\n * The primary text displayed for the document preview.\n */\n title: string\n\n /**\n * A secondary line of text providing additional context about the document.\n */\n subtitle?: string\n\n /**\n * An optional media object, commonly representing an image, that is associated\n * with the document and displayed as part of the preview.\n */\n media?: {type: 'image-asset'; url: string} | null\n\n status?: {\n lastEditedPublishedAt?: string\n lastEditedDraftAt?: string\n }\n}\n\n/**\n * Represents the current state of a preview value along with a flag indicating whether\n * the preview data is still being fetched or is fully resolved.\n *\n * The tuple contains a preview value or null, and a boolean indicating if the data is\n * pending. A `true` value means a fetch is ongoing; `false` indicates that the\n * currently provided preview value is up-to-date.\n *\n * @public\n */\nexport type ValuePending<T> = {\n results: T | null\n isPending: boolean\n}\n\n/**\n * @public\n */\nexport interface PreviewStoreState {\n values: {[TDocumentId in string]?: ValuePending<PreviewValue>}\n documentTypes: {[TDocumentId in string]?: string}\n subscriptions: {[TDocumentId in string]?: {[TSubscriptionId in string]?: true}}\n syncTags: Record<SyncTag, true>\n lastLiveEventId: string | null\n}\n\nexport const previewStore = createResource<PreviewStoreState>({\n name: 'Preview',\n getInitialState() {\n return {\n documentTypes: {},\n lastLiveEventId: null,\n subscriptions: {},\n syncTags: {},\n values: {},\n }\n },\n initialize() {\n const stateSubscriptionForBatches = subscribeToStateAndFetchBatches(this)\n const liveSubscription = subscribeToLiveAndSetLastLiveEventId(this)\n\n return () => {\n stateSubscriptionForBatches.unsubscribe()\n liveSubscription.unsubscribe()\n }\n },\n})\n","import {omit} from 'lodash-es'\n\nimport {type DocumentHandle} from '../documentList/documentListStore'\nimport {createAction} from '../resources/createAction'\nimport {createStateSourceAction, type StateSource} from '../resources/createStateSourceAction'\nimport {\n previewStore,\n type PreviewStoreState,\n type PreviewValue,\n type ValuePending,\n} from './previewStore'\nimport {getPublishedId, randomId, STABLE_EMPTY_PREVIEW} from './util'\n\n/**\n * @public\n */\nexport interface GetPreviewStateOptions {\n document: DocumentHandle\n}\n\nconst _getPreviewState = createStateSourceAction(\n previewStore,\n (state, {document}: GetPreviewStateOptions) => state.values[document._id] ?? STABLE_EMPTY_PREVIEW,\n)\n\n/**\n * @public\n */\nexport const getPreviewState = createAction(previewStore, ({state}) => {\n return function ({document}: GetPreviewStateOptions): StateSource<ValuePending<PreviewValue>> {\n const {_id, _type: documentType} = document\n const documentId = getPublishedId(_id)\n const previewState = _getPreviewState(this, {document})\n\n return {\n ...previewState,\n subscribe: (subscriber) => {\n const subscriptionId = randomId()\n\n state.set('addSubscription', (prev) => ({\n documentTypes: {\n ...prev.documentTypes,\n [documentId]: documentType,\n },\n subscriptions: {\n ...prev.subscriptions,\n [documentId]: {\n ...prev.subscriptions[documentId],\n [subscriptionId]: true,\n },\n },\n }))\n\n const unsubscribe = previewState.subscribe(subscriber)\n\n return () => {\n unsubscribe()\n\n state.set('removeSubscription', (prev): Partial<PreviewStoreState> => {\n const documentSubscriptions = omit(prev.subscriptions[documentId], subscriptionId)\n const hasSubscribers = !!Object.keys(documentSubscriptions).length\n const prevValue = prev.values[documentId]\n const previewValue = prevValue?.results ? prevValue.results : null\n\n return {\n subscriptions: hasSubscribers\n ? {...prev.subscriptions, [documentId]: documentSubscriptions}\n : omit(prev.subscriptions, documentId),\n values: hasSubscribers\n ? prev.values\n : {...prev.values, [documentId]: {results: previewValue, isPending: false}},\n }\n })\n }\n },\n }\n }\n})\n","import {type DocumentHandle} from '../documentList/documentListStore'\nimport {createAction} from '../resources/createAction'\nimport {getPreviewState} from './getPreviewState'\nimport {previewStore, type PreviewValue, type ValuePending} from './previewStore'\n\n/**\n * @public\n */\nexport interface ResolvePreviewOptions {\n document: DocumentHandle\n}\n\n/**\n * @public\n */\nexport const resolvePreview = createAction(previewStore, () => {\n return function ({document}: ResolvePreviewOptions) {\n const {getCurrent, subscribe} = getPreviewState(this, {document})\n\n return new Promise<ValuePending<PreviewValue>>((resolve) => {\n const unsubscribe = subscribe(() => {\n const current = getCurrent()\n if (current?.results) {\n resolve(current)\n unsubscribe()\n }\n })\n })\n }\n})\n","import {type ChannelInput, type ChannelInstance, type Controller} from '@sanity/comlink'\n\nimport {createResource} from '../../resources/createResource'\nimport {type FrameMessage, type WindowMessage} from '../types'\nimport {destroyController} from './actions/destroyController'\n\n/**\n * Individual channel with its relevant options\n * @public\n */\nexport interface ChannelEntry {\n channel: ChannelInstance<FrameMessage, WindowMessage>\n // we store options to ensure that channels remain as unique / consistent as possible\n options: ChannelInput\n // we store refCount to ensure channels remain open only as long as they are in use\n refCount: number\n}\n\n/**\n * Internal state tracking comlink connections\n * @public\n */\nexport interface ComlinkControllerState {\n controller: Controller | null\n controllerOrigin: string | null\n channels: Map<string, ChannelEntry>\n}\n\nexport const comlinkControllerStore = createResource<ComlinkControllerState>({\n name: 'connectionStore',\n getInitialState: () => {\n const initialState = {\n controller: null,\n controllerOrigin: null,\n channels: new Map(),\n }\n return initialState\n },\n initialize() {\n return () => {\n // destroying controller also destroys channels\n destroyController(this)\n }\n },\n})\n","import {createInternalAction} from '../../../resources/createAction'\nimport {type ComlinkControllerState} from '../comlinkControllerStore'\n\n/**\n * Calls the destroy method on the controller and resets the controller state.\n * @public\n */\nexport const destroyController = createInternalAction<ComlinkControllerState, [], void>(\n ({state}) => {\n return () => {\n const {controller} = state.get()\n\n if (controller) {\n controller.destroy()\n state.set('destroyController', {\n controller: null,\n channels: new Map(),\n })\n }\n }\n },\n)\n","import {type ChannelInput} from '@sanity/comlink'\nimport {isEqual} from 'lodash-es'\n\nimport {createAction} from '../../../resources/createAction'\nimport {comlinkControllerStore} from '../comlinkControllerStore'\n\n/**\n * Retrieve or create a channel to be used for communication between\n * an application and the controller.\n * @public\n */\nexport const getOrCreateChannel = createAction(comlinkControllerStore, ({state}) => {\n return (options: ChannelInput) => {\n const controller = state.get().controller\n\n if (!controller) {\n throw new Error('Controller must be initialized before using or creating channels')\n }\n\n const channels = state.get().channels\n const existing = channels.get(options.name)\n\n // limit channels to one per name\n if (existing) {\n if (!isEqual(existing.options, options)) {\n throw new Error(`Channel \"${options.name}\" already exists with different options`)\n }\n\n state.set('incrementChannelRefCount', {\n channels: new Map(channels).set(options.name, {\n ...existing,\n refCount: existing.refCount + 1,\n }),\n })\n existing.channel.start()\n return existing.channel\n }\n\n const channel = controller.createChannel(options)\n channel.start()\n state.set('createChannel', {\n channels: new Map(channels).set(options.name, {\n channel,\n options,\n refCount: 1,\n }),\n })\n\n return channel\n }\n})\n","import {createController} from '@sanity/comlink'\n\nimport {createAction} from '../../../resources/createAction'\nimport {comlinkControllerStore} from '../comlinkControllerStore'\nimport {destroyController} from './destroyController'\n\n/**\n * Initializes or fetches a controller to handle communication\n * between an application and iframes.\n * @public\n */\nexport const getOrCreateController = createAction(comlinkControllerStore, ({state, instance}) => {\n return (targetOrigin: string) => {\n const {controller, controllerOrigin} = state.get()\n if (controller && controllerOrigin === targetOrigin) {\n return controller\n }\n\n // if the target origin has changed, we'll create a new controller,\n // but need to clean up first\n if (controller) {\n destroyController({state, instance})\n }\n\n const newController = createController({targetOrigin})\n state.set('initializeController', {\n controllerOrigin: targetOrigin,\n controller: newController,\n })\n\n return newController\n }\n})\n","import {createAction} from '../../../resources/createAction'\nimport {comlinkControllerStore} from '../comlinkControllerStore'\n\n/**\n * Signals to the store that the consumer has stopped using the channel\n * @public\n */\nexport const releaseChannel = createAction(comlinkControllerStore, ({state}) => {\n return (name: string) => {\n const channels = state.get().channels\n const channelEntry = channels.get(name)\n\n if (channelEntry) {\n const newRefCount = channelEntry.refCount === 0 ? 0 : channelEntry.refCount - 1\n state.set('releaseChannel', {\n channels: new Map(channels).set(name, {\n ...channelEntry,\n refCount: newRefCount,\n }),\n })\n if (newRefCount === 0) {\n channelEntry.channel.stop()\n }\n }\n }\n})\n","import {type Node, type NodeInput} from '@sanity/comlink'\n\nimport {createResource} from '../../resources/createResource'\nimport {type FrameMessage, type WindowMessage} from '../types'\n\n/**\n * Individual node with its relevant options\n * @public\n */\nexport interface NodeEntry {\n node: Node<WindowMessage, FrameMessage>\n // we store options to ensure that channels remain as unique / consistent as possible\n options: NodeInput\n // we store refCount to ensure nodes are running only as long as they are in use\n refCount: number\n}\n\n/**\n * Internal state tracking comlink connections\n * @public\n */\nexport interface ComlinkNodeState {\n nodes: Map<string, NodeEntry>\n}\n\nexport const comlinkNodeStore = createResource<ComlinkNodeState>({\n name: 'nodeStore',\n getInitialState: () => ({\n nodes: new Map(),\n }),\n initialize() {\n return () => {\n const state = this.state.get()\n state.nodes.forEach(({node}) => {\n node.stop()\n })\n }\n },\n})\n","import {createNode, type Node, type NodeInput} from '@sanity/comlink'\nimport {isEqual} from 'lodash-es'\n\nimport {createAction} from '../../../resources/createAction'\nimport {type FrameMessage, type WindowMessage} from '../../types'\nimport {comlinkNodeStore} from '../comlinkNodeStore'\n\n/**\n * Retrieve or create a node to be used for communication between\n * an application and the controller -- specifically, a node should\n * be created within a frame / window to communicate with the controller.\n * @public\n */\nexport const getOrCreateNode = createAction(comlinkNodeStore, ({state}) => {\n return (options: NodeInput) => {\n const nodes = state.get().nodes\n const existing = nodes.get(options.name)\n\n // limit nodes to one per name\n if (existing) {\n if (!isEqual(existing.options, options)) {\n throw new Error(`Node \"${options.name}\" already exists with different options`)\n }\n\n state.set('incrementNodeRefCount', {\n nodes: new Map(nodes).set(options.name, {\n ...existing,\n refCount: existing.refCount + 1,\n }),\n })\n\n existing.node.start()\n return existing.node\n }\n\n const node: Node<WindowMessage, FrameMessage> = createNode(options)\n node.start()\n\n nodes.set(options.name, {node, options, refCount: 1})\n\n state.set('createNode', {nodes})\n\n return node\n }\n})\n","import {createAction} from '../../../resources/createAction'\nimport {comlinkNodeStore} from '../comlinkNodeStore'\n\n/**\n * Signals to the store that the consumer has stopped using the node\n * @public\n */\nexport const releaseNode = createAction(comlinkNodeStore, ({state}) => {\n return (name: string) => {\n const nodes = state.get().nodes\n const nodeEntry = nodes.get(name)\n\n if (nodeEntry) {\n const newRefCount = nodeEntry.refCount === 0 ? 0 : nodeEntry.refCount - 1\n state.set('releaseNode', {\n nodes: new Map(nodes).set(name, {\n ...nodeEntry,\n refCount: newRefCount,\n }),\n })\n if (newRefCount === 0) {\n nodeEntry.node.stop()\n }\n }\n }\n})\n"],"names":["createStore","AuthStateType","DEFAULT_API_VERSION","filter","SchemaConstructor"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils/getEnv.ts","../src/resources/createResource.ts","../src/instance/identity.ts","../src/instance/sanityInstance.ts","../src/resources/createAction.ts","../src/resources/createStore.ts","../src/resources/createStateSourceAction.ts","../src/auth/authStateType.ts","../src/auth/authConstants.ts","../src/auth/subscribeToStateAndFetchCurrentUser.ts","../src/auth/utils.ts","../src/auth/subscribeToStorageEventsAndSetToken.ts","../src/auth/authStore.ts","../src/client/actions/subscribeToAuthEvents.ts","../src/client/clientStore.ts","../src/client/actions/getClient.ts","../src/client/actions/getGlobalClient.ts","../src/client/actions/getSubscribableClient.ts","../src/documentList/documentListConstants.ts","../src/documentList/subscribeToLiveClientAndSetLastLiveEventId.ts","../src/documentList/subscribeToStateAndFetchResults.ts","../src/documentList/documentListStore.ts","../src/auth/fetchLoginUrls.ts","../src/auth/handleCallback.ts","../src/auth/logout.ts","../src/schema/schemaManager.ts","../src/preview/util.ts","../src/preview/subscribeToLiveAndSetLastLiveEventId.ts","../src/schema/getSchemaState.ts","../src/preview/getProjectionForSchemaType.ts","../src/preview/previewQuery.ts","../src/preview/subscribeToStateAndFetchBatches.ts","../src/preview/previewStore.ts","../src/preview/getPreviewState.ts","../src/preview/resolvePreview.ts","../src/comlink/controller/comlinkControllerStore.ts","../src/comlink/controller/actions/destroyController.ts","../src/comlink/controller/actions/getOrCreateChannel.ts","../src/comlink/controller/actions/getOrCreateController.ts","../src/comlink/controller/actions/releaseChannel.ts","../src/comlink/node/comlinkNodeStore.ts","../src/comlink/node/actions/getOrCreateNode.ts","../src/comlink/node/actions/releaseNode.ts"],"sourcesContent":["// Local type declaration for Remix\ntype WindowWithEnv = Window &\n typeof globalThis & {\n ENV?: Record<string, unknown>\n }\n\ntype KnownEnvVar = 'DEV'\n\nexport function getEnv(key: KnownEnvVar): unknown {\n if (typeof import.meta !== 'undefined' && import.meta.env) {\n // Vite environment variables\n return (import.meta.env as unknown as Record<string, unknown>)[key]\n } else if (typeof process !== 'undefined' && process.env) {\n // Node.js or server-side environment variables\n return process.env[key]\n } else if (typeof window !== 'undefined' && (window as WindowWithEnv).ENV) {\n // Remix-style client-side environment variables\n return (window as WindowWithEnv).ENV?.[key]\n }\n return undefined\n}\n","import {Observable} from 'rxjs'\nimport {devtools, type DevtoolsOptions} from 'zustand/middleware'\nimport {createStore} from 'zustand/vanilla'\n\nimport {type SanityInstance, type SdkIdentity} from '../instance/types'\nimport {getEnv} from '../utils/getEnv'\n\nconst resourceCache = new WeakMap<SdkIdentity, Map<string, InitializedResource<unknown>>>()\n\ntype Teardown = () => void\n\nexport interface Resource<TState> {\n name: string\n getInitialState(instance: SanityInstance): TState\n initialize?: (\n this: {instance: SanityInstance; state: ResourceState<TState>},\n instance: SanityInstance,\n ) => Teardown\n}\n\nexport function createResource<TState>(resource: Resource<TState>): Resource<TState> {\n return resource\n}\n\n/**\n * @public\n */\nexport type ResourceState<TState> = {\n get: () => TState\n set: (name: string, state: Partial<TState> | ((s: TState) => Partial<TState>)) => void\n observable: Observable<TState>\n}\n\ninterface InitializedResource<TState> {\n state: ResourceState<TState>\n dispose: () => void\n}\n\nexport function createResourceState<TState>(\n initialState: TState,\n devToolsOptions?: DevtoolsOptions,\n): ResourceState<TState> {\n const store = createStore<TState>()(devtools(() => initialState, devToolsOptions))\n return {\n get: store.getState,\n set: (actionKey, updatedState) => store.setState(updatedState, false, actionKey),\n observable: new Observable((observer) => {\n const emit = () => observer.next(store.getState())\n emit()\n return store.subscribe(emit)\n }),\n }\n}\n\nexport function initializeResource<TState>(\n instance: SanityInstance,\n resource: Resource<TState>,\n): InitializedResource<TState> {\n const initialState = resource.getInitialState(instance)\n const state = createResourceState(initialState, {\n name: resource.name,\n enabled: !!getEnv('DEV'),\n })\n const dispose = resource.initialize?.call({instance, state}, instance) ?? (() => {})\n\n return {state, dispose}\n}\n\nexport function getOrCreateResource<TState>(\n instance: SanityInstance,\n resource: Resource<TState>,\n): InitializedResource<TState> {\n if (!resourceCache.has(instance.identity)) {\n resourceCache.set(instance.identity, new Map())\n }\n const initializedResources = resourceCache.get(instance.identity)!\n const cached = initializedResources.get(resource.name)\n if (cached) return cached as InitializedResource<TState>\n\n const result = initializeResource(instance, resource)\n initializedResources.set(resource.name, result)\n return result\n}\n\nexport function disposeResources(identity: SdkIdentity): void {\n const resources = resourceCache.get(identity)\n if (!resources) return\n\n for (const resource of resources.values()) {\n resource.dispose()\n }\n}\n","import {type SdkIdentity} from './types'\n\n/**\n * thoughtLevel 2 - Primarily what we want is to have an object that we can bind stores/memoizations to, but let the things that depend on it (eg projectId, dataset) be internals that can't be overwritten by accident/intentionally\n * @public\n */\nexport function getSdkIdentity({\n projectId,\n dataset,\n}: {\n projectId: string\n dataset: string\n}): SdkIdentity {\n const id = generateId()\n return Object.freeze({\n id,\n projectId,\n dataset,\n })\n}\n\nfunction generateId() {\n return Array.from({length: 8}, () =>\n Math.floor(Math.random() * 16)\n .toString(16)\n .padStart(2, '0'),\n ).join('')\n}\n","import {disposeResources} from '../resources/createResource'\nimport {getSdkIdentity} from './identity'\nimport {type SanityConfig, type SanityInstance, type SdkIdentity} from './types'\n\n/**\n * Returns a new instance of dependencies required for SanitySDK.\n *\n * @public\n *\n * @param config - The configuration for this instance\n *\n * @returns A new \"instance\" of a Sanity SDK, used to bind resources/configuration to it\n */\nexport function createSanityInstance({\n projectId = '',\n dataset = '',\n ...config\n}: SanityConfig): SanityInstance {\n const identity = getSdkIdentity({projectId, dataset})\n return {\n identity,\n config,\n dispose: () => disposeResources(identity),\n }\n}\n\nconst resourceStorage = new WeakMap<SdkIdentity, Map<string, unknown>>()\n\nfunction getResource(instance: SanityInstance, key: string) {\n const instanceMap = resourceStorage.get(instance.identity)\n return instanceMap?.get(key)\n}\n\nfunction setResource(instance: SanityInstance, key: string, value: unknown) {\n let instanceMap = resourceStorage.get(instance.identity)\n if (!instanceMap) {\n instanceMap = new Map()\n resourceStorage.set(instance.identity, instanceMap)\n }\n instanceMap.set(key, value)\n}\n\n/**\n * This is an internal function that retrieves or creates a Zustand store resource.\n * @internal\n */\nexport function getOrCreateResource<T>(instance: SanityInstance, key: string, creator: () => T): T {\n const cached = getResource(instance, key)\n\n if (cached) {\n return cached as T\n }\n\n const resource = creator()\n setResource(instance, key, resource)\n return resource\n}\n","import {type SanityInstance} from '../instance/types'\nimport {getOrCreateResource, type Resource, type ResourceState} from './createResource'\n\n/** @public */\nexport interface ActionContext<TState> {\n instance: SanityInstance\n state: ResourceState<TState>\n}\n\ntype ResourceActionDefinition<TState, TParams extends unknown[], TReturn> = (options: {\n instance: SanityInstance\n state: ResourceState<TState>\n}) => (this: ActionContext<TState>, ...args: TParams) => TReturn\n\n/**\n * @public\n */\nexport type ResourceAction<TState, TParams extends unknown[], TReturn> = (\n dependencies: SanityInstance | ActionContext<TState>,\n ...params: TParams\n) => TReturn\n\nexport function createAction<TState, TParams extends unknown[], TReturn>(\n resource: Resource<TState>,\n actionDefinition: ResourceActionDefinition<TState, TParams, TReturn>,\n): ResourceAction<TState, TParams, TReturn> {\n return (dependencies: SanityInstance | ActionContext<TState>, ...args: TParams): TReturn => {\n const instance = 'state' in dependencies ? dependencies.instance : dependencies\n const {state} =\n 'state' in dependencies ? dependencies : getOrCreateResource(dependencies, resource)\n const actionContext = {instance, state}\n return actionDefinition(actionContext).bind(actionContext)(...args)\n }\n}\n\n/**\n * @internal\n */\nexport function createInternalAction<TState, TParams extends unknown[], TReturn>(\n actionDefinition: ResourceActionDefinition<TState, TParams, TReturn>,\n) {\n return (actionContext: ActionContext<TState>, ...args: TParams): TReturn => {\n return actionDefinition(actionContext).bind(actionContext)(...args)\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {noop} from 'lodash-es'\n\nimport {type SanityInstance} from '../instance/types'\nimport {type ActionContext, type ResourceAction} from './createAction'\nimport {initializeResource, type Resource} from './createResource'\n\n/**\n * @public\n */\nexport type BoundResourceAction<TParams extends unknown[], TReturn> = (\n ...params: TParams\n) => TReturn\n\ntype BoundActions<TActions extends {[key: string]: ResourceAction<any, any, any>}> = {\n [K in keyof TActions]: TActions[K] extends ResourceAction<any, infer TParams, infer TReturn>\n ? BoundResourceAction<TParams, TReturn>\n : never\n}\n\ntype StoreFactory<TActions extends {[key: string]: ResourceAction<any, any, any>}> = (\n instance: SanityInstance | ActionContext<any>,\n) => {\n dispose: () => void\n} & BoundActions<TActions>\n\nexport function createStore<\n TState,\n TActions extends {[key: string]: ResourceAction<any, any, any>},\n>(resource: Resource<TState>, actions: TActions): StoreFactory<TActions> {\n return function storeFactory(dependencies: SanityInstance | ActionContext<TState>) {\n const instance = 'instance' in dependencies ? dependencies.instance : dependencies\n const {state, dispose} =\n 'state' in dependencies\n ? {state: dependencies.state, dispose: noop}\n : initializeResource(instance, resource)\n const boundActions = Object.entries(actions).reduce<\n Record<string, BoundResourceAction<unknown[], unknown>>\n >((acc, [key, action]) => {\n acc[key] = action.bind(null, {state, instance})\n return acc\n }, {}) as BoundActions<TActions>\n\n return {dispose, ...boundActions}\n }\n}\n","import {filter, map, Observable, pairwise} from 'rxjs'\n\nimport {createAction, type ResourceAction} from './createAction'\nimport {type Resource} from './createResource'\n\n/**\n * @public\n */\nexport interface StateSource<T> {\n subscribe: (onStoreChanged: () => void) => () => void\n getCurrent: () => T\n observable: Observable<T>\n}\n\nexport function createStateSourceAction<TState, TParams extends unknown[], TReturn>(\n resource: Resource<TState>,\n selector: (state: TState, ...params: TParams) => TReturn,\n): ResourceAction<TState, TParams, StateSource<TReturn>> {\n return createAction(resource, ({state}) => {\n return function (...args: TParams): StateSource<TReturn> {\n const getCurrent = () => selector(state.get(), ...args)\n\n const subscribe = (onStoreChanged: () => void) => {\n const subscription = state.observable\n .pipe(\n // this is similar to `distinctUntilChanged` expect that it doesn't\n // emit until the first change from `getCurrent`\n map(getCurrent),\n pairwise(),\n filter(([prev, curr]) => prev !== curr),\n map(([_, curr]) => curr),\n )\n .subscribe({next: onStoreChanged})\n\n return () => subscription.unsubscribe()\n }\n\n const observable = new Observable<TReturn>((observer) => {\n const emitCurrent = () => observer.next(getCurrent())\n emitCurrent()\n return subscribe(emitCurrent)\n })\n\n return {\n getCurrent,\n subscribe,\n observable,\n }\n }\n })\n}\n","/**\n * Represents the various states the authentication type can be in.\n *\n * @public\n */\nexport enum AuthStateType {\n LOGGED_IN = 'logged-in',\n LOGGING_IN = 'logging-in',\n ERROR = 'error',\n LOGGED_OUT = 'logged-out',\n}\n","export const DEFAULT_BASE = 'http://localhost'\nexport const AUTH_CODE_PARAM = 'sid'\nexport const DEFAULT_API_VERSION = '2021-06-07'\nexport const REQUEST_TAG_PREFIX = 'sdk.auth'\n","import {type CurrentUser} from '@sanity/types'\nimport {distinctUntilChanged, filter, map, switchMap} from 'rxjs'\n\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {DEFAULT_API_VERSION, REQUEST_TAG_PREFIX} from './authConstants'\nimport {AuthStateType} from './authStateType'\nimport {type AuthState, type AuthStoreState} from './authStore'\n\nexport const subscribeToStateAndFetchCurrentUser = createInternalAction(\n ({state, instance}: ActionContext<AuthStoreState>) => {\n const {projectId, dataset} = instance.identity\n const {clientFactory, apiHost, authScope} = state.get().options\n\n const currentUser$ = state.observable\n .pipe(\n map(({authState}) => authState),\n filter(\n (authState): authState is Extract<AuthState, {type: AuthStateType.LOGGED_IN}> =>\n authState.type === AuthStateType.LOGGED_IN && !authState.currentUser,\n ),\n map((authState) => authState.token),\n distinctUntilChanged(),\n )\n .pipe(\n map((token) =>\n clientFactory({\n projectId,\n dataset,\n apiVersion: DEFAULT_API_VERSION,\n requestTagPrefix: REQUEST_TAG_PREFIX,\n useProjectHostname: authScope === 'project',\n token,\n ignoreBrowserTokenWarning: true,\n ...(apiHost && {apiHost}),\n }),\n ),\n switchMap((client) =>\n client.observable.request<CurrentUser>({uri: '/users/me', method: 'GET'}),\n ),\n )\n\n return function () {\n return currentUser$.subscribe({\n next: (currentUser) => {\n state.set('setCurrentUser', (prev) => ({\n authState:\n prev.authState.type === AuthStateType.LOGGED_IN\n ? {...prev.authState, currentUser}\n : prev.authState,\n }))\n },\n error: (error) => {\n state.set('setError', {authState: {type: AuthStateType.ERROR, error}})\n },\n })\n }\n },\n)\n","import {EMPTY, fromEvent, Observable} from 'rxjs'\n\nimport {AUTH_CODE_PARAM, DEFAULT_BASE} from './authConstants'\n\nexport function getAuthCode(callbackUrl: string | undefined, locationHref: string): string | null {\n const loc = new URL(locationHref, DEFAULT_BASE)\n const callbackLocation = callbackUrl ? new URL(callbackUrl, DEFAULT_BASE) : undefined\n const callbackLocationMatches = callbackLocation\n ? loc.pathname.toLowerCase().startsWith(callbackLocation.pathname.toLowerCase())\n : true\n\n // for stamped tokens, the authCode is not in the hash, it is in the query params\n const authCode =\n new URLSearchParams(loc.hash.slice(1)).get(AUTH_CODE_PARAM) ||\n new URLSearchParams(loc.search).get(AUTH_CODE_PARAM)\n\n return authCode && callbackLocationMatches ? authCode : null\n}\n\n/**\n * Attempts to retrieve a token from the configured storage.\n * If invalid or not present, returns null.\n */\nexport function getTokenFromStorage(\n storageArea: Storage | undefined,\n storageKey: string,\n): string | null {\n if (!storageArea) return null\n const item = storageArea.getItem(storageKey)\n if (item === null) return null\n\n try {\n const parsed: unknown = JSON.parse(item)\n if (\n typeof parsed !== 'object' ||\n parsed === null ||\n !('token' in parsed) ||\n typeof parsed.token !== 'string'\n ) {\n throw new Error('Invalid stored auth data structure')\n }\n return parsed.token\n } catch {\n storageArea.removeItem(storageKey)\n return null\n }\n}\n\n/**\n * Creates an observable stream of storage events. If not in a browser environment,\n * returns an EMPTY observable.\n */\nexport function getStorageEvents(): Observable<StorageEvent> {\n const isBrowser = typeof window !== 'undefined' && typeof window.addEventListener === 'function'\n\n if (!isBrowser) {\n return EMPTY\n }\n\n return fromEvent<StorageEvent>(window, 'storage')\n}\n\n/**\n * Returns a default storage instance (localStorage) if available.\n * If not available or an error occurs, returns undefined.\n */\nexport function getDefaultStorage(): Storage | undefined {\n try {\n if (typeof localStorage !== 'undefined' && typeof localStorage.getItem === 'function') {\n return localStorage\n }\n return undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Returns the default location to use.\n * Tries accessing `location.href`, falls back to a default base if not available or on error.\n */\nexport function getDefaultLocation(): string {\n try {\n if (typeof location === 'undefined') return DEFAULT_BASE\n if (typeof location.href === 'string') return location.href\n return DEFAULT_BASE\n } catch {\n return DEFAULT_BASE\n }\n}\n","import {defer, distinctUntilChanged, filter, map} from 'rxjs'\n\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {AuthStateType} from './authStateType'\nimport {type AuthStoreState} from './authStore'\nimport {getStorageEvents, getTokenFromStorage} from './utils'\n\nexport const subscribeToStorageEventsAndSetToken = createInternalAction(\n ({state}: ActionContext<AuthStoreState>) => {\n const {storageArea, storageKey} = state.get().options\n\n const tokenFromStorage$ = defer(getStorageEvents).pipe(\n filter(\n (e): e is StorageEvent & {newValue: string} =>\n e.storageArea === storageArea && e.key === storageKey,\n ),\n map(() => getTokenFromStorage(storageArea, storageKey)),\n distinctUntilChanged(),\n )\n\n return function () {\n return tokenFromStorage$.subscribe((token) => {\n state.set('updateTokenFromStorageEvent', {\n authState: token\n ? {type: AuthStateType.LOGGED_IN, token, currentUser: null}\n : {type: AuthStateType.LOGGED_OUT, isDestroyingSession: false},\n })\n })\n }\n },\n)\n","import {type ClientConfig, createClient, type SanityClient} from '@sanity/client'\nimport {type CurrentUser} from '@sanity/types'\n\nimport {createResource} from '../resources/createResource'\nimport {createStateSourceAction} from '../resources/createStateSourceAction'\nimport {AuthStateType} from './authStateType'\nimport {subscribeToStateAndFetchCurrentUser} from './subscribeToStateAndFetchCurrentUser'\nimport {subscribeToStorageEventsAndSetToken} from './subscribeToStorageEventsAndSetToken'\nimport {getAuthCode, getDefaultLocation, getDefaultStorage, getTokenFromStorage} from './utils'\n\n/**\n * Represents the various states the authentication can be in.\n *\n * @public\n */\nexport type AuthState = LoggedInAuthState | LoggedOutAuthState | LoggingInAuthState | ErrorAuthState\n\n/**\n * Logged-in state from the auth state.\n * @public\n */\nexport type LoggedInAuthState = {\n type: AuthStateType.LOGGED_IN\n token: string\n currentUser: CurrentUser | null\n}\n\n/**\n * Logged-out state from the auth state.\n * @public\n */\nexport type LoggedOutAuthState = {type: AuthStateType.LOGGED_OUT; isDestroyingSession: boolean}\n\n/**\n * Logging-in state from the auth state.\n * @public\n */\nexport type LoggingInAuthState = {type: AuthStateType.LOGGING_IN; isExchangingToken: boolean}\n\n/**\n * Error state from the auth state.\n * @public\n */\nexport type ErrorAuthState = {type: AuthStateType.ERROR; error: unknown}\n\n/**\n * Configuration for an authentication provider\n * @public\n */\nexport interface AuthProvider {\n /**\n * Unique identifier for the auth provider (e.g., 'google', 'github')\n */\n name: string\n\n /**\n * Display name for the auth provider in the UI\n */\n title: string\n\n /**\n * Complete authentication URL including callback and token parameters\n */\n url: string\n\n /**\n * Optional URL for direct sign-up flow\n */\n signUpUrl?: string\n}\n\n/**\n * Configuration options for creating an auth store.\n *\n * @public\n */\nexport interface AuthConfig {\n /**\n * The initial location href to use when handling auth callbacks.\n * Defaults to the current window location if available.\n */\n initialLocationHref?: string\n\n /**\n * Factory function to create a SanityClient instance.\n * Defaults to the standard Sanity client factory if not provided.\n */\n clientFactory?: (config: ClientConfig) => SanityClient\n\n /**\n * Custom authentication providers to use instead of or in addition to the default ones.\n * Can be an array of providers or a function that takes the default providers and returns\n * a modified array or a Promise resolving to one.\n */\n providers?: AuthProvider[] | ((prev: AuthProvider[]) => AuthProvider[] | Promise<AuthProvider[]>)\n\n /**\n * The API hostname for requests. Usually leave this undefined, but it can be set\n * if using a custom domain or CNAME for the API endpoint.\n */\n apiHost?: string\n\n /**\n * Storage implementation to persist authentication state.\n * Defaults to `localStorage` if available.\n */\n storageArea?: Storage\n\n /**\n * A callback URL for your application.\n * If none is provided, the auth API will redirect back to the current location (`location.href`).\n * When handling callbacks, this URL's pathname is checked to ensure it matches the callback.\n */\n callbackUrl?: string\n\n /**\n * A static authentication token to use instead of handling the OAuth flow.\n * When provided, the auth store will remain in a logged-in state with this token,\n * ignoring any storage or callback handling.\n */\n token?: string\n\n /**\n * The authentication scope.\n * If set to 'project', requests are scoped to the project-level.\n * If set to 'global', requests are scoped to the user access level.\n * Defaults to 'project'.\n */\n authScope?: 'project' | 'global'\n}\n\n/**\n * @public\n */\nexport interface AuthStoreState {\n authState: AuthState\n providers?: AuthProvider[]\n options: {\n initialLocationHref: string\n clientFactory: (config: ClientConfig) => SanityClient\n customProviders: AuthConfig['providers']\n authScope: 'project' | 'global'\n storageKey: string\n storageArea: Storage | undefined\n apiHost: string | undefined\n callbackUrl: string | undefined\n providedToken: string | undefined\n }\n}\n\nexport const authStore = createResource<AuthStoreState>({\n name: 'Auth',\n getInitialState(instance) {\n const {\n apiHost,\n callbackUrl,\n providers: customProviders,\n authScope = 'project',\n token: providedToken,\n clientFactory = createClient,\n initialLocationHref = getDefaultLocation(),\n storageArea = getDefaultStorage(),\n } = instance.config.auth ?? {}\n const {projectId, dataset} = instance.identity\n\n const storageKey = `__sanity_auth_token_${projectId}_${dataset}`\n\n let authState: AuthState\n\n const token = getTokenFromStorage(storageArea, storageKey)\n\n if (providedToken) {\n authState = {type: AuthStateType.LOGGED_IN, token: providedToken, currentUser: null}\n } else if (getAuthCode(callbackUrl, initialLocationHref)) {\n authState = {type: AuthStateType.LOGGING_IN, isExchangingToken: false}\n } else if (token) {\n authState = {type: AuthStateType.LOGGED_IN, token, currentUser: null}\n } else {\n authState = {type: AuthStateType.LOGGED_OUT, isDestroyingSession: false}\n }\n\n return {\n authState,\n options: {\n apiHost,\n authScope,\n callbackUrl,\n customProviders,\n providedToken,\n clientFactory,\n initialLocationHref,\n storageKey,\n storageArea,\n },\n }\n },\n initialize() {\n const stateSubscription = subscribeToStateAndFetchCurrentUser(this)\n const storageEventsSubscription = subscribeToStorageEventsAndSetToken(this)\n\n return () => {\n stateSubscription.unsubscribe()\n storageEventsSubscription.unsubscribe()\n }\n },\n})\n\n/**\n * @public\n */\nexport const getCurrentUserState = createStateSourceAction(authStore, ({authState}) =>\n authState.type === AuthStateType.LOGGED_IN ? authState.currentUser : null,\n)\n\n/**\n * @public\n */\nexport const getTokenState = createStateSourceAction(authStore, ({authState}) =>\n authState.type === AuthStateType.LOGGED_IN ? authState.token : null,\n)\n/**\n * @public\n */\nexport const getLoginUrlsState = createStateSourceAction(\n authStore,\n ({providers}) => providers ?? null,\n)\n\n/**\n * @public\n */\nexport const getAuthState = createStateSourceAction(authStore, ({authState}) => authState)\n","import {getTokenState} from '../../auth/authStore'\nimport {type ActionContext, createInternalAction} from '../../resources/createAction'\nimport {type ClientState} from '../clientStore'\n\nconst receiveToken = (prev: ClientState, token: string | undefined): ClientState => {\n const newDefaultClient = prev.defaultClient.withConfig({\n token,\n })\n const newGlobalClient = prev.defaultGlobalClient.withConfig({\n token,\n })\n const updatedClients = new Map(\n Array.from(prev.clients.entries()).map(([version, client]) => [\n version,\n client.withConfig({token}),\n ]),\n )\n\n return {\n defaultClient: newDefaultClient,\n defaultGlobalClient: newGlobalClient,\n clients: updatedClients,\n }\n}\n\n/**\n * Updates the client store state when a token is received.\n * @internal\n */\nexport const subscribeToAuthEvents = createInternalAction(\n ({instance, state}: ActionContext<ClientState>) => {\n return () => {\n return getTokenState(instance).observable.subscribe((newToken) => {\n state.set('receiveToken', (prev) => receiveToken(prev, newToken ?? undefined))\n })\n }\n },\n)\n","import {createClient, type SanityClient} from '@sanity/client'\n\nimport {type SanityInstance} from '../instance/types'\nimport {createResource, type Resource} from '../resources/createResource'\nimport {subscribeToAuthEvents} from './actions/subscribeToAuthEvents'\n\nconst DEFAULT_API_VERSION = '2024-11-12'\n\n/**\n * States tracked by the client store\n * @public\n */\nexport interface ClientState {\n defaultClient: SanityClient\n defaultGlobalClient: SanityClient\n clients: Map<string, SanityClient>\n}\n\nexport const clientStore: Resource<ClientState> = createResource({\n name: 'clientStore',\n\n getInitialState: (instance: SanityInstance) => {\n const {identity, config} = instance\n const defaultClient = createClient({\n projectId: identity.projectId,\n dataset: identity.dataset,\n token: config?.auth?.token,\n useCdn: false,\n apiVersion: DEFAULT_API_VERSION,\n ...(config?.auth?.apiHost ? {apiHost: config.auth.apiHost} : {}),\n })\n\n const defaultGlobalClient = createClient({\n token: config?.auth?.token,\n useCdn: false,\n apiVersion: 'vX', // Many global APIs are only available under this version, we may need to support other versions in the future\n useProjectHostname: false,\n ...(config?.auth?.apiHost ? {apiHost: config.auth.apiHost} : {}),\n })\n\n const clients = new Map<string, SanityClient>()\n clients.set(DEFAULT_API_VERSION, defaultClient)\n clients.set('global-vX', defaultGlobalClient)\n\n return {\n defaultClient,\n defaultGlobalClient,\n clients,\n }\n },\n\n initialize() {\n const authEventSubscription = subscribeToAuthEvents(this)\n return () => {\n authEventSubscription.unsubscribe()\n }\n },\n})\n","import {type SanityClient} from '@sanity/client'\n\nimport {createAction} from '../../resources/createAction'\nimport {clientStore} from '../clientStore'\n\n/**\n * Options used when retrieving a client via getOrCreateClient.\n * @public\n */\nexport interface ClientOptions {\n apiVersion?: string\n}\n\n/**\n * Retrieves a memoized client based on the API version,\n * or creates a new one if it doesn't exist.\n * @public\n */\nexport const getClient = createAction(clientStore, ({state}) => {\n return (options: ClientOptions = {}): SanityClient => {\n const {apiVersion} = options\n\n if (!apiVersion) {\n throw new Error('Missing required `apiVersion` option')\n }\n\n const cached = state.get().clients.get(apiVersion)\n if (cached) {\n return cached\n }\n\n // Create new client with specified API version\n const client = state.get().defaultClient.withConfig(options)\n const newMap = new Map(state.get().clients)\n newMap.set(apiVersion, client)\n\n // Update state with new client\n state.set('createClient', {\n clients: newMap,\n })\n\n return client\n }\n})\n","import {createAction} from '../../resources/createAction'\nimport {clientStore} from '../clientStore'\n\n/**\n * Retrieves the global, project-less client.\n * @public\n */\nexport const getGlobalClient = createAction(\n clientStore,\n ({state}) =>\n () =>\n state.get().defaultGlobalClient,\n)\n","import {type SanityClient} from '@sanity/client'\nimport {distinctUntilChanged, map, startWith, type Subscribable} from 'rxjs'\n\nimport {createAction} from '../../resources/createAction'\nimport {clientStore} from '../clientStore'\nimport {type ClientOptions, getClient} from './getClient'\n\n/**\n * Provides a stream of clients, based on the current state of the store.\n * (For example, when a user logs in, this will emit an authorized client.)\n * @public\n */\nexport const getSubscribableClient = createAction(clientStore, ({instance, state}) => {\n return (options: ClientOptions): Subscribable<SanityClient> => {\n const initialClient = getClient(instance, options)\n\n const client$ = state.observable.pipe(\n map(() => getClient(instance, options)),\n startWith(initialClient),\n // as we add more things that can change client configuration,\n // we might want to add more checks here\n distinctUntilChanged((prev, curr) => prev.config().token === curr.config().token),\n )\n\n return {\n subscribe: client$.subscribe.bind(client$),\n }\n }\n})\n","export const API_VERSION = 'vX'\nexport const PAGE_SIZE = 25\n","import {type SanityClient} from '@sanity/client'\nimport {filter, map, Observable, switchMap, withLatestFrom} from 'rxjs'\n\nimport {getSubscribableClient} from '../client/actions/getSubscribableClient'\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {API_VERSION} from './documentListConstants'\nimport {type DocumentListState} from './documentListStore'\n\nexport const subscribeToLiveClientAndSetLastLiveEventId = createInternalAction(\n ({state, instance}: ActionContext<DocumentListState>) => {\n const liveEventMessage$ = new Observable<SanityClient>((observer) =>\n getSubscribableClient(instance, {apiVersion: API_VERSION}).subscribe(observer),\n ).pipe(\n switchMap((client) =>\n client.live.events({includeDrafts: !!client.config().token, tag: 'sdk.document-list'}),\n ),\n filter((e) => e.type === 'message'),\n withLatestFrom(state.observable.pipe(map(({syncTags}) => syncTags))),\n )\n\n return function () {\n return liveEventMessage$.subscribe(([event, syncTags]) => {\n if (event.tags.some((tag) => syncTags.includes(tag))) {\n state.set('updateEventIdFromLiveContentApi', {lastLiveEventId: event.id})\n }\n })\n }\n },\n)\n","import {type SanityClient} from '@sanity/client'\nimport {isEqual, pick} from 'lodash-es'\nimport {\n debounceTime,\n distinctUntilChanged,\n map,\n Observable,\n switchMap,\n tap,\n withLatestFrom,\n} from 'rxjs'\n\nimport {getSubscribableClient} from '../client/actions/getSubscribableClient'\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {API_VERSION} from './documentListConstants'\nimport {type DocumentHandle, type DocumentListState} from './documentListStore'\n\nexport interface DocumentListQueryResult {\n count: number\n results: DocumentHandle[]\n}\n\nexport const subscribeToStateAndFetchResults = createInternalAction(\n ({state, instance}: ActionContext<DocumentListState>) => {\n return function () {\n const client$ = new Observable<SanityClient>((observer) =>\n getSubscribableClient(instance, {apiVersion: API_VERSION}).subscribe(observer),\n )\n\n const fetchInput$ = state.observable.pipe(\n map((s) => pick(s, 'options', 'limit', 'lastLiveEventId')),\n distinctUntilChanged(isEqual as <T>(a: T, b: T) => boolean),\n )\n\n return fetchInput$\n .pipe(\n withLatestFrom(client$),\n debounceTime(0),\n tap(() => {\n state.set('setPending', {isPending: true})\n }),\n switchMap(([{options, limit, lastLiveEventId}, client]) => {\n const filter = options.filter ? `[${options.filter}]` : ''\n const order = options.sort\n ? `| order(${options.sort\n .map((ordering) =>\n [ordering.field, ordering.direction.toLowerCase()]\n .map((str) => str.trim())\n .filter(Boolean)\n .join(' '),\n )\n .join(',')})`\n : ''\n\n const resultsQuery = `*${filter}${order}[0...$__limit]{_id, _type}`\n const countQuery = `count(*${filter})`\n\n return client.observable.fetch<DocumentListQueryResult>(\n `{\"count\":${countQuery},\"results\":${resultsQuery}}`,\n {__limit: limit},\n {\n filterResponse: false,\n returnQuery: false,\n lastLiveEventId,\n tag: 'sdk.document-list',\n perspective: 'previewDrafts',\n },\n )\n }),\n )\n .subscribe({\n next: ({syncTags, result: {count, results}}) => {\n state.set('updateFromFetch', {\n syncTags,\n results,\n count,\n isPending: false,\n })\n },\n })\n }\n },\n)\n","import {type SyncTag} from '@sanity/client'\nimport {type SortOrderingItem} from '@sanity/types'\nimport {createSelector} from 'reselect'\n\nimport {createAction} from '../resources/createAction'\nimport {createResource} from '../resources/createResource'\nimport {createStateSourceAction} from '../resources/createStateSourceAction'\nimport {createStore} from '../resources/createStore'\nimport {PAGE_SIZE} from './documentListConstants'\nimport {subscribeToLiveClientAndSetLastLiveEventId} from './subscribeToLiveClientAndSetLastLiveEventId'\nimport {subscribeToStateAndFetchResults} from './subscribeToStateAndFetchResults'\n\n/**\n * Configuration options for filtering and sorting documents in a document list.\n * @public\n */\nexport interface DocumentListOptions {\n /** GROQ filter expression to query specific documents */\n filter?: string\n /** Array of sort ordering specifications to determine the order of results */\n sort?: SortOrderingItem[]\n /** The Content Lake perspective to use for this list. Defaults to `previewDrafts`. */\n perspective?: string\n}\n\n/**\n * Represents an identifier to a Sanity document, containing its `_id` to pull\n * the document from content lake and its `_type` to look up its schema type.\n * @public\n */\nexport interface DocumentHandle {\n _id: string\n _type: string\n}\n\n/**\n * @public\n */\nexport interface DocumentListState {\n options: DocumentListOptions\n lastLiveEventId?: string\n syncTags: SyncTag[]\n limit: number\n count: number\n results: DocumentHandle[]\n isPending: boolean\n}\n\nconst documentList = createResource<DocumentListState>({\n name: 'documentList',\n getInitialState: () => ({\n limit: PAGE_SIZE,\n options: {perspective: 'previewDrafts'},\n results: [],\n syncTags: [],\n isPending: false,\n count: 0,\n }),\n initialize() {\n const stateSubscription = subscribeToStateAndFetchResults(this)\n const liveClientSubscription = subscribeToLiveClientAndSetLastLiveEventId(this)\n\n return () => {\n stateSubscription.unsubscribe()\n liveClientSubscription.unsubscribe()\n }\n },\n})\n\nconst getState = createStateSourceAction(\n documentList,\n createSelector(\n [\n (state: DocumentListState) => state.results,\n (state: DocumentListState) => state.count,\n (state: DocumentListState) => state.isPending,\n ],\n (results, count, isPending) => ({\n results,\n isPending,\n count,\n hasMore: results.length < count,\n }),\n ),\n)\n\nconst setOptions = createAction(documentList, ({state}) => {\n return function (options: DocumentListOptions) {\n state.set('setOptions', (prev) => ({\n options: {\n ...prev.options,\n ...options,\n },\n }))\n }\n})\n\nconst loadMore = createAction(documentList, ({state}) => {\n return function () {\n state.set('loadMore', (prev) => ({limit: prev.limit + PAGE_SIZE}))\n }\n})\n\n/**\n * @public\n */\nexport const createDocumentListStore = createStore(documentList, {\n getState,\n loadMore,\n setOptions,\n})\n","import {type AuthProvider} from '@sanity/client'\n\nimport {createAction} from '../resources/createAction'\nimport {DEFAULT_API_VERSION, REQUEST_TAG_PREFIX} from './authConstants'\nimport {authStore} from './authStore'\nimport {getDefaultLocation} from './utils'\n\n/**\n * @public\n */\nexport const fetchLoginUrls = createAction(authStore, ({state, instance}) => {\n const {projectId, dataset} = instance.identity\n const {callbackUrl, clientFactory, apiHost, authScope, customProviders} = state.get().options\n const client = clientFactory({\n projectId,\n dataset,\n apiVersion: DEFAULT_API_VERSION,\n requestTagPrefix: REQUEST_TAG_PREFIX,\n useProjectHostname: authScope === 'project',\n ...(apiHost && {apiHost}),\n })\n\n return async function () {\n const cachedProviders = state.get().providers\n if (cachedProviders) return cachedProviders\n\n const {providers: defaultProviders} = await client.request<{providers: AuthProvider[]}>({\n uri: '/auth/providers',\n tag: 'fetch-providers',\n })\n\n let providers: AuthProvider[]\n\n if (typeof customProviders === 'function') {\n providers = await customProviders(defaultProviders)\n } else if (!customProviders?.length) {\n providers = defaultProviders\n } else {\n const customProviderUrls = new Set(customProviders.map((p) => p.url))\n providers = defaultProviders\n .filter((official) => !customProviderUrls.has(official.url))\n .concat(customProviders)\n }\n\n const configuredProviders = providers.map((provider) => {\n const url = new URL(provider.url)\n const origin = new URL(\n callbackUrl\n ? new URL(callbackUrl, new URL(getDefaultLocation()).origin).toString()\n : getDefaultLocation(),\n )\n\n // `getDefaultLocation()` may be populated with an `sid` from a previous\n // failed login attempt and should be omitted from the next login URL\n const hashParams = new URLSearchParams(origin.hash.slice(1))\n hashParams.delete('sid')\n origin.hash = hashParams.toString()\n origin.searchParams.delete('sid')\n origin.searchParams.delete('url')\n\n // similarly, the origin may be populated with an `error` query param if\n // the auth provider redirects back to the application. this should also\n // be omitted from the origin sent\n origin.searchParams.delete('error')\n\n url.searchParams.set('origin', origin.toString())\n url.searchParams.set('withSid', 'true')\n url.searchParams.set('type', 'stampedToken')\n if (authScope === 'project') {\n url.searchParams.set('projectId', projectId)\n }\n\n return {...provider, url: url.toString()}\n })\n\n state.set('fetchedLoginUrls', {providers: configuredProviders})\n\n return configuredProviders\n }\n})\n","import {createAction} from '../resources/createAction'\nimport {DEFAULT_API_VERSION, REQUEST_TAG_PREFIX} from './authConstants'\nimport {AuthStateType} from './authStateType'\nimport {authStore} from './authStore'\nimport {getAuthCode, getDefaultLocation} from './utils'\n\n/**\n * @public\n */\nexport const handleCallback = createAction(authStore, ({state, instance}) => {\n const {projectId, dataset} = instance.identity\n const {providedToken, callbackUrl, clientFactory, apiHost, authScope, storageArea, storageKey} =\n state.get().options\n\n return async function (locationHref: string = getDefaultLocation()) {\n // If a token is provided, no need to handle callback\n if (providedToken) return false\n\n // Don't handle the callback if already in flight.\n const {authState} = state.get()\n if (authState.type === AuthStateType.LOGGING_IN && authState.isExchangingToken) return false\n\n // If there is no matching `authCode` then we can't handle the callback\n const authCode = getAuthCode(callbackUrl, locationHref)\n if (!authCode) return false\n\n // Otherwise, start the exchange\n state.set('exchangeSessionForToken', {\n authState: {type: AuthStateType.LOGGING_IN, isExchangingToken: true},\n })\n\n try {\n const client = clientFactory({\n projectId,\n dataset,\n apiVersion: DEFAULT_API_VERSION,\n requestTagPrefix: REQUEST_TAG_PREFIX,\n useProjectHostname: authScope === 'project',\n ...(apiHost && {apiHost}),\n })\n\n const {token} = await client.request<{token: string; label: string}>({\n method: 'GET',\n uri: '/auth/fetch',\n query: {sid: authCode},\n tag: 'fetch-token',\n })\n\n storageArea?.setItem(storageKey, JSON.stringify({token}))\n state.set('setToken', {authState: {type: AuthStateType.LOGGED_IN, token, currentUser: null}})\n\n const loc = new URL(locationHref)\n loc.hash = ''\n loc.searchParams.delete('sid')\n loc.searchParams.delete('url')\n return loc.toString()\n } catch (error) {\n state.set('exchangeSessionForTokenError', {authState: {type: AuthStateType.ERROR, error}})\n return false\n }\n }\n})\n","import {createAction} from '../resources/createAction'\nimport {DEFAULT_API_VERSION, REQUEST_TAG_PREFIX} from './authConstants'\nimport {AuthStateType} from './authStateType'\nimport {authStore} from './authStore'\n\n/**\n * @public\n */\nexport const logout = createAction(authStore, ({state, instance}) => {\n const {projectId, dataset} = instance.identity\n const {clientFactory, apiHost, authScope, providedToken, storageArea, storageKey} =\n state.get().options\n\n return async function () {\n // If a token is statically provided, logout does nothing\n if (providedToken) return\n\n const {authState} = state.get()\n\n // If we already have an inflight request, no-op\n if (authState.type === AuthStateType.LOGGED_OUT && authState.isDestroyingSession) return\n const token = authState.type === AuthStateType.LOGGED_IN && authState.token\n\n try {\n if (token) {\n state.set('loggingOut', {\n authState: {type: AuthStateType.LOGGED_OUT, isDestroyingSession: true},\n })\n\n const client = clientFactory({\n token,\n projectId,\n dataset,\n requestTagPrefix: REQUEST_TAG_PREFIX,\n apiVersion: DEFAULT_API_VERSION,\n useProjectHostname: authScope === 'project',\n ...(apiHost && {apiHost}),\n })\n\n await client.request<void>({uri: '/auth/logout', method: 'POST'})\n }\n } finally {\n state.set('logoutSuccess', {\n authState: {type: AuthStateType.LOGGED_OUT, isDestroyingSession: false},\n })\n storageArea?.removeItem(storageKey)\n }\n }\n})\n","import {Schema as SchemaConstructor} from '@sanity/schema'\nimport {type Schema, type SchemaTypeDefinition} from '@sanity/types'\n\nimport {createResource} from '../resources/createResource'\n\n/**\n * @public\n */\nexport interface SchemaConfig {\n types: SchemaTypeDefinition[]\n}\n\n/**\n * @public\n */\nexport interface SchemaManagerState {\n schema: Schema\n}\n\nexport const schemaManager = createResource<SchemaManagerState>({\n name: 'schemaManager',\n getInitialState(instance) {\n const {config} = instance\n const schema = SchemaConstructor.compile({\n name: 'default',\n types: config.schema?.types ?? [],\n })\n\n // TODO: check for schema errors and warn on schema warnings\n\n return {schema}\n },\n})\n","import {getEnv} from '../utils/getEnv'\nimport {type PreviewValue, type ValuePending} from './previewStore'\n\nexport const PREVIEW_TAG = 'sdk.preview'\nexport const STABLE_EMPTY_PREVIEW: ValuePending<PreviewValue> = {results: null, isPending: false}\nexport const STABLE_ERROR_PREVIEW: ValuePending<PreviewValue> = {\n results: {\n title: 'Preview Error',\n ...(!!getEnv('DEV') && {subtitle: 'Check the console for more details'}),\n },\n isPending: false,\n}\n\nexport function getPublishedId(id: string): string {\n const draftsPrefix = 'drafts.'\n return id.startsWith(draftsPrefix) ? id.slice(draftsPrefix.length) : id\n}\n\nexport function getDraftId(id: string): string {\n const draftsPrefix = 'drafts.'\n return id.startsWith(draftsPrefix) ? id : `${draftsPrefix}${id}`\n}\n\nexport function randomId(): string {\n return Array.from({length: 8}, () =>\n Math.floor(Math.random() * 16)\n .toString(16)\n .padStart(2, '0'),\n ).join('')\n}\n\nexport function hashString(str: string): string {\n // Using a large prime number for the hash\n const PRIME = 31\n // Using a max 32-bit integer to prevent overflow\n const MOD = 2147483647\n\n let hash = 0\n\n // Process chunks of the string to reduce complexity\n for (let i = 0; i < str.length; i++) {\n // Rolling hash computation\n hash = (hash * PRIME + str.charCodeAt(i)) % MOD\n }\n\n // Ensure we return a positive hash\n return Math.abs(hash).toString(16).padStart(8, '0')\n}\n","import {type SanityClient} from '@sanity/client'\nimport {combineLatest, distinctUntilChanged, filter, map, Observable, switchMap} from 'rxjs'\n\nimport {getSubscribableClient} from '../client/actions/getSubscribableClient'\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {type PreviewStoreState} from './previewStore'\nimport {PREVIEW_TAG} from './util'\n\nexport const subscribeToLiveAndSetLastLiveEventId = createInternalAction(\n ({instance, state}: ActionContext<PreviewStoreState>) => {\n const client$ = new Observable<SanityClient>((observer) =>\n getSubscribableClient(instance, {apiVersion: 'vX'}).subscribe(observer),\n )\n const syncTags$ = state.observable.pipe(\n map((i) => i.syncTags),\n distinctUntilChanged(),\n )\n\n return function () {\n const messageEvents$ = client$.pipe(\n switchMap((client) =>\n client.live\n .events({includeDrafts: !!client.config().token, tag: PREVIEW_TAG})\n .pipe(filter((e): e is Extract<typeof e, {type: 'message'}> => e.type === 'message')),\n ),\n )\n\n return combineLatest([messageEvents$, syncTags$]).subscribe({\n next: ([event, currentSyncTags]) => {\n for (const tag of event.tags) {\n if (currentSyncTags[tag]) {\n state.set('setLastLiveEventId', {lastLiveEventId: event.id})\n return\n }\n }\n },\n })\n }\n },\n)\n","import {createStateSourceAction} from '../resources/createStateSourceAction'\nimport {schemaManager} from './schemaManager'\n\nexport const getSchemaState = createStateSourceAction(schemaManager, (state) => state.schema)\n","import {type ReferenceSchemaType, type Schema, type SchemaType} from '@sanity/types'\n\nexport function getProjectionForSchemaType(schema: Schema, schemaTypeName: string): string {\n const schemaType = schema.get(schemaTypeName)\n if (!schemaType) {\n throw new Error(`Could not find type \\`${schemaTypeName}\\` in the provided schema.`)\n }\n\n return `{${Object.entries(schemaType.preview?.select ?? {})\n .map(([key, path]) => {\n return `${JSON.stringify(key)}:${getGroqFromPath(schema, schemaType, path)}`\n })\n .join(',')}}`\n}\n\nfunction isReferenceType(\n type: SchemaType | undefined,\n visited = new Set<SchemaType>(),\n): type is ReferenceSchemaType {\n if (!type) return false\n if (visited.has(type)) return false\n visited.add(type)\n\n if (type.name === 'reference') return true\n return isReferenceType(type.type, visited)\n}\n\ntype PathSegment =\n | {type: 'attribute'; name: string}\n | {type: 'element'; index: number}\n | {type: 'deref'}\n\nfunction printPath(segments: PathSegment[]): string {\n return segments.reduce((acc, segment) => {\n if (segment.type === 'deref') return `${acc}->`\n if (segment.type === 'element') return `${acc}[${segment.index}]`\n if (acc.endsWith('->')) return `${acc}${segment.name}`\n return [acc, segment.name].filter(Boolean).join('.')\n }, '')\n}\n\nconst cache = new WeakMap<SchemaType, Map<string, string>>()\n\nfunction getGroqFromPath(schema: Schema, node: SchemaType, path: string): string {\n const cached = cache.get(node)?.get(path)\n if (cached) return cached\n\n const possiblePaths = Array.from(\n new Set(resolveAllPaths(schema, node, path.split('.')).map(printPath)),\n )\n if (!possiblePaths.length) {\n // TODO: bubble this instead of warning\n // eslint-disable-next-line no-console\n console.warn(`Could not resolve path \\`${path}\\` from schema type \\`${node.name}\\`.`)\n return 'null'\n }\n\n const result =\n possiblePaths.length === 1 ? possiblePaths[0] : `coalesce(${possiblePaths.join(',')})`\n\n if (!cache.has(node)) {\n cache.set(node, new Map())\n }\n const mapByPaths = cache.get(node)!\n mapByPaths.set(path, result)\n\n return result\n}\n\nfunction resolveAllPaths(schema: Schema, schemaType: SchemaType, path: string[]): PathSegment[][] {\n const [name, ...rest] = path\n if (name?.startsWith('_')) {\n return [\n [\n {type: 'attribute', name},\n ...rest.map(\n (next): PathSegment =>\n /\\d+/.test(next)\n ? {type: 'element', index: parseInt(next, 10)}\n : {type: 'attribute', name: next},\n ),\n ],\n ]\n } else if (!name) {\n return [[]]\n } else if (isReferenceType(schemaType)) {\n return schemaType.to.flatMap((referenceType) =>\n resolveAllPaths(schema, referenceType, path).map((nextPath): PathSegment[] => [\n {type: 'deref'},\n ...nextPath,\n ]),\n )\n } else if (schemaType.jsonType === 'object') {\n const fieldType = schemaType.fields.find((field) => field.name === name)?.type\n if (!fieldType) return []\n\n return resolveAllPaths(schema, fieldType, rest).map((nextPath): PathSegment[] => [\n {type: 'attribute', name},\n ...nextPath,\n ])\n } else if (schemaType.jsonType === 'array') {\n const index = parseInt(name, 10)\n return schemaType.of.flatMap((itemType) =>\n resolveAllPaths(schema, itemType, rest).map((nextPath): PathSegment[] => [\n {type: 'element', index},\n ...nextPath,\n ]),\n )\n } else {\n return []\n }\n}\n","import {type Schema} from '@sanity/types'\n\nimport {getProjectionForSchemaType} from './getProjectionForSchemaType'\nimport {\n type PreviewQueryResult,\n type PreviewStoreState,\n type PreviewValue,\n type ValuePending,\n} from './previewStore'\nimport {\n getDraftId,\n getPublishedId,\n hashString,\n STABLE_EMPTY_PREVIEW,\n STABLE_ERROR_PREVIEW,\n} from './util'\n\ninterface ProcessPreviewQueryOptions {\n projectId: string\n dataset: string\n schema: Schema\n ids: Set<string>\n documentTypes: {[TDocumentId in string]?: string}\n results: PreviewQueryResult[]\n}\n\nfunction defaultPrepare(value: Record<string, unknown>): PreviewValue {\n let title\n let subtitle\n\n if ('title' in value) {\n if (typeof value['title'] === 'string') {\n title = value['title']\n }\n }\n\n if ('subtitle' in value) {\n if (typeof value['subtitle'] === 'string') {\n subtitle = value['subtitle']\n }\n }\n\n return {title: title ?? 'Untitled', subtitle}\n}\n\nfunction hasImageAsset<T>(value: unknown): value is T & {asset: {_ref: string}} {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'asset' in value &&\n typeof (value as {asset: unknown}).asset === 'object' &&\n typeof (value as {asset: {_ref: unknown}}).asset?._ref === 'string'\n )\n}\n\nfunction assetIdToUrl(assetId: string, projectId: string, dataset: string) {\n const pattern = /^image-(?<assetName>[A-Za-z0-9]+)-(?<dimensions>\\d+x\\d+)-(?<format>[a-z]+)$/\n const match = assetId.match(pattern)\n if (!match?.groups) {\n throw new Error(\n `Invalid asset ID \\`${assetId}\\`. Expected: image-{assetName}-{width}x{height}-{format}`,\n )\n }\n\n const {assetName, dimensions, format} = match.groups\n return `https://cdn.sanity.io/images/${projectId}/${dataset}/${assetName}-${dimensions}.${format}`\n}\n\nexport function normalizeMedia(\n media: unknown,\n projectId: string,\n dataset: string,\n): PreviewValue['media'] {\n if (!media) return null\n if (!hasImageAsset(media)) return null\n return {type: 'image-asset', url: assetIdToUrl(media.asset._ref, projectId, dataset)}\n}\n\ninterface PreparePreviewForSchemaTypeOptions {\n projectId: string\n dataset: string\n schema: Schema\n schemaTypeName: string\n selectResult: PreviewQueryResult['select']\n}\n\nexport function preparePreviewForSchemaType({\n projectId,\n dataset,\n schema,\n schemaTypeName,\n selectResult,\n}: PreparePreviewForSchemaTypeOptions): Omit<PreviewValue, 'status'> {\n const schemaType = schema.get(schemaTypeName)\n if (!schemaType) {\n throw new Error(\n `Could not find schema type \\`${schemaTypeName}\\` in schema \\`${schema.name}\\`.`,\n )\n }\n const prepare = (schemaType.preview?.prepare ?? defaultPrepare) as (val: unknown) => PreviewValue\n\n try {\n const result = prepare(selectResult)\n return {...result, media: normalizeMedia(result.media, projectId, dataset)}\n } catch (e) {\n const message =\n typeof e === 'object' && e && 'message' in e && typeof e.message === 'string'\n ? e.message\n : 'Unknown error.'\n\n throw new Error(`Failed to prepare preview: ${message}`, {cause: e})\n }\n}\n\nexport function processPreviewQuery({\n projectId,\n dataset,\n schema,\n ids,\n documentTypes,\n results,\n}: ProcessPreviewQueryOptions): PreviewStoreState['values'] {\n const resultMap = results.reduce<{[TDocumentId in string]?: PreviewQueryResult}>((acc, next) => {\n acc[next._id] = next\n return acc\n }, {})\n\n return Object.fromEntries(\n Array.from(ids).map((id): [string, ValuePending<PreviewValue>] => {\n const publishedId = getPublishedId(id)\n const draftId = getDraftId(id)\n\n const draftResult = resultMap[draftId]\n const publishedResult = resultMap[publishedId]\n const documentType = documentTypes[publishedId]\n if (!documentType) return [id, STABLE_EMPTY_PREVIEW]\n\n const selectResult = draftResult?.select ?? publishedResult?.select\n if (!selectResult) return [id, STABLE_EMPTY_PREVIEW]\n\n try {\n const preview = preparePreviewForSchemaType({\n projectId,\n dataset,\n schema,\n schemaTypeName: documentType,\n selectResult,\n })\n const status: PreviewValue['status'] = {\n ...(draftResult?._updatedAt && {lastEditedDraftAt: draftResult._updatedAt}),\n ...(publishedResult?._updatedAt && {lastEditedPublishedAt: publishedResult._updatedAt}),\n }\n\n return [id, {results: {...preview, status}, isPending: false}]\n } catch (e) {\n // TODO: replace this with bubbling the error\n // eslint-disable-next-line no-console\n console.warn(e)\n return [id, STABLE_ERROR_PREVIEW]\n }\n }),\n )\n}\n\ntype ProjectionMap = Record<string, {projection: string; documentTypes: Set<string>}>\n\ninterface CreatePreviewQueryResult {\n query: string\n params: Record<string, string[]>\n}\n\nexport function createPreviewQuery(\n documentIds: Set<string>,\n documentTypes: {[TDocumentId in string]?: string},\n schema: Schema,\n): CreatePreviewQueryResult {\n const documentIdsByDocumentType = Array.from(documentIds).reduce<Record<string, Set<string>>>(\n (acc, id) => {\n const documentType = documentTypes[id]\n if (!documentType) return acc\n\n const ids = acc[documentType] ?? new Set()\n ids.add(id)\n acc[documentType] = ids\n\n return acc\n },\n {},\n )\n\n const projections = Object.keys(documentIdsByDocumentType)\n .map((documentType) => {\n const projection = getProjectionForSchemaType(schema, documentType)\n const projectionHash = hashString(projection)\n return {documentType, projection, projectionHash}\n })\n .reduce<ProjectionMap>((acc, {documentType, projection, projectionHash}) => {\n const obj = acc[projectionHash] ?? {documentTypes: new Set(), projection}\n obj.documentTypes.add(documentType)\n\n acc[projectionHash] = obj\n return acc\n }, {})\n\n const query = `[${Object.entries(projections)\n .map(([projectionHash, {projection}]) => {\n return `...*[_id in $__ids_${projectionHash}]{_id,_type,_updatedAt,\"select\":${projection}}`\n })\n .join(',')}]`\n\n const params = Object.fromEntries(\n Object.entries(projections).map(([projectionHash, value]) => {\n const idsInProjection = Array.from(\n Array.from(value.documentTypes)\n .map((documentType) => documentIdsByDocumentType[documentType] ?? new Set<string>())\n .reduce((acc, next) => {\n for (const i of next) acc.add(i)\n return acc\n }, new Set<string>()),\n ).flatMap((id) => [getPublishedId(id), getDraftId(id)])\n\n return [`__ids_${projectionHash}`, Array.from(idsInProjection)]\n }),\n )\n\n return {query, params}\n}\n","import {type SanityClient, type SyncTag} from '@sanity/client'\nimport {\n combineLatest,\n debounceTime,\n distinctUntilChanged,\n EMPTY,\n map,\n Observable,\n pairwise,\n startWith,\n switchMap,\n tap,\n withLatestFrom,\n} from 'rxjs'\n\nimport {getSubscribableClient} from '../client/actions/getSubscribableClient'\nimport {type ActionContext, createInternalAction} from '../resources/createAction'\nimport {getSchemaState} from '../schema/getSchemaState'\nimport {createPreviewQuery, processPreviewQuery} from './previewQuery'\nimport {type PreviewQueryResult, type PreviewStoreState} from './previewStore'\nimport {PREVIEW_TAG} from './util'\n\nconst BATCH_DEBOUNCE_TIME = 50\n\nexport const subscribeToStateAndFetchBatches = createInternalAction(\n ({state, instance}: ActionContext<PreviewStoreState>) => {\n return function () {\n const client$ = new Observable<SanityClient>((observer) =>\n getSubscribableClient(instance, {apiVersion: 'vX'}).subscribe(observer),\n )\n const schema$ = getSchemaState(instance).observable\n const documentTypes$ = state.observable.pipe(\n map((i) => i.documentTypes),\n distinctUntilChanged(),\n )\n const lastLiveEventId$ = state.observable.pipe(\n map((i) => i.lastLiveEventId),\n distinctUntilChanged(),\n )\n\n const newSubscriberIds$ = state.observable.pipe(\n map(({subscriptions}) => new Set(Object.keys(subscriptions))),\n distinctUntilChanged((a, b) =>\n a.size !== b.size ? false : Array.from(a).every((i) => b.has(i)),\n ),\n debounceTime(BATCH_DEBOUNCE_TIME),\n startWith(new Set<string>()),\n pairwise(),\n tap(([prevIds, currIds]) => {\n // for all new subscriptions, set their values to pending\n const newIds = [...currIds].filter((element) => !prevIds.has(element))\n state.set('updatingPending', (prev) => {\n const pendingValues = newIds.reduce<PreviewStoreState['values']>((acc, id) => {\n const prevValue = prev.values[id]\n const value = prevValue?.results ? prevValue.results : null\n acc[id] = {results: value, isPending: true}\n return acc\n }, {})\n return {values: {...prev.values, ...pendingValues}}\n })\n }),\n withLatestFrom(documentTypes$),\n map(([[, ids], documentTypes]) => ({ids, documentTypes})),\n )\n\n return combineLatest([newSubscriberIds$, lastLiveEventId$, client$, schema$])\n .pipe(\n switchMap(([{ids, documentTypes}, lastLiveEventId, client, schema]) => {\n if (!ids.size) return EMPTY\n const {query, params} = createPreviewQuery(ids, documentTypes, schema)\n\n return client.observable\n .fetch<PreviewQueryResult[]>(query, params, {\n filterResponse: false,\n returnQuery: false,\n tag: PREVIEW_TAG,\n lastLiveEventId,\n })\n .pipe(map((response) => ({...response, ids, schema, documentTypes})))\n }),\n map(({ids, result, syncTags, documentTypes, schema}) => ({\n syncTags,\n values: processPreviewQuery({\n projectId: instance.identity.projectId,\n dataset: instance.identity.dataset,\n ids,\n documentTypes,\n results: result,\n schema,\n }),\n })),\n )\n .subscribe({\n next: ({syncTags = [], values}) => {\n state.set('updateResult', (prev) => ({\n values: {...prev.values, ...values},\n syncTags: syncTags.reduce<Record<SyncTag, true>>((acc, next) => {\n acc[next] = true\n return acc\n }, {}),\n }))\n },\n })\n }\n },\n)\n","import {type SyncTag} from '@sanity/client'\n\nimport {createResource} from '../resources/createResource'\nimport {subscribeToLiveAndSetLastLiveEventId} from './subscribeToLiveAndSetLastLiveEventId'\nimport {subscribeToStateAndFetchBatches} from './subscribeToStateAndFetchBatches'\n\nexport interface PreviewQueryResult {\n _id: string\n _type: string\n _updatedAt: string\n select: Record<string, unknown>\n}\n\n/**\n * Represents the set of values displayed as a preview for a given Sanity document.\n * This includes a primary title, a secondary subtitle, and optional media associated\n * with the document.\n *\n * @public\n */\nexport interface PreviewValue {\n /**\n * The primary text displayed for the document preview.\n */\n title: string\n\n /**\n * A secondary line of text providing additional context about the document.\n */\n subtitle?: string\n\n /**\n * An optional media object, commonly representing an image, that is associated\n * with the document and displayed as part of the preview.\n */\n media?: {type: 'image-asset'; url: string} | null\n\n status?: {\n lastEditedPublishedAt?: string\n lastEditedDraftAt?: string\n }\n}\n\n/**\n * Represents the current state of a preview value along with a flag indicating whether\n * the preview data is still being fetched or is fully resolved.\n *\n * The tuple contains a preview value or null, and a boolean indicating if the data is\n * pending. A `true` value means a fetch is ongoing; `false` indicates that the\n * currently provided preview value is up-to-date.\n *\n * @public\n */\nexport type ValuePending<T> = {\n results: T | null\n isPending: boolean\n}\n\n/**\n * @public\n */\nexport interface PreviewStoreState {\n values: {[TDocumentId in string]?: ValuePending<PreviewValue>}\n documentTypes: {[TDocumentId in string]?: string}\n subscriptions: {[TDocumentId in string]?: {[TSubscriptionId in string]?: true}}\n syncTags: Record<SyncTag, true>\n lastLiveEventId: string | null\n}\n\nexport const previewStore = createResource<PreviewStoreState>({\n name: 'Preview',\n getInitialState() {\n return {\n documentTypes: {},\n lastLiveEventId: null,\n subscriptions: {},\n syncTags: {},\n values: {},\n }\n },\n initialize() {\n const stateSubscriptionForBatches = subscribeToStateAndFetchBatches(this)\n const liveSubscription = subscribeToLiveAndSetLastLiveEventId(this)\n\n return () => {\n stateSubscriptionForBatches.unsubscribe()\n liveSubscription.unsubscribe()\n }\n },\n})\n","import {omit} from 'lodash-es'\n\nimport {type DocumentHandle} from '../documentList/documentListStore'\nimport {createAction} from '../resources/createAction'\nimport {createStateSourceAction, type StateSource} from '../resources/createStateSourceAction'\nimport {\n previewStore,\n type PreviewStoreState,\n type PreviewValue,\n type ValuePending,\n} from './previewStore'\nimport {getPublishedId, randomId, STABLE_EMPTY_PREVIEW} from './util'\n\n/**\n * @public\n */\nexport interface GetPreviewStateOptions {\n document: DocumentHandle\n}\n\nconst _getPreviewState = createStateSourceAction(\n previewStore,\n (state, {document}: GetPreviewStateOptions) => state.values[document._id] ?? STABLE_EMPTY_PREVIEW,\n)\n\n/**\n * @public\n */\nexport const getPreviewState = createAction(previewStore, ({state}) => {\n return function ({document}: GetPreviewStateOptions): StateSource<ValuePending<PreviewValue>> {\n const {_id, _type: documentType} = document\n const documentId = getPublishedId(_id)\n const previewState = _getPreviewState(this, {document})\n\n return {\n ...previewState,\n subscribe: (subscriber) => {\n const subscriptionId = randomId()\n\n state.set('addSubscription', (prev) => ({\n documentTypes: {\n ...prev.documentTypes,\n [documentId]: documentType,\n },\n subscriptions: {\n ...prev.subscriptions,\n [documentId]: {\n ...prev.subscriptions[documentId],\n [subscriptionId]: true,\n },\n },\n }))\n\n const unsubscribe = previewState.subscribe(subscriber)\n\n return () => {\n unsubscribe()\n\n state.set('removeSubscription', (prev): Partial<PreviewStoreState> => {\n const documentSubscriptions = omit(prev.subscriptions[documentId], subscriptionId)\n const hasSubscribers = !!Object.keys(documentSubscriptions).length\n const prevValue = prev.values[documentId]\n const previewValue = prevValue?.results ? prevValue.results : null\n\n return {\n subscriptions: hasSubscribers\n ? {...prev.subscriptions, [documentId]: documentSubscriptions}\n : omit(prev.subscriptions, documentId),\n values: hasSubscribers\n ? prev.values\n : {...prev.values, [documentId]: {results: previewValue, isPending: false}},\n }\n })\n }\n },\n }\n }\n})\n","import {type DocumentHandle} from '../documentList/documentListStore'\nimport {createAction} from '../resources/createAction'\nimport {getPreviewState} from './getPreviewState'\nimport {previewStore, type PreviewValue, type ValuePending} from './previewStore'\n\n/**\n * @public\n */\nexport interface ResolvePreviewOptions {\n document: DocumentHandle\n}\n\n/**\n * @public\n */\nexport const resolvePreview = createAction(previewStore, () => {\n return function ({document}: ResolvePreviewOptions) {\n const {getCurrent, subscribe} = getPreviewState(this, {document})\n\n return new Promise<ValuePending<PreviewValue>>((resolve) => {\n const unsubscribe = subscribe(() => {\n const current = getCurrent()\n if (current?.results) {\n resolve(current)\n unsubscribe()\n }\n })\n })\n }\n})\n","import {type ChannelInput, type ChannelInstance, type Controller} from '@sanity/comlink'\n\nimport {createResource} from '../../resources/createResource'\nimport {type FrameMessage, type WindowMessage} from '../types'\nimport {destroyController} from './actions/destroyController'\n\n/**\n * Individual channel with its relevant options\n * @public\n */\nexport interface ChannelEntry {\n channel: ChannelInstance<FrameMessage, WindowMessage>\n // we store options to ensure that channels remain as unique / consistent as possible\n options: ChannelInput\n // we store refCount to ensure channels remain open only as long as they are in use\n refCount: number\n}\n\n/**\n * Internal state tracking comlink connections\n * @public\n */\nexport interface ComlinkControllerState {\n controller: Controller | null\n controllerOrigin: string | null\n channels: Map<string, ChannelEntry>\n}\n\nexport const comlinkControllerStore = createResource<ComlinkControllerState>({\n name: 'connectionStore',\n getInitialState: () => {\n const initialState = {\n controller: null,\n controllerOrigin: null,\n channels: new Map(),\n }\n return initialState\n },\n initialize() {\n return () => {\n // destroying controller also destroys channels\n destroyController(this)\n }\n },\n})\n","import {createInternalAction} from '../../../resources/createAction'\nimport {type ComlinkControllerState} from '../comlinkControllerStore'\n\n/**\n * Calls the destroy method on the controller and resets the controller state.\n * @public\n */\nexport const destroyController = createInternalAction<ComlinkControllerState, [], void>(\n ({state}) => {\n return () => {\n const {controller} = state.get()\n\n if (controller) {\n controller.destroy()\n state.set('destroyController', {\n controller: null,\n channels: new Map(),\n })\n }\n }\n },\n)\n","import {type ChannelInput} from '@sanity/comlink'\nimport {isEqual} from 'lodash-es'\n\nimport {createAction} from '../../../resources/createAction'\nimport {comlinkControllerStore} from '../comlinkControllerStore'\n\n/**\n * Retrieve or create a channel to be used for communication between\n * an application and the controller.\n * @public\n */\nexport const getOrCreateChannel = createAction(comlinkControllerStore, ({state}) => {\n return (options: ChannelInput) => {\n const controller = state.get().controller\n\n if (!controller) {\n throw new Error('Controller must be initialized before using or creating channels')\n }\n\n const channels = state.get().channels\n const existing = channels.get(options.name)\n\n // limit channels to one per name\n if (existing) {\n if (!isEqual(existing.options, options)) {\n throw new Error(`Channel \"${options.name}\" already exists with different options`)\n }\n\n state.set('incrementChannelRefCount', {\n channels: new Map(channels).set(options.name, {\n ...existing,\n refCount: existing.refCount + 1,\n }),\n })\n existing.channel.start()\n return existing.channel\n }\n\n const channel = controller.createChannel(options)\n channel.start()\n state.set('createChannel', {\n channels: new Map(channels).set(options.name, {\n channel,\n options,\n refCount: 1,\n }),\n })\n\n return channel\n }\n})\n","import {createController} from '@sanity/comlink'\n\nimport {createAction} from '../../../resources/createAction'\nimport {comlinkControllerStore} from '../comlinkControllerStore'\nimport {destroyController} from './destroyController'\n\n/**\n * Initializes or fetches a controller to handle communication\n * between an application and iframes.\n * @public\n */\nexport const getOrCreateController = createAction(comlinkControllerStore, ({state, instance}) => {\n return (targetOrigin: string) => {\n const {controller, controllerOrigin} = state.get()\n if (controller && controllerOrigin === targetOrigin) {\n return controller\n }\n\n // if the target origin has changed, we'll create a new controller,\n // but need to clean up first\n if (controller) {\n destroyController({state, instance})\n }\n\n const newController = createController({targetOrigin})\n state.set('initializeController', {\n controllerOrigin: targetOrigin,\n controller: newController,\n })\n\n return newController\n }\n})\n","import {createAction} from '../../../resources/createAction'\nimport {comlinkControllerStore} from '../comlinkControllerStore'\n\n/**\n * Signals to the store that the consumer has stopped using the channel\n * @public\n */\nexport const releaseChannel = createAction(comlinkControllerStore, ({state}) => {\n return (name: string) => {\n const channels = state.get().channels\n const channelEntry = channels.get(name)\n\n if (channelEntry) {\n const newRefCount = channelEntry.refCount === 0 ? 0 : channelEntry.refCount - 1\n state.set('releaseChannel', {\n channels: new Map(channels).set(name, {\n ...channelEntry,\n refCount: newRefCount,\n }),\n })\n if (newRefCount === 0) {\n channelEntry.channel.stop()\n }\n }\n }\n})\n","import {type Node, type NodeInput} from '@sanity/comlink'\n\nimport {createResource} from '../../resources/createResource'\nimport {type FrameMessage, type WindowMessage} from '../types'\n\n/**\n * Individual node with its relevant options\n * @public\n */\nexport interface NodeEntry {\n node: Node<WindowMessage, FrameMessage>\n // we store options to ensure that channels remain as unique / consistent as possible\n options: NodeInput\n // we store refCount to ensure nodes are running only as long as they are in use\n refCount: number\n}\n\n/**\n * Internal state tracking comlink connections\n * @public\n */\nexport interface ComlinkNodeState {\n nodes: Map<string, NodeEntry>\n}\n\nexport const comlinkNodeStore = createResource<ComlinkNodeState>({\n name: 'nodeStore',\n getInitialState: () => ({\n nodes: new Map(),\n }),\n initialize() {\n return () => {\n const state = this.state.get()\n state.nodes.forEach(({node}) => {\n node.stop()\n })\n }\n },\n})\n","import {createNode, type Node, type NodeInput} from '@sanity/comlink'\nimport {isEqual} from 'lodash-es'\n\nimport {createAction} from '../../../resources/createAction'\nimport {type FrameMessage, type WindowMessage} from '../../types'\nimport {comlinkNodeStore} from '../comlinkNodeStore'\n\n/**\n * Retrieve or create a node to be used for communication between\n * an application and the controller -- specifically, a node should\n * be created within a frame / window to communicate with the controller.\n * @public\n */\nexport const getOrCreateNode = createAction(comlinkNodeStore, ({state}) => {\n return (options: NodeInput) => {\n const nodes = state.get().nodes\n const existing = nodes.get(options.name)\n\n // limit nodes to one per name\n if (existing) {\n if (!isEqual(existing.options, options)) {\n throw new Error(`Node \"${options.name}\" already exists with different options`)\n }\n\n state.set('incrementNodeRefCount', {\n nodes: new Map(nodes).set(options.name, {\n ...existing,\n refCount: existing.refCount + 1,\n }),\n })\n\n existing.node.start()\n return existing.node\n }\n\n const node: Node<WindowMessage, FrameMessage> = createNode(options)\n node.start()\n\n nodes.set(options.name, {node, options, refCount: 1})\n\n state.set('createNode', {nodes})\n\n return node\n }\n})\n","import {createAction} from '../../../resources/createAction'\nimport {comlinkNodeStore} from '../comlinkNodeStore'\n\n/**\n * Signals to the store that the consumer has stopped using the node\n * @public\n */\nexport const releaseNode = createAction(comlinkNodeStore, ({state}) => {\n return (name: string) => {\n const nodes = state.get().nodes\n const nodeEntry = nodes.get(name)\n\n if (nodeEntry) {\n const newRefCount = nodeEntry.refCount === 0 ? 0 : nodeEntry.refCount - 1\n state.set('releaseNode', {\n nodes: new Map(nodes).set(name, {\n ...nodeEntry,\n refCount: newRefCount,\n }),\n })\n if (newRefCount === 0) {\n nodeEntry.node.stop()\n }\n }\n }\n})\n"],"names":["createStore","AuthStateType","DEFAULT_API_VERSION","filter","SchemaConstructor"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/sdk",
3
- "version": "0.0.0-alpha.7",
3
+ "version": "0.0.0-alpha.8",
4
4
  "private": false,
5
5
  "description": "Sanity SDK",
6
6
  "keywords": [
@@ -60,12 +60,12 @@
60
60
  "eslint": "^9.17.0",
61
61
  "prettier": "^3.4.2",
62
62
  "typescript": "^5.7.2",
63
- "vite": "^5.4.14",
63
+ "vite": "^6.1.0",
64
64
  "vitest": "^3.0.5",
65
65
  "@repo/config-eslint": "0.0.0",
66
- "@repo/package.config": "0.0.1",
67
66
  "@repo/config-test": "0.0.1",
68
- "@repo/tsconfig": "0.0.1"
67
+ "@repo/tsconfig": "0.0.1",
68
+ "@repo/package.config": "0.0.1"
69
69
  },
70
70
  "engines": {
71
71
  "node": ">=20.0.0"
@@ -12,6 +12,7 @@ export type {StateSource} from '../resources/createStateSourceAction'
12
12
  /** CLIENT */
13
13
  // Utils
14
14
  export {type ClientOptions, getClient} from '../client/actions/getClient'
15
+ export {getGlobalClient} from '../client/actions/getGlobalClient'
15
16
  export {getSubscribableClient} from '../client/actions/getSubscribableClient'
16
17
  // Types
17
18
  export type {ClientState} from '../client/clientStore'
@@ -0,0 +1,27 @@
1
+ import {beforeEach, describe, expect, test} from 'vitest'
2
+
3
+ import {config} from '../../../test/fixtures'
4
+ import {createSanityInstance} from '../../instance/sanityInstance'
5
+ import {type SanityInstance} from '../../instance/types'
6
+ import {getGlobalClient} from './getGlobalClient'
7
+
8
+ describe('getGlobalClient', () => {
9
+ let instance: SanityInstance
10
+
11
+ beforeEach(() => {
12
+ instance = createSanityInstance(config)
13
+ })
14
+
15
+ test('returns the default client from the store', () => {
16
+ const client = getGlobalClient(instance)
17
+ expect(client.config().apiVersion).toBe('X')
18
+ expect(client.config().useProjectHostname).toBe(false)
19
+ expect(client.config().apiHost).toBe('https://api.sanity.io')
20
+ })
21
+
22
+ test('returns the same client instance on subsequent calls', () => {
23
+ const client1 = getGlobalClient(instance)
24
+ const client2 = getGlobalClient(instance)
25
+ expect(client1).toBe(client2)
26
+ })
27
+ })
@@ -0,0 +1,13 @@
1
+ import {createAction} from '../../resources/createAction'
2
+ import {clientStore} from '../clientStore'
3
+
4
+ /**
5
+ * Retrieves the global, project-less client.
6
+ * @public
7
+ */
8
+ export const getGlobalClient = createAction(
9
+ clientStore,
10
+ ({state}) =>
11
+ () =>
12
+ state.get().defaultGlobalClient,
13
+ )
@@ -6,6 +6,9 @@ const receiveToken = (prev: ClientState, token: string | undefined): ClientState
6
6
  const newDefaultClient = prev.defaultClient.withConfig({
7
7
  token,
8
8
  })
9
+ const newGlobalClient = prev.defaultGlobalClient.withConfig({
10
+ token,
11
+ })
9
12
  const updatedClients = new Map(
10
13
  Array.from(prev.clients.entries()).map(([version, client]) => [
11
14
  version,
@@ -15,6 +18,7 @@ const receiveToken = (prev: ClientState, token: string | undefined): ClientState
15
18
 
16
19
  return {
17
20
  defaultClient: newDefaultClient,
21
+ defaultGlobalClient: newGlobalClient,
18
22
  clients: updatedClients,
19
23
  }
20
24
  }
@@ -51,13 +51,14 @@ describe('clientStore', () => {
51
51
  expect(state.defaultClient.config().apiHost).toBe('https://api.sanity.work')
52
52
  })
53
53
 
54
- it('initializes clients Map with default client', () => {
54
+ it('initializes clients Map with default clients', () => {
55
55
  const instance = createSanityInstance(config)
56
56
  const store = getOrCreateResource(instance, clientStore)
57
57
  const state = store.state.get()
58
58
 
59
- expect(state.clients.size).toBe(1)
59
+ expect(state.clients.size).toBe(2)
60
60
  expect(state.clients.get('2024-11-12')).toBe(state.defaultClient)
61
+ expect(state.clients.get('global-vX')).toBe(state.defaultGlobalClient)
61
62
  })
62
63
 
63
64
  it('maintains separate stores for different instances', () => {
@@ -12,6 +12,7 @@ const DEFAULT_API_VERSION = '2024-11-12'
12
12
  */
13
13
  export interface ClientState {
14
14
  defaultClient: SanityClient
15
+ defaultGlobalClient: SanityClient
15
16
  clients: Map<string, SanityClient>
16
17
  }
17
18
 
@@ -29,11 +30,21 @@ export const clientStore: Resource<ClientState> = createResource({
29
30
  ...(config?.auth?.apiHost ? {apiHost: config.auth.apiHost} : {}),
30
31
  })
31
32
 
33
+ const defaultGlobalClient = createClient({
34
+ token: config?.auth?.token,
35
+ useCdn: false,
36
+ apiVersion: 'vX', // Many global APIs are only available under this version, we may need to support other versions in the future
37
+ useProjectHostname: false,
38
+ ...(config?.auth?.apiHost ? {apiHost: config.auth.apiHost} : {}),
39
+ })
40
+
32
41
  const clients = new Map<string, SanityClient>()
33
42
  clients.set(DEFAULT_API_VERSION, defaultClient)
43
+ clients.set('global-vX', defaultGlobalClient)
34
44
 
35
45
  return {
36
46
  defaultClient,
47
+ defaultGlobalClient,
37
48
  clients,
38
49
  }
39
50
  },