{"version":3,"file":"_unstable_store.cjs","sources":["../src/store/createReadOnlyStore.ts","../src/store/listeners/errors.ts","../src/store/listeners/utils/eventChainUtils.ts","../src/store/listeners/utils/sequentializeListenerEvents.ts","../src/store/listeners/createDocumentEventListener.ts","../src/store/utils/createDataLoader.ts","../src/store/listeners/createDocumentLoader.ts","../src/store/listeners/createDocumentUpdateListener.ts","../src/store/listeners/createIdSetListener.ts","../src/store/listeners/utils/shareReplayLatest.ts","../src/store/listeners/utils/withListenErrors.ts","../src/store/listeners/createSharedListener.ts","../src/store/mock/createMockBackendAPI.ts","../src/store/optimistic/backend/createOptimisticStoreClientBackend.ts","../src/store/optimistic/backend/createOptimisticStoreMockBackend.ts"],"sourcesContent":["import {\n  combineLatest,\n  finalize,\n  type Observable,\n  ReplaySubject,\n  share,\n  timer,\n} from 'rxjs'\n\nimport {type SanityDocumentBase} from '../mutations/types'\nimport {\n  type DocumentUpdate,\n  type DocumentUpdateListener,\n} from './listeners/createDocumentUpdateListener'\n\nexport type MapTuple<T, U> = {[K in keyof T]: U}\n\nexport interface ReadOnlyDocumentStore {\n  listenDocument: <Doc extends SanityDocumentBase>(\n    id: string,\n  ) => Observable<DocumentUpdate<Doc>>\n  listenDocuments: <\n    Doc extends SanityDocumentBase,\n    const IdTuple extends string[],\n  >(\n    id: IdTuple,\n  ) => Observable<MapTuple<IdTuple, DocumentUpdate<Doc>>>\n}\n\n/**\n * @param listenDocumentUpdates – a function that takes a document id and returns  an observable of document snapshots\n * @param options\n */\nexport function createReadOnlyStore(\n  listenDocumentUpdates: DocumentUpdateListener<SanityDocumentBase>,\n  options: {shutdownDelay?: number} = {},\n): ReadOnlyDocumentStore {\n  const cache = new Map<\n    string,\n    Observable<DocumentUpdate<SanityDocumentBase>>\n  >()\n\n  const {shutdownDelay} = options\n\n  function listenDocument<Doc extends SanityDocumentBase>(id: string) {\n    if (cache.has(id)) {\n      return cache.get(id)! as Observable<DocumentUpdate<Doc>>\n    }\n    const cached = listenDocumentUpdates(id).pipe(\n      finalize(() => cache.delete(id)),\n      share({\n        resetOnRefCountZero:\n          typeof shutdownDelay === 'number' ? () => timer(shutdownDelay) : true,\n        connector: () => new ReplaySubject(1),\n      }),\n    )\n    cache.set(id, cached)\n    return cached as Observable<DocumentUpdate<Doc>>\n  }\n  return {\n    listenDocument,\n    listenDocuments<Doc extends SanityDocumentBase, IdTuple extends string[]>(\n      ids: IdTuple,\n    ) {\n      return combineLatest(\n        ids.map(id => listenDocument<Doc>(id)),\n      ) as Observable<MapTuple<IdTuple, DocumentUpdate<Doc>>>\n    },\n  }\n}\n","import {ClientError as SanityClientError} from '@sanity/client'\n\nimport {type ListenerSequenceState} from './utils/sequentializeListenerEvents'\n\n/*\n * This file should include all errors that can be thrown by the document listener\n */\n\nexport const ClientError = SanityClientError\n\nexport class FetchError extends Error {\n  cause?: Error\n  constructor(message: string, extra?: {cause?: Error}) {\n    super(message)\n    this.cause = extra?.cause\n    this.name = 'FetchError'\n  }\n}\n\nexport class PermissionDeniedError extends Error {\n  cause?: Error\n  constructor(message: string, extra?: {cause?: Error}) {\n    super(message)\n    this.cause = extra?.cause\n    this.name = 'PermissionDeniedError'\n  }\n}\n\nexport class ChannelError extends Error {\n  constructor(message: string) {\n    super(message)\n    this.name = 'ChannelError'\n  }\n}\n\nexport class DisconnectError extends Error {\n  constructor(message: string) {\n    super(message)\n    this.name = 'DisconnectError'\n  }\n}\n\nexport class OutOfSyncError extends Error {\n  /**\n   * Attach state to the error for debugging/reporting\n   */\n  state: ListenerSequenceState\n  constructor(message: string, state: ListenerSequenceState) {\n    super(message)\n    this.name = 'OutOfSyncError'\n    this.state = state\n  }\n}\n\nexport class DeadlineExceededError extends OutOfSyncError {\n  constructor(message: string, state: ListenerSequenceState) {\n    super(message, state)\n    this.name = 'DeadlineExceededError'\n  }\n}\nexport class MaxBufferExceededError extends OutOfSyncError {\n  constructor(message: string, state: ListenerSequenceState) {\n    super(message, state)\n    this.name = 'MaxBufferExceededError'\n  }\n}\n\nexport function isClientError(e: unknown): e is SanityClientError {\n  if (typeof e !== 'object') return false\n  if (!e) return false\n  return 'statusCode' in e && 'response' in e\n}\n","export function discardChainTo<T extends {resultRev?: string}>(\n  chain: T[],\n  revision: string | undefined,\n) {\n  const revisionIndex = chain.findIndex(event => event.resultRev === revision)\n\n  return split(chain, revisionIndex + 1)\n}\n\nfunction split<T>(array: T[], index: number): [T[], T[]] {\n  if (index < 0) {\n    return [[], array]\n  }\n  return [array.slice(0, index), array.slice(index)]\n}\n\nexport function toOrderedChains<\n  T extends {previousRev?: string; resultRev?: string},\n>(events: T[]) {\n  const parents: Record<string, T | undefined> = {}\n\n  events.forEach(event => {\n    parents[event.resultRev || 'undefined'] = events.find(\n      other => other.resultRev === event.previousRev,\n    )\n  })\n\n  // get entries without a parent (if there's more than one, we have a problem)\n  const orphans = Object.entries(parents).filter(([, parent]) => {\n    return !parent\n  })!\n\n  return orphans.map(orphan => {\n    const [headRev] = orphan\n\n    let current = events.find(event => event.resultRev === headRev)\n\n    const sortedList: T[] = []\n    while (current) {\n      sortedList.push(current)\n\n      current = events.find(event => event.previousRev === current?.resultRev)\n    }\n    return sortedList\n  })\n}\n","import {partition as lodashPartition} from 'lodash'\nimport {concat, type Observable, of, switchMap, throwError, timer} from 'rxjs'\nimport {mergeMap, scan} from 'rxjs/operators'\n\nimport {type SanityDocumentBase} from '../../../mutations/types'\nimport {type ListenerEvent, type ListenerMutationEvent} from '../../types'\nimport {DeadlineExceededError, MaxBufferExceededError} from '../errors'\nimport {discardChainTo, toOrderedChains} from './eventChainUtils'\n\n/**\n * lodash types are not great\n * todo: replace with es-toolkit\n * @param array\n * @param predicate\n */\nfunction partition<T>(\n  array: T[],\n  predicate: (element: T) => boolean,\n): [trueValues: T[], falseValues: T[]] {\n  return lodashPartition(array, predicate)\n}\nexport interface ListenerSequenceState {\n  /**\n   * Tracks the latest revision from the server that can be applied locally\n   * Once we receive a mutation event that has a `previousRev` that equals `base.revision`\n   * we will move `base.revision` to the event's `resultRev`\n   * `base.revision` will be undefined if document doesn't exist.\n   * `base` is `undefined` until the snapshot event is received\n   */\n  base: {revision: string | undefined} | undefined\n  /**\n   * Array of events to pass on to the stream, e.g. when mutation applies to current head revision, or a chain is complete\n   */\n  emitEvents: ListenerEvent[]\n  /**\n   * Buffer to keep track of events that doesn't line up in a [previousRev, resultRev] -- [previousRev, resultRev] sequence\n   * This can happen if events arrive out of order, or if an event in the middle for some reason gets lost\n   */\n  buffer: ListenerMutationEvent[]\n}\n\nconst DEFAULT_MAX_BUFFER_SIZE = 20\nconst DEFAULT_DEADLINE_MS = 30000\n\nconst EMPTY_ARRAY: never[] = []\n\nexport interface SequentializeListenerEventsOptions {\n  maxBufferSize?: number\n  resolveChainDeadline?: number\n  onDiscard?: (discarded: ListenerMutationEvent[]) => void\n  onBrokenChain?: (discarded: ListenerMutationEvent[]) => void\n}\n\n/**\n * Takes an input observable of listener events that might arrive out of order, and emits them in sequence\n * If we receive mutation events that doesn't line up in [previousRev, resultRev] pairs we'll put them in a buffer and\n * check if we have an unbroken chain every time we receive a new event\n *\n * If the buffer grows beyond `maxBufferSize`, or if `resolveChainDeadline` milliseconds passes before the chain resolves\n * an OutOfSyncError will be thrown on the stream\n *\n * @internal\n */\nexport function sequentializeListenerEvents<Doc extends SanityDocumentBase>(\n  options?: SequentializeListenerEventsOptions,\n) {\n  const {\n    resolveChainDeadline = DEFAULT_DEADLINE_MS,\n    maxBufferSize = DEFAULT_MAX_BUFFER_SIZE,\n    onDiscard,\n    onBrokenChain,\n  } = options || {}\n\n  return (input$: Observable<ListenerEvent>): Observable<ListenerEvent> => {\n    return input$.pipe(\n      scan(\n        (\n          state: ListenerSequenceState,\n          event: ListenerEvent,\n        ): ListenerSequenceState => {\n          if (event.type === 'mutation' && !state.base) {\n            throw new Error(\n              'Invalid state. Cannot create a sequence without a base',\n            )\n          }\n          if (event.type === 'sync') {\n            // When receiving a new snapshot, we can safely discard the current orphaned and chainable buffers\n            return {\n              base: {revision: event.document?._rev},\n              buffer: EMPTY_ARRAY,\n              emitEvents: [event],\n            }\n          }\n\n          if (event.type === 'mutation') {\n            if (!event.resultRev && !event.previousRev) {\n              throw new Error(\n                'Invalid mutation event: Events must have either resultRev or previousRev',\n              )\n            }\n            // Note: the buffer may have multiple holes in it (this is a worst case scenario, and probably not likely, but still),\n            // so we need to consider all possible chains\n            // `toOrderedChains` will return all detected chains and each of the returned chains will be ordered\n            // Once we have a list of chains, we can then discard any chain that leads up to the current revision\n            // since they are already applied on the document\n            const orderedChains = toOrderedChains(\n              state.buffer.concat(event),\n            ).map(chain => {\n              // in case the chain leads up to the current revision\n              const [discarded, rest] = discardChainTo(\n                chain,\n                state.base!.revision,\n              )\n              if (onDiscard && discarded.length > 0) {\n                onDiscard(discarded)\n              }\n              return rest\n            })\n\n            const [applicableChains, _nextBuffer] = partition(\n              orderedChains,\n              chain => {\n                // note: there can be at most one applicable chain\n                return state.base!.revision === chain[0]?.previousRev\n              },\n            )\n\n            const nextBuffer = _nextBuffer.flat()\n            if (applicableChains.length > 1) {\n              throw new Error('Expected at most one applicable chain')\n            }\n            if (\n              applicableChains.length > 0 &&\n              applicableChains[0]!.length > 0\n            ) {\n              // we now have a continuous chain that can apply on the base revision\n              // Move current base revision to the last mutation event in the applicable chain\n              const lastMutation = applicableChains[0]!.at(-1)!\n              const nextBaseRevision =\n                // special case: if the mutation deletes the document it technically has  no revision, despite\n                // resultRev pointing at a transaction id.\n                lastMutation.transition === 'disappear'\n                  ? undefined\n                  : lastMutation?.resultRev\n              return {\n                base: {revision: nextBaseRevision},\n                emitEvents: applicableChains[0]!,\n                buffer: nextBuffer,\n              }\n            }\n\n            if (nextBuffer.length >= maxBufferSize) {\n              throw new MaxBufferExceededError(\n                `Too many unchainable mutation events: ${state.buffer.length}`,\n                state,\n              )\n            }\n            return {\n              ...state,\n              buffer: nextBuffer,\n              emitEvents: EMPTY_ARRAY,\n            }\n          }\n          // Any other event (e.g. 'reconnect' is passed on verbatim)\n          return {...state, emitEvents: [event]}\n        },\n        {\n          emitEvents: EMPTY_ARRAY,\n          base: undefined,\n          buffer: EMPTY_ARRAY,\n        },\n      ),\n      switchMap(state => {\n        if (state.buffer.length > 0) {\n          onBrokenChain?.(state.buffer)\n          return concat(\n            of(state),\n            timer(resolveChainDeadline).pipe(\n              mergeMap(() =>\n                throwError(() => {\n                  return new DeadlineExceededError(\n                    `Did not resolve chain within a deadline of ${resolveChainDeadline}ms`,\n                    state,\n                  )\n                }),\n              ),\n            ),\n          )\n        }\n        return of(state)\n      }),\n      mergeMap(state => {\n        // this will simply flatten the list of events into individual emissions\n        // if the flushEvents array is empty, nothing will be emitted\n        return state.emitEvents\n      }),\n    )\n  }\n}\n","import {type ReconnectEvent, type WelcomeEvent} from '@sanity/client'\nimport {\n  catchError,\n  concatMap,\n  EMPTY,\n  map,\n  type Observable,\n  of,\n  throwError,\n} from 'rxjs'\n\nimport {type SanityDocumentBase} from '../../mutations/types'\nimport {type ListenerMutationEvent, type ListenerSyncEvent} from '../types'\nimport {FetchError, isClientError, PermissionDeniedError} from './errors'\nimport {type DocumentLoader} from './types'\nimport {sequentializeListenerEvents} from './utils/sequentializeListenerEvents'\n\n/**\n * Creates a function that can be used to listen for events that happens in a single document\n * Features\n *  - builtin retrying and connection recovery (track disconnected state by listening for `reconnect` events)\n *  - builtin mutation event ordering (they might arrive out of order), lost events detection (/listen endpoint doesn't guarantee delivery) and recovery\n *  - discards already-applied mutation events received while fetching the initial document snapshot\n * @param options\n */\nexport function createDocumentEventListener(options: {\n  loadDocument: DocumentLoader\n  listenerEvents: Observable<\n    WelcomeEvent | ListenerMutationEvent | ReconnectEvent\n  >\n}) {\n  const {listenerEvents, loadDocument} = options\n\n  return function listen<Doc extends SanityDocumentBase>(documentId: string) {\n    return listenerEvents.pipe(\n      concatMap(event => {\n        if (event.type === 'mutation') {\n          return event.documentId === documentId ? of(event) : EMPTY\n        }\n\n        if (event.type === 'reconnect') {\n          return of(event)\n        }\n\n        if (event.type === 'welcome') {\n          return loadDocument(documentId).pipe(\n            catchError((err: unknown) => {\n              const error = toError(err)\n              if (isClientError(error)) {\n                return throwError(() => error)\n              }\n              return throwError(\n                () =>\n                  new FetchError(\n                    `An unexpected error occurred while fetching document: ${error?.message}`,\n                    {cause: error},\n                  ),\n              )\n            }),\n            map(result => {\n              if (result.accessible) {\n                return result.document as Doc\n              }\n              if (result.reason === 'permission') {\n                throw new PermissionDeniedError(\n                  `Permission denied. Make sure the current user (or token) has permission to read the document with ID=\"${documentId}\".`,\n                )\n              }\n              return undefined\n            }),\n            map(\n              (doc: undefined | Doc): ListenerSyncEvent<Doc> => ({\n                type: 'sync',\n                document: doc,\n              }),\n            ),\n          )\n        }\n        // ignore unknown events\n        return EMPTY\n      }),\n      sequentializeListenerEvents<Doc>({\n        maxBufferSize: 10,\n        resolveChainDeadline: 10_000,\n      }),\n    )\n  }\n}\n\nfunction toError(maybeErr: unknown) {\n  if (maybeErr instanceof Error) {\n    return maybeErr\n  }\n  if (typeof maybeErr === 'object' && maybeErr) {\n    return Object.assign(new Error(), maybeErr)\n  }\n  return new Error(String(maybeErr))\n}\n","import {\n  asyncScheduler,\n  BehaviorSubject,\n  bufferWhen,\n  concat,\n  defer,\n  EMPTY,\n  filter,\n  map,\n  merge,\n  mergeMap,\n  Observable,\n  of,\n  scheduled,\n  share,\n  Subject,\n  takeUntil,\n  takeWhile,\n} from 'rxjs'\n\ntype AnyKey = keyof any\n\nconst defaultDurationSelector = () => scheduled(of(0), asyncScheduler)\n\ntype Request<T> = {key: T; cancelled: boolean}\n\nexport function createDataLoader<T, KeyT extends AnyKey>(options: {\n  onLoad: (ids: KeyT[]) => Observable<T[]>\n  durationSelector?: () => Observable<unknown>\n}) {\n  const durationSelector = options.durationSelector || defaultDurationSelector\n\n  const requests$ = new BehaviorSubject<Request<KeyT> | undefined>(undefined)\n  const unsubscribes$ = new Subject<void>()\n\n  const batchResponses = requests$.pipe(\n    filter(req => !!req),\n    bufferWhen(durationSelector),\n    map(requests => requests.filter(request => !request.cancelled)),\n    filter(requests => requests.length > 0),\n    mergeMap(requests => {\n      const keys = requests.map(request => request.key)\n\n      const responses = options.onLoad(keys).pipe(\n        takeUntil(\n          unsubscribes$.pipe(\n            filter(() => requests.every(request => request.cancelled)),\n          ),\n        ),\n        mergeMap(batchResult => {\n          if (batchResult.length !== requests.length) {\n            throw new Error(\n              `The length of the returned batch must be equal to the number of batched requests. Requested a batch of length ${requests.length}, but received a batch of ${batchResult.length}.`,\n            )\n          }\n          return requests.map((request, i) => {\n            return {\n              type: 'value' as const,\n              request,\n              response: batchResult[i]!,\n            }\n          })\n        }),\n      )\n      // we need to signal to subscribers that the request batch has ended\n      const responseEnds = requests.map(request => ({\n        request,\n        type: 'complete' as const,\n      }))\n      return concat(responses, responseEnds)\n    }),\n    share(),\n  )\n\n  return (key: KeyT) => {\n    return new Observable<T>(subscriber => {\n      const mutableRequestState: Request<KeyT> = {key, cancelled: false}\n      const emit = defer(() => {\n        requests$.next(mutableRequestState)\n        return EMPTY\n      })\n      const subscription = merge(\n        batchResponses.pipe(\n          filter(batchResult => batchResult.request === mutableRequestState),\n          takeWhile(batchResult => batchResult.type !== 'complete'),\n          map(batchResult => batchResult.response),\n        ),\n        emit,\n      ).subscribe(subscriber)\n\n      return () => {\n        // note: will not be cancelled in-flight unless the whole batch is cancelled\n        mutableRequestState.cancelled = true\n        unsubscribes$.next()\n        subscription.unsubscribe()\n      }\n    })\n  }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {keyBy} from 'lodash'\nimport {map, type Observable} from 'rxjs'\n\nimport {type SanityDocumentBase} from '../../mutations/types'\nimport {createDataLoader} from '../utils/createDataLoader'\nimport {type DocumentResult} from './types'\n\nexport type FetchDocuments = (ids: string[]) => Observable<DocEndpointResponse>\n\nexport interface OmittedDocument {\n  id: string\n  reason: 'existence' | 'permission'\n}\nexport interface DocEndpointResponse {\n  documents: SanityDocumentBase[]\n  omitted: OmittedDocument[]\n}\n\n/**\n * Creates a \"dataloader\" style document loader that fetches from the /doc endpoint\n * @param {FetchDocuments} fetchDocuments - The client instance used for fetching documents.\n * @param options\n */\nexport function createDocumentLoader(\n  fetchDocuments: FetchDocuments,\n  options?: {durationSelector?: () => Observable<unknown>; tag?: string},\n) {\n  return createDataLoader({\n    onLoad: (ids: string[]) => fetchDedupedWith(fetchDocuments, ids),\n    durationSelector: options?.durationSelector,\n  })\n}\n\nexport function createDocumentLoaderFromClient(\n  client: SanityClient,\n  options?: {durationSelector?: () => Observable<unknown>; tag?: string},\n) {\n  const fetchDocument = (ids: string[]) => {\n    const requestOptions = {\n      uri: client.getDataUrl('doc', ids.join(',')),\n      json: true,\n      tag: options?.tag,\n    }\n\n    return client.observable.request<DocEndpointResponse>(requestOptions)\n  }\n\n  return createDocumentLoader(fetchDocument, options)\n}\n\n/**\n * Processes an array of document IDs:\n * 1. Extracts the set of unique IDs from the input array.\n * 2. Calls `fetchDocuments` with the unique IDs to retrieve their corresponding documents.\n * 3. Returns an array of documents, preserving the order and duplication of IDs in the input array.\n *\n * Example:\n * - Input: [a, a, b]\n * - `fetchDocuments` is called with ([a, b]), returning: [{_id: a}, {_id: b}]\n * - Output: [{_id: a}, {_id: a}, {_id: b}]\n *\n * @param {FetchDocuments} fetchDocuments - The client instance used for fetching documents.\n * @param {Array<string>} ids - An array of document IDs to process.\n * @returns {Observable<DocumentResult[]>} - An array of documents, mapped to the input IDs.\n */\nfunction fetchDedupedWith(fetchDocuments: FetchDocuments, ids: string[]) {\n  const unique = [...new Set(ids)]\n  return fetchDocuments(unique).pipe(\n    map(results => prepareResponse(ids, results)),\n    map(results => {\n      const byId = keyBy(results, result => result.id)\n      return ids.map(id => byId[id]!)\n    }),\n  )\n}\n\nfunction prepareResponse(\n  requestedIds: string[],\n  response: DocEndpointResponse,\n): DocumentResult[] {\n  const documents = keyBy(response.documents, entry => entry._id!)\n  const omitted = keyBy(response.omitted, entry => entry.id)\n  return requestedIds.map(id => {\n    if (documents[id]) {\n      return {id, accessible: true, document: documents[id]!}\n    }\n    const omittedEntry = omitted[id]\n    if (!omittedEntry) {\n      // in case the document is missing and there's no entry for it in `omitted`\n      // this should not normally happen, but if it does, handle it is as if the document doesn't exist\n      return {id, accessible: false, reason: 'existence'}\n    }\n    if (omittedEntry.reason === 'permission') {\n      return {\n        id,\n        accessible: false,\n        reason: 'permission',\n      }\n    }\n    // handle any unknown omitted reason as nonexistence too\n    return {\n      id,\n      accessible: false,\n      reason: 'existence',\n    }\n  })\n}\n","import {filter, type Observable} from 'rxjs'\nimport {scan} from 'rxjs/operators'\n\nimport {decodeAll} from '../../encoders/sanity'\nimport {type SanityDocumentBase} from '../../mutations/types'\nimport {applyAll} from '../documentMap/applyDocumentMutation'\nimport {applyMutationEventEffects} from '../documentMap/applyMendoza'\nimport {\n  type ListenerEvent,\n  type ListenerMutationEvent,\n  type ListenerReconnectEvent,\n  type ListenerSyncEvent,\n} from '../types'\nimport {hasProperty} from '../utils/isEffectEvent'\n\nexport interface DocumentSyncUpdate<Doc extends SanityDocumentBase> {\n  documentId: string\n  snapshot: Doc | undefined\n  event: ListenerSyncEvent<Doc>\n}\nexport interface DocumentMutationUpdate<Doc extends SanityDocumentBase> {\n  documentId: string\n  snapshot: Doc | undefined\n  event: ListenerMutationEvent\n}\n\nexport interface DocumentReconnectUpdate<Doc extends SanityDocumentBase> {\n  documentId: string\n  snapshot: Doc | undefined\n  event: ListenerReconnectEvent\n}\n\nexport type DocumentUpdate<Doc extends SanityDocumentBase> =\n  | DocumentSyncUpdate<Doc>\n  | DocumentMutationUpdate<Doc>\n  | DocumentReconnectUpdate<any>\n\nexport type DocumentUpdateListener<Doc extends SanityDocumentBase> = (\n  id: string,\n) => Observable<DocumentUpdate<Doc>>\n\n/**\n * Creates a function that can be used to listen for document updates\n * Emits the latest snapshot of the document along with the latest event\n * @param options\n */\nexport function createDocumentUpdateListener(options: {\n  listenDocumentEvents: (documentId: string) => Observable<ListenerEvent>\n}) {\n  const {listenDocumentEvents} = options\n\n  return function listen<Doc extends SanityDocumentBase>(documentId: string) {\n    return listenDocumentEvents(documentId).pipe(\n      scan(\n        (\n          prev: DocumentUpdate<Doc> | undefined,\n          event: ListenerEvent,\n        ): DocumentUpdate<Doc> => {\n          if (event.type === 'sync') {\n            return {\n              event,\n              documentId,\n              snapshot: event.document,\n            } as DocumentUpdate<Doc>\n          }\n          if (event.type === 'mutation') {\n            if (prev?.event === undefined) {\n              throw new Error(\n                'Received a mutation event before sync event. Something is wrong',\n              )\n            }\n            if (hasProperty(event, 'effects')) {\n              return {\n                event,\n                documentId,\n                snapshot: applyMutationEventEffects(\n                  prev.snapshot,\n                  event,\n                ) as Doc,\n              }\n            }\n            if (hasProperty(event, 'mutations')) {\n              return {\n                event,\n                documentId,\n                snapshot: applyAll(\n                  prev.snapshot,\n                  decodeAll(event.mutations),\n                ) as Doc,\n              }\n            }\n            throw new Error(\n              'No effects found on listener event. The listener must be set up to use effectFormat=mendoza.',\n            )\n          }\n          return {documentId, snapshot: prev?.snapshot, event}\n        },\n        undefined,\n      ),\n      // ignore seed value\n      filter(update => update !== undefined),\n    )\n  }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {sortedIndex} from 'lodash'\nimport {type Observable, of} from 'rxjs'\nimport {filter, map, mergeMap, scan} from 'rxjs/operators'\n\nimport {type ListenerEndpointEvent, type QueryParams} from '../types'\n\nexport type DocumentIdSetState = {\n  status: 'connecting' | 'reconnecting' | 'connected'\n  event: DocumentIdSetEvent | InitialEvent\n  snapshot: string[]\n}\n\nexport type InitialEvent = {type: 'connect'}\n\nexport type InsertMethod = 'sorted' | 'prepend' | 'append'\n\nexport type DocumentIdSetEvent =\n  | {type: 'sync'; documentIds: string[]}\n  | {type: 'reconnect'}\n  | {\n      type: 'op'\n      op: 'add' | 'remove'\n      documentId: string\n    }\n\nconst INITIAL_STATE: DocumentIdSetState = {\n  status: 'connecting',\n  event: {type: 'connect'},\n  snapshot: [],\n}\n\nexport type FetchDocumentIdsFn = (\n  query: string,\n  params?: QueryParams,\n  options?: {tag?: string},\n) => Observable<string[]>\n\nexport type IdSetListenFn = (\n  query: string,\n  params?: QueryParams,\n  options?: {\n    visibility: 'transaction'\n    events: ['welcome', 'mutation', 'reconnect']\n    includeResult: false\n    includeMutations: false\n    tag?: string\n  },\n) => Observable<ListenerEndpointEvent>\n\nexport function createIdSetListener(\n  listen: IdSetListenFn,\n  fetch: FetchDocumentIdsFn,\n) {\n  return function listenIdSet(\n    queryFilter: string,\n    params: QueryParams,\n    options: {tag?: string} = {},\n  ) {\n    const {tag} = options\n\n    const query = `*[${queryFilter}]._id`\n    function fetchFilter() {\n      return fetch(query, params, {\n        tag: tag ? tag + '.fetch' : undefined,\n      }).pipe(\n        map((result): string[] => {\n          if (!Array.isArray(result)) {\n            throw new Error(\n              `Expected query to return array of documents, but got ${typeof result}`,\n            )\n          }\n          return result as string[]\n        }),\n      )\n    }\n    return listen(query, params, {\n      visibility: 'transaction',\n      events: ['welcome', 'mutation', 'reconnect'],\n      includeResult: false,\n      includeMutations: false,\n      tag: tag ? tag + '.listen' : undefined,\n    }).pipe(\n      mergeMap(event => {\n        return event.type === 'welcome'\n          ? fetchFilter().pipe(map(result => ({type: 'sync' as const, result})))\n          : of(event)\n      }),\n      map((event): DocumentIdSetEvent | undefined => {\n        if (event.type === 'mutation') {\n          if (event.transition === 'update') {\n            // ignore updates, as we're only interested in documents appearing and disappearing from the set\n            return undefined\n          }\n          if (event.transition === 'appear') {\n            return {\n              type: 'op',\n              op: 'add',\n              documentId: event.documentId,\n            }\n          }\n          if (event.transition === 'disappear') {\n            return {\n              type: 'op',\n              op: 'remove',\n              documentId: event.documentId,\n            }\n          }\n          return undefined\n        }\n        if (event.type === 'sync') {\n          return {type: 'sync', documentIds: event.result}\n        }\n        if (event.type === 'reconnect') {\n          return {type: 'reconnect' as const}\n        }\n        return undefined\n      }),\n      // ignore undefined\n      filter(ev => !!ev),\n    )\n  }\n}\nexport function createIdSetListenerFromClient(client: SanityClient) {}\n\n/** Converts a stream of id set listener events into a state containing the list of document ids */\nexport function toState(options: {insert?: InsertMethod} = {}) {\n  const {insert: insertOption = 'sorted'} = options\n  return (input$: Observable<DocumentIdSetEvent>) =>\n    input$.pipe(\n      scan((state: DocumentIdSetState, event): DocumentIdSetState => {\n        if (event.type === 'reconnect') {\n          return {\n            ...state,\n            event,\n            status: 'reconnecting',\n          }\n        }\n        if (event.type === 'sync') {\n          return {\n            ...state,\n            event,\n            status: 'connected',\n          }\n        }\n        if (event.type === 'op') {\n          if (event.op === 'add') {\n            return {\n              event,\n              status: 'connected',\n              snapshot: insert(state.snapshot, event.documentId, insertOption),\n            }\n          }\n          if (event.op === 'remove') {\n            return {\n              event,\n              status: 'connected',\n              snapshot: state.snapshot.filter(id => id !== event.documentId),\n            }\n          }\n          throw new Error(`Unexpected operation: ${event.op}`)\n        }\n        return state\n      }, INITIAL_STATE),\n    )\n}\n\nfunction insert<T>(array: T[], element: T, strategy: InsertMethod): T[] {\n  let index: number\n  if (strategy === 'prepend') {\n    index = 0\n  } else if (strategy === 'append') {\n    index = array.length\n  } else {\n    index = sortedIndex(array, element) as number\n  }\n\n  return array.toSpliced(index, 0, element)\n}\n","import {\n  finalize,\n  merge,\n  type MonoTypeOperatorFunction,\n  Observable,\n  share,\n  type ShareConfig,\n  tap,\n} from 'rxjs'\n\nexport type ShareReplayLatestConfig<T> = ShareConfig<T> & {\n  predicate: (value: T) => boolean\n}\n\n/**\n * A variant of share that takes a predicate function to determine which value to replay to new subscribers\n * @param predicate - Predicate function to determine which value to replay\n */\nexport function shareReplayLatest<T>(\n  predicate: (value: T) => boolean,\n): MonoTypeOperatorFunction<T>\n\n/**\n * A variant of share that takes a predicate function to determine which value to replay to new subscribers\n * @param config - ShareConfig with additional predicate function\n */\nexport function shareReplayLatest<T>(\n  config: ShareReplayLatestConfig<T>,\n): MonoTypeOperatorFunction<T>\n\n/**\n * A variant of share that takes a predicate function to determine which value to replay to new subscribers\n * @param configOrPredicate - Predicate function to determine which value to replay\n * @param config - Optional ShareConfig\n */\nexport function shareReplayLatest<T>(\n  configOrPredicate:\n    | ShareReplayLatestConfig<T>\n    | ShareReplayLatestConfig<T>['predicate'],\n  config?: ShareConfig<T>,\n) {\n  return _shareReplayLatest(\n    typeof configOrPredicate === 'function'\n      ? {predicate: configOrPredicate, ...config}\n      : configOrPredicate,\n  )\n}\nfunction _shareReplayLatest<T>(\n  config: ShareReplayLatestConfig<T>,\n): MonoTypeOperatorFunction<T> {\n  return (source: Observable<T>) => {\n    let latest: T | undefined\n    let emitted = false\n\n    const {predicate, ...shareConfig} = config\n\n    const wrapped = source.pipe(\n      tap(value => {\n        if (config.predicate(value)) {\n          emitted = true\n          latest = value\n        }\n      }),\n      finalize(() => {\n        emitted = false\n        latest = undefined\n      }),\n      share(shareConfig),\n    )\n    const emitLatest = new Observable<T>(subscriber => {\n      if (emitted) {\n        subscriber.next(latest as T) // this type cast is safe because of the `emitted`-guard\n      }\n      subscriber.complete()\n    })\n    return merge(wrapped, emitLatest)\n  }\n}\n","import {map, type Observable} from 'rxjs'\n\nimport {\n  type ListenerEndpointEvent,\n  type ListenerMutationEvent,\n} from '../../types'\nimport {ChannelError, DisconnectError} from '../errors'\n/**\n * Takes a stream of /listen events and turn them into errors in case of disconnect or channelError\n */\nexport function withListenErrors() {\n  return (input$: Observable<ListenerEndpointEvent>) =>\n    input$.pipe(\n      map(event => {\n        if (event.type === 'mutation') {\n          return event as ListenerMutationEvent\n        }\n        if (event.type === 'disconnect') {\n          throw new DisconnectError(`DisconnectError: ${event.reason}`)\n        }\n        if (event.type === 'channelError') {\n          throw new ChannelError(`ChannelError: ${event.message}`)\n        }\n        // pass on welcome and reconnect events\n        // note: reconnect is special and should not be subject to error path + retry because that will reinstantiate the eventsource instance\n        return event\n      }),\n    )\n}\n","import {\n  type ReconnectEvent,\n  type SanityClient,\n  type WelcomeEvent,\n} from '@sanity/client'\nimport {type Observable, timer} from 'rxjs'\n\nimport {\n  type ListenerEndpointEvent,\n  type ListenerMutationEvent,\n  type QueryParams,\n} from '../types'\nimport {shareReplayLatest} from './utils/shareReplayLatest'\nimport {withListenErrors} from './utils/withListenErrors'\n\nexport interface ListenerOptions {\n  /**\n   * Provide a custom filter to the listener. By default, this listener will include all events\n   * Note: make sure the filter includes events from documents you will subscribe to.\n   */\n  filter?: string\n  /**\n   * Whether to include system documents or not\n   * This will be ignored if a custom filter is provided\n   */\n  includeSystemDocuments?: boolean\n  /**\n   * How long after the last subscriber is unsubscribed to keep the connection open\n   */\n  shutdownDelay?: number\n  /**\n   * Include mutations in listener events\n   */\n  includeMutations?: boolean\n\n  /**\n   * Request tag\n   */\n  tag?: string\n}\n\nexport type SharedListenerListenFn = (\n  query: string,\n  queryParams: QueryParams,\n  options: RequestOptions,\n) => Observable<ListenerEndpointEvent>\n\n/**\n * These are fixed, and it's up to the implementation of the listen function to turn them into request parameters\n */\nexport interface RequestOptions {\n  events: ['welcome', 'mutation', 'reconnect']\n  includeResult: false\n  includePreviousRevision: false\n  visibility: 'transaction'\n  effectFormat: 'mendoza'\n  includeMutations?: boolean\n  tag?: string\n}\n\n/**\n * Creates a (low level) shared listener that will emit 'welcome' for all new subscribers immediately, and thereafter emit every listener event, including welcome, mutation, and reconnects\n * Requires a Sanity client instance\n */\nexport function createSharedListenerFromClient(\n  client: SanityClient,\n  options?: ListenerOptions,\n): Observable<WelcomeEvent | ListenerMutationEvent | ReconnectEvent> {\n  const listener = (\n    query: string,\n    queryParams: QueryParams,\n    request: RequestOptions,\n  ) => {\n    return client.listen(\n      query,\n      queryParams,\n      request,\n    ) as Observable<ListenerEndpointEvent>\n  }\n\n  return createSharedListener(listener, options)\n}\n\n/**\n * Creates a (low level) shared listener that will emit 'welcome' for all new subscribers immediately, and thereafter emit every listener event, including welcome, mutation, and reconnects\n * Useful for cases where you need control of how the listen request is set up\n */\nexport function createSharedListener(\n  listen: SharedListenerListenFn,\n  options: ListenerOptions = {},\n): Observable<WelcomeEvent | ListenerMutationEvent | ReconnectEvent> {\n  const {filter, tag, shutdownDelay, includeSystemDocuments, includeMutations} =\n    options\n\n  const query = filter\n    ? `*[${filter}]`\n    : includeSystemDocuments\n      ? '*[!(_id in path(\"_.**\"))]'\n      : '*'\n\n  return listen(\n    query,\n    {},\n    {\n      events: ['welcome', 'mutation', 'reconnect'],\n      includeResult: false,\n      includePreviousRevision: false,\n      visibility: 'transaction',\n      effectFormat: 'mendoza',\n      ...(includeMutations ? {} : {includeMutations: false}),\n      tag,\n    },\n  ).pipe(\n    shareReplayLatest({\n      // note: resetOnError and resetOnComplete are both default true\n      resetOnError: true,\n      resetOnComplete: true,\n      predicate: event =>\n        event.type === 'welcome' || event.type === 'reconnect',\n      resetOnRefCountZero:\n        typeof shutdownDelay === 'number' ? () => timer(shutdownDelay) : true,\n    }),\n    withListenErrors(),\n  )\n}\n","import {partition} from 'lodash'\nimport {concat, filter, merge, NEVER, type Observable, of, Subject} from 'rxjs'\nimport {map} from 'rxjs/operators'\n\nimport {encodeAll} from '../../encoders/sanity'\nimport {type Transaction} from '../../mutations/types'\nimport {applyMutations} from '../documentMap/applyMutations'\nimport {createDocumentMap} from '../documentMap/createDocumentMap'\nimport {type DocEndpointResponse} from '../listeners/createDocumentLoader'\nimport {\n  type ListenerEndpointEvent,\n  type ListenerWelcomeEvent,\n  type SubmitResult,\n} from '../types'\nimport {createTransactionId} from '../utils/createTransactionId'\n\nfunction createWelcomeEvent(): ListenerWelcomeEvent {\n  return {\n    type: 'welcome',\n    listenerName: 'mock' + Math.random().toString(32).substring(2),\n  }\n}\n\n/**\n * This is the interface that a mock backend instance needs to implement\n */\nexport interface MockBackendAPI {\n  listen(query: string): Observable<ListenerEndpointEvent>\n  getDocuments(ids: string[]): Observable<DocEndpointResponse>\n  submit(transaction: Transaction): Observable<SubmitResult>\n}\nexport function createMockBackendAPI(): MockBackendAPI {\n  const documentMap = createDocumentMap()\n  const listenerEvents = new Subject<ListenerEndpointEvent>()\n  return {\n    listen: (query: string) => {\n      return concat(\n        of(createWelcomeEvent()),\n        merge(NEVER, listenerEvents).pipe(\n          filter(m => m.type === 'mutation'),\n          map(ev => structuredClone(ev)),\n        ),\n      )\n    },\n    getDocuments(ids: string[]): Observable<DocEndpointResponse> {\n      const docs = ids.map(id => ({id, document: documentMap.get(id)}))\n      const [existing, omitted] = partition(docs, entry => entry.document)\n      return of(\n        structuredClone({\n          documents: existing.map(entry => entry.document!),\n          omitted: omitted.map(entry => ({id: entry.id, reason: 'existence'})),\n        } satisfies DocEndpointResponse),\n      )\n    },\n    submit: (_transaction: Transaction) => {\n      const transaction = structuredClone(_transaction)\n      const result = applyMutations(\n        transaction.mutations,\n        documentMap,\n        transaction.id as never,\n      )\n\n      result.forEach(res => {\n        listenerEvents.next({\n          type: 'mutation',\n          documentId: res.id,\n          mutations: encodeAll(res.mutations),\n          transactionId: transaction.id || createTransactionId(),\n          previousRev: res.before?._rev,\n          resultRev: res.after?._rev,\n          transition:\n            res.after === undefined\n              ? 'disappear'\n              : res.before === undefined\n                ? 'appear'\n                : 'update',\n        })\n      })\n      return of({} satisfies SubmitResult)\n    },\n  }\n}\n","import {type SanityClient} from '@sanity/client'\nimport {from} from 'rxjs'\n\nimport {encodeTransaction} from '../../../encoders/sanity'\nimport {type Transaction} from '../../../mutations/types'\nimport {createDocumentEventListener} from '../../listeners/createDocumentEventListener'\nimport {createDocumentLoaderFromClient} from '../../listeners/createDocumentLoader'\nimport {createSharedListenerFromClient} from '../../listeners/createSharedListener'\nimport {type OptimisticStoreBackend} from '../createOptimisticStore'\n\nexport function createOptimisticStoreClientBackend(\n  client: SanityClient,\n): OptimisticStoreBackend {\n  const listenDocument = createDocumentEventListener({\n    loadDocument: createDocumentLoaderFromClient(client),\n    listenerEvents: createSharedListenerFromClient(client),\n  })\n  return {\n    listen: listenDocument,\n    submit: (transaction: Transaction) =>\n      from(\n        client.dataRequest('mutate', encodeTransaction(transaction), {\n          visibility: 'async',\n          returnDocuments: false,\n        }),\n      ),\n  }\n}\n","import {createDocumentEventListener} from '../../listeners/createDocumentEventListener'\nimport {createDocumentLoader} from '../../listeners/createDocumentLoader'\nimport {createSharedListener} from '../../listeners/createSharedListener'\nimport {type MockBackendAPI} from '../../mock/createMockBackendAPI'\nimport {type OptimisticStoreBackend} from '../createOptimisticStore'\n\nexport function createOptimisticStoreMockBackend(\n  backendAPI: MockBackendAPI,\n): OptimisticStoreBackend {\n  const sharedListener = createSharedListener((query: string, options) =>\n    backendAPI.listen(query),\n  )\n  const loadDocument = createDocumentLoader(ids => backendAPI.getDocuments(ids))\n  const listenDocument = createDocumentEventListener({\n    loadDocument,\n    listenerEvents: sharedListener,\n  })\n  return {listen: listenDocument, submit: backendAPI.submit}\n}\n"],"names":["finalize","share","timer","ReplaySubject","combineLatest","lodashPartition","scan","switchMap","concat","of","mergeMap","throwError","concatMap","EMPTY","catchError","map","scheduled","asyncScheduler","BehaviorSubject","Subject","filter","bufferWhen","takeUntil","Observable","defer","merge","takeWhile","keyBy","hasProperty","applyMutationEventEffects","applyAll","decodeAll","sortedIndex","tap","createDocumentMap","NEVER","partition","applyMutations","encodeAll","createTransactionId","from","encodeTransaction"],"mappings":"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"}