{"version":3,"file":"LiveQueryProvider.cjs","sources":["../../src/LiveQueryProvider/constants.ts","../../src/LiveQueryProvider/useLiveEvents.ts","../../src/LiveQueryProvider/utils.ts","../../src/LiveQueryProvider/useLiveQueries.ts","../../src/LiveQueryProvider/usePerspective.ts","../../src/LiveQueryProvider/LiveQueryProvider.tsx"],"sourcesContent":["export const DEFAULT_TAG = 'sanity.preview-kit'\n","import {type LiveEvent, type LiveEventMessage} from '@sanity/client'\nimport {useDeferredValue, useEffect, useReducer, useState} from 'react'\n\nimport type {LiveQueryProviderProps} from '../types'\nimport {DEFAULT_TAG} from './constants'\n\ntype State = {\n  /**\n   * Growing list over live events with Sync Tags,\n   * that can be used to refetch with Sanity Client, using the id as the lastLiveEventId parameter\n   */\n  messages: LiveEventMessage[]\n  /**\n   * If the connection experiences a reconnect, or a restart event is received, the counter is incremented.\n   * This counter is suitable as a `key` on React Components as a way to reset its internal state and refetch.\n   */\n  resets: number\n}\n\nexport function reducer(state: State, event: LiveEvent): State {\n  switch (event.type) {\n    case 'message':\n      return {\n        ...state,\n        messages: [...state.messages, event],\n      }\n    case 'reconnect':\n    case 'restart':\n      return {\n        ...state,\n        messages: [],\n        resets: state.resets + 1,\n      }\n    case 'welcome':\n      // no-op\n      return state\n    default:\n      throw Error(\n        `Unknown event: ${\n          // eslint-disable-next-line @typescript-eslint/no-explicit-any\n          (event as any).type\n        }`,\n        {cause: event},\n      )\n  }\n}\n\nexport const initialState: State = {\n  messages: [],\n  resets: 0,\n}\n\nexport function useLiveEvents(client: LiveQueryProviderProps['client']): State {\n  const [state, dispatch] = useReducer(reducer, initialState)\n  const [error, setError] = useState<unknown>(null)\n  if (error !== null) {\n    // Push error to nearest error boundary\n    throw error\n  }\n\n  useEffect(() => {\n    const subscription = client.live.events({includeDrafts: true, tag: DEFAULT_TAG}).subscribe({\n      next: dispatch,\n      error: (err) =>\n        setError(\n          err instanceof Error ? err : new Error('Unexpected error in useLiveEvents', {cause: err}),\n        ),\n    })\n    return () => subscription.unsubscribe()\n  }, [client.live])\n\n  return useDeferredValue(state)\n}\n","import {type ClientPerspective, type QueryParams} from '@sanity/client'\n\n/**\n * Cache key format: `query:{\"params\":...,\"perspective\":...}`\n * @internal\n */\nexport type QueryCacheKey = `${string}:${string}`\n\nexport function getQueryCacheKey(\n  query: string,\n  params: QueryParams,\n  perspective: Exclude<ClientPerspective, 'raw'>,\n): QueryCacheKey {\n  return `${query}:${JSON.stringify({params, perspective})}`\n}\n","import {\n  type ClientPerspective,\n  type ContentSourceMap,\n  type QueryParams,\n  type SyncTag,\n} from '@sanity/client'\nimport {useCallback, useReducer, useState} from 'react'\nimport isEqual from 'react-fast-compare'\n\nimport {getQueryCacheKey, type QueryCacheKey} from './utils'\n\nexport type OnStoreChange = () => void\n\ntype LiveQueriesState = Map<\n  QueryCacheKey,\n  {\n    query: string\n    params: QueryParams\n    perspective: Exclude<ClientPerspective, 'raw'>\n    listeners: Set<OnStoreChange>\n  }\n>\n\nexport type LiveSnapshots = Map<\n  QueryCacheKey,\n  {\n    result: unknown\n    resultSourceMap: ContentSourceMap | null | undefined\n    syncTags: SyncTag[] | undefined\n  }\n>\n\ntype SubscribeAction = {\n  type: 'subscribe'\n  payload: {\n    query: string\n    params: QueryParams\n    perspective: Exclude<ClientPerspective, 'raw'>\n    onStoreChange: OnStoreChange\n  }\n}\ntype UnsubscribeAction = {\n  type: 'unsubscribe'\n  payload: {\n    query: string\n    params: QueryParams\n    perspective: Exclude<ClientPerspective, 'raw'>\n    onStoreChange: OnStoreChange\n  }\n}\nexport type SnapshotAction = {\n  type: 'snapshot'\n  payload: {\n    query: string\n    params: QueryParams\n    result: unknown\n    resultSourceMap: ContentSourceMap | undefined\n    perspective: Exclude<ClientPerspective, 'raw'>\n    tags: `s1:${string}`[] | undefined\n  }\n}\ntype Action = SubscribeAction | UnsubscribeAction | SnapshotAction\n\nfunction subscribe(queries: LiveQueriesState, {payload}: SubscribeAction): LiveQueriesState {\n  const key = getQueryCacheKey(payload.query, payload.params, payload.perspective)\n\n  if (!queries.get(key)?.listeners.has(payload.onStoreChange)) {\n    const nextQueries = new Map(queries)\n    const value = nextQueries.get(key) || {\n      query: payload.query,\n      params: payload.params,\n      perspective: payload.perspective,\n      listeners: new Set(),\n    }\n    const listeners = new Set(value.listeners)\n    listeners.add(payload.onStoreChange)\n    nextQueries.set(key, {...value, listeners})\n    return nextQueries\n  }\n\n  return queries\n}\n\nfunction unsubscribe(queries: LiveQueriesState, {payload}: UnsubscribeAction): LiveQueriesState {\n  const key = getQueryCacheKey(payload.query, payload.params, payload.perspective)\n\n  const value = queries.get(key)\n  if (!value) {\n    return queries\n  }\n  if (!value.listeners.has(payload.onStoreChange)) {\n    return queries\n  }\n  const nextQueries = new Map(queries)\n  const listeners = new Set(value.listeners)\n  listeners.delete(payload.onStoreChange)\n  if (listeners.size === 0) {\n    nextQueries.delete(key)\n  } else {\n    nextQueries.set(key, {...value, listeners})\n  }\n  return nextQueries\n}\n\nexport function reducer(state: LiveQueriesState, action: Action): LiveQueriesState {\n  switch (action.type) {\n    case 'subscribe':\n      return subscribe(state, action)\n    case 'unsubscribe':\n      return unsubscribe(state, action)\n    default:\n      throw Error(\n        `Unknown action: ${\n          // eslint-disable-next-line @typescript-eslint/no-explicit-any\n          (action as any).type\n        }`,\n        {cause: action},\n      )\n  }\n}\n\nexport const initialQueries: LiveQueriesState = new Map()\n\nexport type LiveQueriesDispatch = React.Dispatch<Action>\n\nexport type LiveQueriesUpdate = (\n  key: QueryCacheKey,\n  result: unknown,\n  resultSourceMap: ContentSourceMap | null | undefined,\n  syncTags: SyncTag[] | undefined,\n) => boolean\n\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nexport function useLiveQueries() {\n  const [queries, dispatch] = useReducer(reducer, initialQueries)\n  const [snapshots] = useState<LiveSnapshots>(() => new Map())\n\n  const subscribe = useCallback((payload: SubscribeAction['payload']): (() => void) => {\n    dispatch({type: 'subscribe', payload})\n    return () => dispatch({type: 'unsubscribe', payload})\n  }, [])\n  /**\n   * This handler is intentionally mutating the snapshots state, this is so that useSyncExternalStore hooks\n   * can read the current state in its getSnapshot handlers.\n   * The caller is responsible for looping over listeners in order to notify the stores.\n   */\n  const update = useCallback<LiveQueriesUpdate>(\n    (key, result, resultSourceMap, syncTags) => {\n      const prev = snapshots.get(key)\n      if (prev && isEqual(prev, {result, resultSourceMap, syncTags})) {\n        return false\n      }\n      snapshots.set(key, {\n        result: isEqual(prev?.result, result) ? prev?.result : result,\n        resultSourceMap: isEqual(prev?.resultSourceMap, resultSourceMap)\n          ? prev?.resultSourceMap\n          : resultSourceMap,\n        syncTags: isEqual(prev?.syncTags, syncTags) ? prev?.syncTags : syncTags,\n      })\n\n      return true\n    },\n    [snapshots],\n  )\n\n  return {queries, snapshots, subscribe, update}\n}\n","import type {ClientPerspective} from '@sanity/client'\nimport {createNode, createNodeMachine} from '@sanity/comlink'\nimport {\n  createCompatibilityActors,\n  type LoaderControllerMsg,\n  type LoaderNodeMsg,\n} from '@sanity/presentation-comlink'\nimport {useEffect, useState} from 'react'\nimport isEqual from 'react-fast-compare'\n\nexport function usePerspective(\n  initialPerspective: Exclude<ClientPerspective, 'raw'>,\n): Exclude<ClientPerspective, 'raw'> {\n  const [presentationPerspective, setPresentationPerspective] = useState<Exclude<\n    ClientPerspective,\n    'raw'\n  > | null>(null)\n\n  useEffect(() => {\n    const comlink = createNode<LoaderNodeMsg, LoaderControllerMsg>(\n      {\n        name: 'loaders',\n        connectTo: 'presentation',\n      },\n      createNodeMachine<LoaderNodeMsg, LoaderControllerMsg>().provide({\n        actors: createCompatibilityActors<LoaderNodeMsg>(),\n      }),\n    )\n\n    comlink.on('loader/perspective', ({perspective}) => {\n      if (perspective !== 'raw') {\n        setPresentationPerspective((prev) => (isEqual(prev, perspective) ? prev : perspective))\n      }\n    })\n\n    const stop = comlink.start()\n    return () => stop()\n  }, [])\n  return presentationPerspective === null ? initialPerspective : presentationPerspective\n}\n","import type {ClientPerspective, LiveEventMessage, QueryParams, SyncTag} from '@sanity/client'\nimport {useEffect, useMemo, useState} from 'react'\n\nimport {defineStoreContext as Context} from '../context'\nimport {useQueryPerspective, useShouldPause} from '../hooks'\nimport type {\n  DefineListenerContext,\n  ListenerGetSnapshot,\n  ListenerSubscribe,\n  LiveQueryProviderProps,\n} from '../types'\nimport {DEFAULT_TAG} from './constants'\nimport {useLiveEvents} from './useLiveEvents'\nimport {type LiveQueriesUpdate, type OnStoreChange, useLiveQueries} from './useLiveQueries'\nimport {usePerspective} from './usePerspective'\nimport {getQueryCacheKey, type QueryCacheKey} from './utils'\n\n/**\n * @internal\n */\nexport default function LiveStoreProvider(props: LiveQueryProviderProps): React.JSX.Element {\n  const {children, token} = props\n\n  if (!props.client) {\n    throw new Error('Missing a `client` prop with a configured Sanity client instance')\n  }\n\n  const perspective = useQueryPerspective(usePerspective(props.perspective || 'drafts'))\n\n  // Ensure these values are stable even if userland isn't memoizing properly\n  const [client] = useState(() => {\n    const {requestTagPrefix} = props.client.config()\n    return props.client.withConfig({\n      requestTagPrefix: requestTagPrefix || DEFAULT_TAG,\n      // Set the recommended defaults, this is a convenience to make it easier to share a client config from a server component to the client component\n      ...(token && {\n        token,\n        useCdn: false,\n        perspective: 'drafts',\n        ignoreBrowserTokenWarning: true,\n      }),\n    })\n  })\n  const [logger] = useState(() => props.logger)\n\n  useEffect(() => {\n    if (logger) {\n      logger.log(\n        `[@sanity/preview-kit]: Updates will be applied in real-time using the Sanity Live Content API.`,\n      )\n    }\n  }, [logger])\n\n  const {queries, snapshots, subscribe, update} = useLiveQueries()\n\n  const context = useMemo(() => {\n    return function defineListener<QueryResult>(\n      initialSnapshot: QueryResult,\n      query: string,\n      params: QueryParams,\n      hookPerspective: Exclude<ClientPerspective, 'raw'> | null,\n    ) {\n      const effectivePerspective = hookPerspective || perspective\n      const snapshotsKey = getQueryCacheKey(query, params, effectivePerspective)\n      const contextSubscribe: ListenerSubscribe = (onStoreChange) => {\n        const unsubscribe = subscribe({\n          query,\n          params,\n          perspective: effectivePerspective,\n          onStoreChange,\n        })\n\n        return () => unsubscribe()\n      }\n      const getSnapshot: ListenerGetSnapshot<QueryResult> = () =>\n        snapshots.has(snapshotsKey)\n          ? (snapshots.get(snapshotsKey)?.result as unknown as QueryResult)\n          : initialSnapshot\n\n      return {subscribe: contextSubscribe, getSnapshot}\n    } satisfies DefineListenerContext\n  }, [perspective, snapshots, subscribe])\n\n  const liveEvents = useLiveEvents(client)\n\n  return (\n    <Context.Provider value={context}>\n      {children}\n      {[...queries.entries()].map(([key, {query, params, perspective, listeners}]) => {\n        return (\n          <QuerySubscription\n            key={`${liveEvents.resets}:${key}`}\n            client={client}\n            listeners={listeners}\n            params={params}\n            query={query}\n            perspective={perspective}\n            liveEventsMessages={liveEvents.messages}\n            snapshotKey={key}\n            syncTags={snapshots.get(key)?.syncTags}\n            update={update}\n          />\n        )\n      })}\n    </Context.Provider>\n  )\n}\nLiveStoreProvider.displayName = 'LiveStoreProvider'\n\ninterface QuerySubscriptionProps extends Required<Pick<LiveQueryProviderProps, 'client'>> {\n  query: string\n  params: QueryParams\n  perspective: Exclude<ClientPerspective, 'raw'>\n  update: LiveQueriesUpdate\n  snapshotKey: QueryCacheKey\n  liveEventsMessages: LiveEventMessage[]\n  syncTags: SyncTag[] | undefined\n  listeners: Set<OnStoreChange>\n}\nfunction QuerySubscription(props: QuerySubscriptionProps) {\n  const {\n    client,\n    query,\n    params,\n    perspective,\n    snapshotKey,\n    update,\n    liveEventsMessages,\n    syncTags,\n    listeners,\n  } = props\n\n  const [skipEventIds] = useState(() => new Set(liveEventsMessages.map((msg) => msg.id)))\n  const recentLiveEvents = useMemo(\n    () => liveEventsMessages.filter((msg) => !skipEventIds.has(msg.id)),\n    [liveEventsMessages, skipEventIds],\n  )\n  const lastLiveEvent = useMemo(\n    () => recentLiveEvents.findLast((msg) => msg.tags.some((tag) => syncTags?.includes(tag))),\n    [recentLiveEvents, syncTags],\n  )\n  const lastLiveEventId = lastLiveEvent?.id\n\n  // Make sure any async errors bubble up to the nearest error boundary\n  const [error, setError] = useState<unknown>(null)\n  if (error) throw error\n\n  const shouldPause = useShouldPause()\n  useEffect(() => {\n    if (shouldPause) {\n      return\n    }\n    let fulfilled = false\n    const controller = new AbortController()\n\n    client\n      .fetch(query, params, {\n        lastLiveEventId,\n        perspective,\n        signal: controller.signal,\n        filterResponse: false,\n        returnQuery: false,\n      })\n      .then(({result, resultSourceMap, syncTags: nextTags}) => {\n        update(snapshotKey, result, resultSourceMap, nextTags)\n        for (const listener of listeners) {\n          listener()\n        }\n        fulfilled = true\n      })\n      .catch((error) => {\n        if (error.name !== 'AbortError') {\n          setError(error)\n        }\n      })\n\n    return () => {\n      if (!fulfilled) {\n        controller.abort()\n      }\n    }\n  }, [\n    client,\n    lastLiveEventId,\n    listeners,\n    params,\n    perspective,\n    query,\n    shouldPause,\n    snapshotKey,\n    update,\n  ])\n\n  return null\n}\nQuerySubscription.displayName = 'QuerySubscription'\n"],"names":["reducer","useReducer","useState","useEffect","useDeferredValue","subscribe","useCallback","isEqual","comlink","createNode","createNodeMachine","createCompatibilityActors","useQueryPerspective","useMemo","unsubscribe","jsxs","Context","perspective","jsx","useShouldPause","error"],"mappings":"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"}