{"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/documentMap/applyDocumentMutation.ts","../src/store/documentMap/applyMendoza.ts","../src/store/utils/isEffectEvent.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/utils/getMutationDocumentId.ts","../src/store/documentMap/applyMutations.ts","../src/store/documentMap/createDocumentMap.ts","../src/store/utils/createTransactionId.ts","../src/store/mock/createMockBackendAPI.ts","../src/store/optimistic/backend/createOptimisticStoreClientBackend.ts","../src/store/optimistic/backend/createOptimisticStoreMockBackend.ts","../src/store/documentMap/commit.ts","../src/store/utils/createReplayMemoizer.ts","../src/store/utils/filterMutationGroups.ts","../src/store/utils/arrayUtils.ts","../src/store/optimistic/optimizations/squashNodePatches.ts","../src/store/optimistic/optimizations/squashDMPStrings.ts","../src/store/utils/mergeMutationGroups.ts","../src/store/optimistic/optimizations/squashMutations.ts","../src/store/optimistic/rebase.ts","../src/store/optimistic/createOptimisticStore.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          requests.map((request, i) => ({\n            type: 'value' as const,\n            request,\n            response: batchResult[i],\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 {nanoid} from 'nanoid'\n\nimport {applyPatchMutation, assignId, hasId} from '../../apply'\nimport {\n  type CreateIfNotExistsMutation,\n  type CreateMutation,\n  type CreateOrReplaceMutation,\n  type DeleteMutation,\n  type Mutation,\n  type PatchMutation,\n  type SanityDocumentBase,\n} from '../../mutations/types'\n\nexport type MutationResult<Doc extends SanityDocumentBase> =\n  | {\n      id: string\n      status: 'created'\n      after: Doc\n    }\n  | {\n      id: string\n      status: 'updated'\n      before: Doc\n      after: Doc\n    }\n  | {\n      id: string\n      status: 'deleted'\n      before: Doc | undefined\n      after: undefined\n    }\n  | {\n      status: 'error'\n      message: string\n    }\n  | {\n      status: 'noop'\n    }\n\n/**\n * Applies a set of mutations to the provided document\n * @param current\n * @param mutation\n */\nexport function applyAll<Doc extends SanityDocumentBase>(\n  current: Doc | undefined,\n  mutation: Mutation<Doc>[],\n): Doc | undefined {\n  return mutation.reduce((doc, m) => {\n    const res = applyDocumentMutation(doc, m)\n    if (res.status === 'error') {\n      throw new Error(res.message)\n    }\n    return res.status === 'noop' ? doc : res.after\n  }, current)\n}\n\n/**\n * Applies a mutation to the provided document\n * @param document\n * @param mutation\n */\nexport function applyDocumentMutation<Doc extends SanityDocumentBase>(\n  document: Doc | undefined,\n  mutation: Mutation<Doc>,\n): MutationResult<Doc> {\n  if (mutation.type === 'create') {\n    return create(document, mutation)\n  }\n  if (mutation.type === 'createIfNotExists') {\n    return createIfNotExists(document, mutation)\n  }\n  if (mutation.type === 'delete') {\n    return del(document, mutation)\n  }\n  if (mutation.type === 'createOrReplace') {\n    return createOrReplace(document, mutation)\n  }\n  if (mutation.type === 'patch') {\n    return patch(document, mutation)\n  }\n  // @ts-expect-error all cases should be covered\n  throw new Error(`Invalid mutation type: ${mutation.type}`)\n}\n\nfunction create<Doc extends SanityDocumentBase>(\n  document: Doc | undefined,\n  mutation: CreateMutation<Doc>,\n): MutationResult<Doc> {\n  if (document) {\n    return {status: 'error', message: 'Document already exist'}\n  }\n  const result = assignId(mutation.document, nanoid)\n  return {status: 'created', id: result._id, after: result}\n}\n\nfunction createIfNotExists<Doc extends SanityDocumentBase>(\n  document: Doc | undefined,\n  mutation: CreateIfNotExistsMutation<Doc>,\n): MutationResult<Doc> {\n  if (!hasId(mutation.document)) {\n    return {\n      status: 'error',\n      message: 'Cannot createIfNotExists on document without _id',\n    }\n  }\n  return document\n    ? {status: 'noop'}\n    : {status: 'created', id: mutation.document._id, after: mutation.document}\n}\n\nfunction createOrReplace<Doc extends SanityDocumentBase>(\n  document: Doc | undefined,\n  mutation: CreateOrReplaceMutation<Doc>,\n): MutationResult<Doc> {\n  if (!hasId(mutation.document)) {\n    return {\n      status: 'error',\n      message: 'Cannot createIfNotExists on document without _id',\n    }\n  }\n\n  return document\n    ? {\n        status: 'updated',\n        id: mutation.document._id,\n        before: document,\n        after: mutation.document,\n      }\n    : {status: 'created', id: mutation.document._id, after: mutation.document}\n}\n\nfunction del<Doc extends SanityDocumentBase>(\n  document: Doc | undefined,\n  mutation: DeleteMutation,\n): MutationResult<Doc> {\n  if (!document) {\n    return {status: 'noop'}\n  }\n  if (mutation.id !== document._id) {\n    return {status: 'error', message: 'Delete mutation targeted wrong document'}\n  }\n  return {\n    status: 'deleted',\n    id: mutation.id,\n    before: document,\n    after: undefined,\n  }\n}\n\nfunction patch<Doc extends SanityDocumentBase>(\n  document: Doc | undefined,\n  mutation: PatchMutation,\n): MutationResult<Doc> {\n  if (!document) {\n    return {\n      status: 'error',\n      message: 'Cannot apply patch on nonexistent document',\n    }\n  }\n  const next = applyPatchMutation(mutation, document)\n  return document === next\n    ? {status: 'noop'}\n    : {status: 'updated', id: mutation.id, before: document, after: next}\n}\n","import {applyPatch, type RawPatch} from 'mendoza'\n\nimport {type SanityDocumentBase} from '../../mutations/types'\n\nfunction omitRev(document: SanityDocumentBase | undefined) {\n  if (document === undefined) {\n    return undefined\n  }\n  const {_rev, ...doc} = document\n  return doc\n}\n\nexport function applyMendozaPatch(\n  document: SanityDocumentBase | undefined,\n  patch: RawPatch,\n  patchBaseRev?: string,\n): SanityDocumentBase | undefined {\n  if (patchBaseRev !== document?._rev) {\n    throw new Error(\n      'Invalid document revision. The provided patch is calculated from a different revision than the current document',\n    )\n  }\n  const next = applyPatch(omitRev(document), patch)\n  return next === null ? undefined : next\n}\n\nexport function applyMutationEventEffects(\n  document: SanityDocumentBase | undefined,\n  event: {effects: {apply: RawPatch}; previousRev?: string; resultRev?: string},\n) {\n  if (!event.effects) {\n    throw new Error(\n      'Mutation event is missing effects. Is the listener set up with effectFormat=mendoza?',\n    )\n  }\n  const next = applyMendozaPatch(\n    document,\n    event.effects.apply,\n    event.previousRev,\n  )\n  // next will be undefined in case of deletion\n  return next ? {...next, _rev: event.resultRev} : undefined\n}\n","export function hasProperty<T, P extends keyof T>(\n  value: T,\n  property: P,\n): value is T & Required<Pick<T, P>> {\n  const val = value[property]\n  return typeof val !== 'undefined' && val !== null\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)\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","type MutationLike =\n  | {type: 'patch'; id: string}\n  | {type: 'create'; document: {_id: string}}\n  | {type: 'delete'; id: string}\n  | {type: 'createIfNotExists'; document: {_id: string}}\n  | {type: 'createOrReplace'; document: {_id: string}}\n\nexport function getMutationDocumentId(mutation: MutationLike): string {\n  if (mutation.type === 'patch') {\n    return mutation.id\n  }\n  if (mutation.type === 'create') {\n    return mutation.document._id\n  }\n  if (mutation.type === 'delete') {\n    return mutation.id\n  }\n  if (mutation.type === 'createIfNotExists') {\n    return mutation.document._id\n  }\n  if (mutation.type === 'createOrReplace') {\n    return mutation.document._id\n  }\n  throw new Error('Invalid mutation type')\n}\n","import {type Mutation, type SanityDocumentBase} from '../../mutations/types'\nimport {type DocumentMap} from '../types'\nimport {getMutationDocumentId} from '../utils/getMutationDocumentId'\nimport {applyDocumentMutation} from './applyDocumentMutation'\n\nexport interface UpdateResult<T extends SanityDocumentBase> {\n  id: string\n  status: 'created' | 'updated' | 'deleted'\n  before?: T\n  after?: T\n  mutations: Mutation[]\n}\n\n/**\n * Takes a list of mutations and applies them to documents in a documentMap\n */\nexport function applyMutations<T extends SanityDocumentBase>(\n  mutations: Mutation[],\n  documentMap: DocumentMap<T>,\n  /**\n   * note: should never be set client side – only for test purposes\n   */\n  transactionId?: never,\n): UpdateResult<T>[] {\n  const updatedDocs: Record<\n    string,\n    {\n      before: T | undefined\n      after: T | undefined\n      mutations: Mutation[]\n    }\n  > = Object.create(null)\n\n  for (const mutation of mutations) {\n    const documentId = getMutationDocumentId(mutation)\n    if (!documentId) {\n      throw new Error('Unable to get document id from mutation')\n    }\n\n    const before = updatedDocs[documentId]?.after || documentMap.get(documentId)\n    const res = applyDocumentMutation(before, mutation)\n    if (res.status === 'error') {\n      throw new Error(res.message)\n    }\n\n    let entry = updatedDocs[documentId]\n    if (!entry) {\n      entry = {before, after: before, mutations: []}\n      updatedDocs[documentId] = entry\n    }\n\n    // Note: transactionId should never be set client side. Only for test purposes\n    // if a transaction id is passed, set it as a new _rev\n    const after = transactionId\n      ? {...(res.status === 'noop' ? before : res.after), _rev: transactionId}\n      : res.status === 'noop'\n        ? before\n        : res.after\n\n    documentMap.set(documentId, after)\n    entry.after = after\n    entry.mutations.push(mutation)\n  }\n\n  return Object.entries(updatedDocs).map(\n    ([id, {before, after, mutations: muts}]) => {\n      return {\n        id,\n        status: after ? (before ? 'updated' : 'created') : 'deleted',\n        mutations: muts,\n        before,\n        after,\n      }\n    },\n  )\n}\n","import {type SanityDocumentBase} from '../../mutations/types'\n\n/**\n * Minimalistic dataset implementation that only supports what's strictly necessary\n */\nexport function createDocumentMap() {\n  const documents = new Map<string, SanityDocumentBase | undefined>()\n  return {\n    set: (id: string, doc: SanityDocumentBase | undefined) =>\n      void documents.set(id, doc),\n    get: (id: string) => documents.get(id),\n    delete: (id: string) => documents.delete(id),\n  }\n}\n","import {uuid} from '@sanity/uuid'\n\nexport function createTransactionId() {\n  return uuid()\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","import {type SanityDocumentBase} from '../../mutations/types'\nimport {type DocumentMap} from '../types'\nimport {type UpdateResult} from './applyMutations'\n\nexport function commit<Doc extends SanityDocumentBase>(\n  results: UpdateResult<Doc>[],\n  documentMap: DocumentMap<Doc>,\n) {\n  results.forEach(result => {\n    if (result.status === 'created' || result.status === 'updated') {\n      documentMap.set(result.id, result.after)\n    }\n    if (result.status === 'deleted') {\n      documentMap.delete(result.id)\n    }\n  })\n}\n","import {finalize, type Observable, ReplaySubject, share, timer} from 'rxjs'\n\nexport function createReplayMemoizer(expiry: number) {\n  const memo: {[key: string]: Observable<any>} = Object.create(null)\n  return function memoize<T>(\n    key: string,\n    observable: Observable<T>,\n  ): Observable<T> {\n    if (!(key in memo)) {\n      memo[key] = observable.pipe(\n        finalize(() => {\n          delete memo[key]\n        }),\n        share({\n          connector: () => new ReplaySubject(1),\n          resetOnRefCountZero: () => timer(expiry),\n        }),\n      )\n    }\n    return memo[key]!\n  }\n}\n","import {type Mutation} from '../../mutations/types'\nimport {type MutationGroup} from '../types'\nimport {getMutationDocumentId} from './getMutationDocumentId'\n\nexport function filterMutationGroupsById(\n  mutationGroups: MutationGroup[],\n  id: string,\n): Mutation[] {\n  return mutationGroups.flatMap(mutationGroup =>\n    mutationGroup.mutations.flatMap(mut =>\n      getMutationDocumentId(mut) === id ? [mut] : [],\n    ),\n  )\n}\n","export function takeUntil<T>(\n  arr: T[],\n  predicate: (item: T) => boolean,\n  opts?: {inclusive: boolean},\n) {\n  const result = []\n  for (const item of arr) {\n    if (predicate(item)) {\n      if (opts?.inclusive) {\n        result.push(item)\n      }\n      return result\n    }\n    result.push(item)\n  }\n  return result\n}\n\nexport function takeUntilRight<T>(\n  arr: T[],\n  predicate: (item: T) => boolean,\n  opts?: {inclusive: boolean},\n) {\n  const result = []\n  for (const item of arr.slice().reverse()) {\n    if (predicate(item)) {\n      if (opts?.inclusive) {\n        result.push(item)\n      }\n      return result\n    }\n    result.push(item)\n  }\n  return result.reverse()\n}\n","import {makePatches, stringifyPatches} from '@sanity/diff-match-patch'\n\nimport {applyNodePatch} from '../../../apply'\nimport {type Operation} from '../../../mutations/operations/types'\nimport {type NodePatch, type SanityDocumentBase} from '../../../mutations/types'\nimport {getAtPath, type Path, startsWith, stringify} from '../../../path'\nimport {takeUntilRight} from '../../utils/arrayUtils'\n\nfunction isEqualPath(p1: Path, p2: Path) {\n  return stringify(p1) === stringify(p2)\n}\n\nfunction supersedes(later: Operation, earlier: Operation) {\n  return (\n    (earlier.type === 'set' || earlier.type === 'unset') &&\n    (later.type === 'set' || later.type === 'unset')\n  )\n}\n\nexport function squashNodePatches(patches: NodePatch[]) {\n  return compactSetIfMissingPatches(\n    compactSetPatches(compactUnsetPatches(patches)),\n  )\n}\n\nexport function compactUnsetPatches(patches: NodePatch[]) {\n  return patches.reduce(\n    (earlierPatches: NodePatch[], laterPatch: NodePatch) => {\n      if (laterPatch.op.type !== 'unset') {\n        earlierPatches.push(laterPatch)\n        return earlierPatches\n      }\n      // find all preceding patches that are affected by this unset\n      const unaffected = earlierPatches.filter(\n        earlierPatch => !startsWith(laterPatch.path, earlierPatch.path),\n      )\n      unaffected.push(laterPatch)\n      return unaffected\n    },\n    [],\n  )\n}\n\nexport function compactSetPatches(patches: NodePatch[]) {\n  return patches.reduceRight(\n    (laterPatches: NodePatch[], earlierPatch: NodePatch) => {\n      const replacement = laterPatches.find(\n        later =>\n          supersedes(later.op, earlierPatch.op) &&\n          isEqualPath(later.path, earlierPatch.path),\n      )\n      if (replacement) {\n        // we already have another patch later in the chain that replaces this one\n        return laterPatches\n      }\n      laterPatches.unshift(earlierPatch)\n      return laterPatches\n    },\n    [],\n  )\n}\n\nexport function compactSetIfMissingPatches(patches: NodePatch[]) {\n  return patches.reduce(\n    (previousPatches: NodePatch[], laterPatch: NodePatch) => {\n      if (laterPatch.op.type !== 'setIfMissing') {\n        previousPatches.push(laterPatch)\n        return previousPatches\n      }\n      // look at preceding patches up until the first unset\n      const check = takeUntilRight(\n        previousPatches,\n        patch => patch.op.type === 'unset',\n      )\n      const precedent = check.find(\n        precedingPatch =>\n          precedingPatch.op.type === 'setIfMissing' &&\n          isEqualPath(precedingPatch.path, laterPatch.path),\n      )\n      if (precedent) {\n        // we already have an identical patch earlier in the chain that voids this one\n        return previousPatches\n      }\n      previousPatches.push(laterPatch)\n      return previousPatches\n    },\n    [],\n  )\n}\n\nexport function compactDMPSetPatches(\n  base: SanityDocumentBase,\n  patches: NodePatch[],\n) {\n  let edge = base\n  return patches.reduce(\n    (earlierPatches: NodePatch[], laterPatch: NodePatch) => {\n      const before = edge\n      edge = applyNodePatch(laterPatch, edge)\n      if (\n        laterPatch.op.type === 'set' &&\n        typeof laterPatch.op.value === 'string'\n      ) {\n        const current = getAtPath(laterPatch.path, before)\n        if (typeof current === 'string') {\n          // we can replace the earlier diffMatchPatches with a new one\n          const replaced: NodePatch = {\n            ...laterPatch,\n            op: {\n              type: 'diffMatchPatch',\n              value: stringifyPatches(\n                makePatches(current, laterPatch.op.value),\n              ),\n            },\n          }\n          return earlierPatches\n            .flatMap(ep => {\n              return isEqualPath(ep.path, laterPatch.path) &&\n                ep.op.type === 'diffMatchPatch'\n                ? []\n                : ep\n            })\n            .concat(replaced)\n        }\n      }\n      earlierPatches.push(laterPatch)\n      return earlierPatches\n    },\n    [],\n  )\n}\n","import {\n  type Mutation,\n  type NodePatch,\n  type PatchMutation,\n  type SanityDocumentBase,\n} from '../../../mutations/types'\nimport {type MutationGroup} from '../../types'\nimport {compactDMPSetPatches} from './squashNodePatches'\n\ninterface DataStore {\n  get: (id: string) => SanityDocumentBase | undefined\n}\nexport function squashDMPStrings(\n  base: DataStore,\n  mutationGroups: MutationGroup[],\n): MutationGroup[] {\n  return mutationGroups.map(mutationGroup => ({\n    ...mutationGroup,\n    mutations: dmpIfyMutations(base, mutationGroup.mutations),\n  }))\n}\n\nexport function dmpIfyMutations(\n  store: DataStore,\n  mutations: Mutation[],\n): Mutation[] {\n  return mutations.map((mutation, i) => {\n    if (mutation.type !== 'patch') {\n      return mutation\n    }\n    const base = store.get(mutation.id)\n    return base ? dmpifyPatchMutation(base, mutation) : mutation\n  })\n}\n\nexport function dmpifyPatchMutation(\n  base: SanityDocumentBase,\n  mutation: PatchMutation,\n): PatchMutation {\n  return {\n    ...mutation,\n    patches: compactDMPSetPatches(base, mutation.patches as NodePatch[]),\n  }\n}\n","import {type MutationGroup} from '../types'\n\n/**\n * Merges adjacent non-transactional mutation groups, interleaving transactional mutations as-is\n * @param mutationGroups\n */\nexport function mergeMutationGroups(\n  mutationGroups: MutationGroup[],\n): MutationGroup[] {\n  return chunkWhile(mutationGroups, group => !group.transaction).flatMap(\n    chunk => ({\n      ...chunk[0]!,\n      mutations: chunk.flatMap(c => c.mutations),\n    }),\n  )\n}\n\n/**\n * Groups subsequent mutations into transactions, leaves transactions as-is\n * @param arr\n * @param predicate\n */\nexport function chunkWhile<T>(\n  arr: T[],\n  predicate: (item: T) => boolean,\n): T[][] {\n  const res: T[][] = []\n  let currentChunk: T[] = []\n  arr.forEach(item => {\n    if (predicate(item)) {\n      currentChunk.push(item)\n    } else {\n      if (currentChunk.length > 0) {\n        res.push(currentChunk)\n      }\n      currentChunk = []\n      res.push([item])\n    }\n  })\n  if (currentChunk.length > 0) {\n    res.push(currentChunk)\n  }\n  return res\n}\n","import {groupBy} from 'lodash'\n\nimport {type Mutation, type NodePatch} from '../../../mutations/types'\nimport {type MutationGroup} from '../../types'\nimport {takeUntilRight} from '../../utils/arrayUtils'\nimport {getMutationDocumentId} from '../../utils/getMutationDocumentId'\nimport {mergeMutationGroups} from '../../utils/mergeMutationGroups'\nimport {squashNodePatches} from './squashNodePatches'\n\nexport function squashMutationGroups(staged: MutationGroup[]): MutationGroup[] {\n  return mergeMutationGroups(staged)\n    .map(transaction => ({\n      ...transaction,\n      mutations: squashMutations(transaction.mutations),\n    }))\n    .map(transaction => ({\n      ...transaction,\n      mutations: transaction.mutations.map(mutation => {\n        if (mutation.type !== 'patch') {\n          return mutation\n        }\n        return {\n          ...mutation,\n          patches: squashNodePatches(mutation.patches as NodePatch[]),\n        }\n      }),\n    }))\n}\n\ntype FIXME = Mutation[]\n\n/*\n assumptions:\n the order documents appear with their mutations within the same transaction doesn't matter\n */\nexport function squashMutations(mutations: Mutation[]): Mutation[] {\n  const byDocument = groupBy(mutations, getMutationDocumentId)\n  return Object.values(byDocument).flatMap(documentMutations => {\n    // these are the mutations that happens for the document with <id> within the same transactions\n    return squashCreateIfNotExists(squashDelete(documentMutations as FIXME))\n      .flat()\n      .reduce((acc: Mutation[], docMutation) => {\n        const prev = acc[acc.length - 1]\n        if ((!prev || prev.type === 'patch') && docMutation.type === 'patch') {\n          return acc.slice(0, -1).concat({\n            ...docMutation,\n            patches: (prev?.patches || []).concat(docMutation.patches),\n          })\n        }\n        return acc.concat(docMutation)\n      }, [])\n  })\n}\n\n/**\n * WARNING: This assumes that the mutations are only for a single document\n * @param mutations\n */\nexport function squashCreateIfNotExists(mutations: Mutation[]): Mutation[] {\n  if (mutations.length === 0) {\n    return mutations\n  }\n\n  return mutations.reduce((previousMuts: Mutation[], laterMut: Mutation) => {\n    if (laterMut.type !== 'createIfNotExists') {\n      previousMuts.push(laterMut)\n      return previousMuts\n    }\n    const prev = takeUntilRight(previousMuts, m => m.type === 'delete')\n    const precedent = prev.find(\n      precedingPatch => precedingPatch.type === 'createIfNotExists',\n    )\n    if (precedent) {\n      // we already have an identical patch earlier in the chain that voids this one\n      return previousMuts\n    }\n    previousMuts.push(laterMut)\n    return previousMuts\n  }, [])\n}\n\nfunction squashDelete(mutations: Mutation[]): Mutation[] {\n  if (mutations.length === 0) {\n    return mutations\n  }\n\n  return mutations.reduce((previousMuts: Mutation[], laterMut: Mutation) => {\n    if (laterMut.type === 'delete') {\n      return [laterMut]\n    }\n    previousMuts.push(laterMut)\n    return previousMuts\n  }, [])\n}\n","import {applyPatches} from '../../apply'\nimport {\n  type Mutation,\n  type NodePatch,\n  type PatchMutation,\n  type SanityDocumentBase,\n} from '../../mutations/types'\nimport {getAtPath} from '../../path'\nimport {applyAll} from '../documentMap/applyDocumentMutation'\nimport {type MutationGroup} from '../types'\nimport {getMutationDocumentId} from '../utils/getMutationDocumentId'\nimport {compactDMPSetPatches} from './optimizations/squashNodePatches'\n\ntype RebaseTransaction = {\n  mutations: Mutation[]\n}\n\ntype FlatMutation = Exclude<Mutation, PatchMutation>\n\nfunction flattenMutations(mutations: Mutation[]) {\n  return mutations.flatMap((mut): Mutation | Mutation[] => {\n    if (mut.type === 'patch') {\n      return mut.patches.map(\n        (patch): PatchMutation => ({\n          type: 'patch',\n          id: mut.id,\n          patches: [patch],\n        }),\n      )\n    }\n    return mut\n  })\n}\n\nexport function rebase(\n  documentId: string,\n  oldBase: SanityDocumentBase | undefined,\n  newBase: SanityDocumentBase | undefined,\n  localMutations: MutationGroup[],\n): [newLocal: MutationGroup[], rebased: SanityDocumentBase | undefined] {\n  // const flattened = flattenMutations(newStage.flatMap(t => t.mutations))\n\n  // 1. get the dmpified mutations from the newStage based on the old base\n  // 2. apply those to the new base\n  // 3. convert those back into set patches based on the new base and return as a new newStage\n  let edge = oldBase\n  const dmpified = localMutations.map(transaction => {\n    const mutations = transaction.mutations.flatMap(mut => {\n      if (getMutationDocumentId(mut) !== documentId) {\n        return []\n      }\n      const before = edge\n      edge = applyAll(edge, [mut])\n      if (!before) {\n        return mut\n      }\n      if (mut.type !== 'patch') {\n        return mut\n      }\n      return {\n        type: 'dmpified' as const,\n        mutation: {\n          ...mut,\n          // Todo: make compactDMPSetPatches return pairs of patches that was dmpified with their\n          //  original as dmpPatches and original is not 1:1 (e..g some of the original may not be dmpified)\n          dmpPatches: compactDMPSetPatches(before, mut.patches as NodePatch[]),\n          original: mut.patches,\n        },\n      }\n    })\n    return {...transaction, mutations}\n  })\n\n  let newBaseWithDMPForOldBaseApplied: SanityDocumentBase | undefined = newBase\n  // NOTE: It might not be possible to apply them - if so, we fall back to applying the pending changes\n  // todo: revisit this\n  const appliedCleanly = dmpified.map(transaction => {\n    const applied = []\n    return transaction.mutations.forEach(mut => {\n      if (mut.type === 'dmpified') {\n        // go through all dmpified, try to apply, if they fail, use the original un-optimized set patch instead\n        try {\n          newBaseWithDMPForOldBaseApplied = applyPatches(\n            mut.mutation.dmpPatches,\n            newBaseWithDMPForOldBaseApplied,\n          )\n          applied.push(mut)\n        } catch (err) {\n          // eslint-disable-next-line no-console\n          console.warn('Failed to apply dmp patch, falling back to original')\n          try {\n            newBaseWithDMPForOldBaseApplied = applyPatches(\n              mut.mutation.original,\n              newBaseWithDMPForOldBaseApplied,\n            )\n            applied.push(mut)\n          } catch (second: any) {\n            throw new Error(\n              `Failed to apply patch for document \"${documentId}\": ${second.message}`,\n            )\n          }\n        }\n      } else {\n        newBaseWithDMPForOldBaseApplied = applyAll(\n          newBaseWithDMPForOldBaseApplied,\n          [mut],\n        )\n      }\n    })\n  })\n\n  const newStage = localMutations.map((transaction): MutationGroup => {\n    // update all set patches to set to the current value\n    return {\n      ...transaction,\n      mutations: transaction.mutations.map(mut => {\n        if (mut.type !== 'patch' || getMutationDocumentId(mut) !== documentId) {\n          return mut\n        }\n        return {\n          ...mut,\n          patches: mut.patches.map(patch => {\n            if (patch.op.type !== 'set') {\n              return patch\n            }\n            return {\n              ...patch,\n              op: {\n                ...patch.op,\n                value: getAtPath(patch.path, newBaseWithDMPForOldBaseApplied),\n              },\n            }\n          }),\n        }\n      }),\n    }\n  })\n  return [newStage, newBaseWithDMPForOldBaseApplied]\n}\n","import {type ReconnectEvent} from '@sanity/client'\nimport {\n  concatMap,\n  defer,\n  EMPTY,\n  filter,\n  from,\n  lastValueFrom,\n  map,\n  merge,\n  mergeMap,\n  type Observable,\n  of,\n  Subject,\n  tap,\n  toArray,\n} from 'rxjs'\n\nimport {decodeAll, type SanityMutation} from '../../encoders/sanity'\nimport {type Transaction} from '../../mutations/types'\nimport {applyAll} from '../documentMap/applyDocumentMutation'\nimport {applyMutationEventEffects} from '../documentMap/applyMendoza'\nimport {applyMutations} from '../documentMap/applyMutations'\nimport {commit} from '../documentMap/commit'\nimport {createDocumentMap} from '../documentMap/createDocumentMap'\nimport {\n  type ListenerEvent,\n  type MutationGroup,\n  type OptimisticDocumentEvent,\n  type OptimisticStore,\n  type RemoteDocumentEvent,\n  type RemoteMutationEvent,\n  type SubmitResult,\n  type TransactionalMutationGroup,\n} from '../types'\nimport {createReplayMemoizer} from '../utils/createReplayMemoizer'\nimport {createTransactionId} from '../utils/createTransactionId'\nimport {filterMutationGroupsById} from '../utils/filterMutationGroups'\nimport {hasProperty} from '../utils/isEffectEvent'\nimport {squashDMPStrings} from './optimizations/squashDMPStrings'\nimport {squashMutationGroups} from './optimizations/squashMutations'\nimport {rebase} from './rebase'\n\nexport interface OptimisticStoreBackend {\n  /**\n   * Sets up a subscription to a document\n   * The first event should either be a sync event or an error event.\n   * After that, it should emit mutation events, error events or sync events\n   * @param id\n   */\n  listen: (id: string) => Observable<ListenerEvent>\n  submit: (mutationGroups: Transaction) => Observable<SubmitResult>\n}\n\nlet didEmitMutationsAccessWarning = false\n// certain components, like the portable text editor, rely on mutations to be present in the event\n// i.e. it's not enough to just have the mendoza-patches.\n// If the listener event did not include mutations (e.g. if excludeMutations was set to true),\n// this warning will be issued if a downstream consumers attempts to access event.mutations\nfunction warnNoMutationsReceived() {\n  if (!didEmitMutationsAccessWarning) {\n    // eslint-disable-next-line no-console\n    console.warn(\n      new Error(\n        'No mutation received from backend. The listener is likely set up with `excludeMutations: true`. If your app need to know about mutations, make sure the listener is set up to include mutations',\n      ),\n    )\n    didEmitMutationsAccessWarning = true\n  }\n}\n\nconst EMPTY_ARRAY: any[] = []\n\n/**\n * Creates a local dataset that allows subscribing to documents by id and submitting mutations to be optimistically applied\n * @param backend\n */\nexport function createOptimisticStore(\n  backend: OptimisticStoreBackend,\n): OptimisticStore {\n  const local = createDocumentMap()\n  const remote = createDocumentMap()\n  const memoize = createReplayMemoizer(1000)\n  let stagedChanges: MutationGroup[] = []\n\n  const remoteEvents$ = new Subject<RemoteDocumentEvent>()\n  const localMutations$ = new Subject<OptimisticDocumentEvent>()\n\n  const stage$ = new Subject<void>()\n\n  function setStaged(nextPending: MutationGroup[]) {\n    stagedChanges = nextPending\n    stage$.next()\n  }\n\n  function getLocalEvents(id: string) {\n    return localMutations$.pipe(filter(event => event.id === id))\n  }\n\n  function getRemoteEvents(id: string) {\n    return backend.listen(id).pipe(\n      filter(\n        (event): event is Exclude<ListenerEvent, ReconnectEvent> =>\n          event.type !== 'reconnect',\n      ),\n      mergeMap((event): Observable<RemoteDocumentEvent> => {\n        const oldLocal = local.get(id)\n        const oldRemote = remote.get(id)\n        if (event.type === 'sync') {\n          const newRemote = event.document\n          const [rebasedStage, newLocal] = rebase(\n            id,\n            oldRemote,\n            newRemote,\n            stagedChanges,\n          )\n          return of({\n            type: 'sync',\n            id,\n            before: {remote: oldRemote, local: oldLocal},\n            after: {remote: newRemote, local: newLocal},\n            rebasedStage,\n          })\n        } else if (event.type === 'mutation') {\n          // we have already seen this mutation\n          if (event.transactionId === oldRemote?._rev) {\n            return EMPTY\n          }\n          let newRemote\n          if (hasProperty(event, 'effects')) {\n            newRemote = applyMutationEventEffects(oldRemote, event)\n          } else if (hasProperty(event, 'mutations')) {\n            newRemote = applyAll(oldRemote, decodeAll(event.mutations))\n          } else {\n            throw new Error(\n              'Neither effects or mutations found on listener event',\n            )\n          }\n          const [rebasedStage, newLocal] = rebase(\n            id,\n            oldRemote,\n            newRemote,\n            stagedChanges,\n          )\n\n          if (newLocal) {\n            newLocal._rev = event.transactionId\n          }\n          const emittedEvent: RemoteMutationEvent = {\n            type: 'mutation',\n            id,\n            rebasedStage,\n            before: {remote: oldRemote, local: oldLocal},\n            after: {remote: newRemote, local: newLocal},\n            effects: event.effects,\n            previousRev: event.previousRev,\n            resultRev: event.resultRev,\n            // overwritten below\n            mutations: EMPTY_ARRAY,\n          }\n          if (event.mutations) {\n            emittedEvent.mutations = decodeAll(\n              event.mutations as SanityMutation[],\n            )\n          } else {\n            Object.defineProperty(\n              emittedEvent,\n              'mutations',\n              warnNoMutationsReceived,\n            )\n          }\n          return of(emittedEvent)\n        } else {\n          // @ts-expect-error should have covered all cases\n          throw new Error(`Unknown event type: ${event.type}`)\n        }\n      }),\n      tap(event => {\n        local.set(event.id, event.after.local)\n        remote.set(event.id, event.after.remote)\n        setStaged(event.rebasedStage)\n      }),\n      tap({\n        next: event => remoteEvents$.next(event),\n        error: err => {\n          // todo: how to propagate errors?\n          // remoteEvents$.next()\n        },\n      }),\n    )\n  }\n\n  function listenEvents(id: string) {\n    return defer(() =>\n      memoize(id, merge(getLocalEvents(id), getRemoteEvents(id))),\n    )\n  }\n\n  const metaEvents$ = merge(localMutations$, remoteEvents$)\n\n  return {\n    meta: {\n      events: metaEvents$,\n      stage: stage$.pipe(\n        map(\n          () =>\n            // note: this should not be tampered with by consumers. We might want to do a deep-freeze during dev to avoid accidental mutations\n            stagedChanges,\n        ),\n      ),\n      conflicts: EMPTY, // does nothing for now\n    },\n    mutate: mutations => {\n      // add mutations to list of pending changes\n      stagedChanges.push({transaction: false, mutations})\n      // Apply mutations to local dataset (note: this is immutable, and doesn't change the dataset)\n      const results = applyMutations(mutations, local)\n      // Write the updated results back to the \"local\" dataset\n      commit(results, local)\n      results.forEach(result => {\n        localMutations$.next({\n          type: 'optimistic',\n          before: result.before,\n          after: result.after,\n          mutations: result.mutations,\n          id: result.id,\n          stagedChanges: filterMutationGroupsById(stagedChanges, result.id),\n        })\n      })\n      return results\n    },\n    transaction: mutationsOrTransaction => {\n      const transaction: TransactionalMutationGroup = Array.isArray(\n        mutationsOrTransaction,\n      )\n        ? {mutations: mutationsOrTransaction, transaction: true}\n        : {...mutationsOrTransaction, transaction: true}\n\n      stagedChanges.push(transaction)\n      const results = applyMutations(transaction.mutations, local)\n      commit(results, local)\n      results.forEach(result => {\n        localMutations$.next({\n          type: 'optimistic',\n          mutations: result.mutations,\n          id: result.id,\n          before: result.before,\n          after: result.after,\n          stagedChanges: filterMutationGroupsById(stagedChanges, result.id),\n        })\n      })\n      return results\n    },\n    listenEvents: listenEvents,\n    listen: id =>\n      listenEvents(id).pipe(\n        map(event =>\n          event.type === 'optimistic' ? event.after : event.after.local,\n        ),\n      ),\n    optimize: () => {\n      setStaged(squashMutationGroups(stagedChanges))\n    },\n    submit: () => {\n      const pending = stagedChanges\n      setStaged([])\n      return lastValueFrom(\n        from(\n          toTransactions(\n            // Squashing DMP strings is the last thing we do before submitting\n            squashDMPStrings(remote, squashMutationGroups(pending)),\n          ),\n        ).pipe(\n          concatMap(mut => backend.submit(mut)),\n          toArray(),\n        ),\n      )\n    },\n  }\n}\n\nfunction toTransactions(groups: MutationGroup[]): Transaction[] {\n  return groups.map(group => {\n    if (group.transaction && group.id !== undefined) {\n      return {id: group.id!, mutations: group.mutations}\n    }\n    return {id: createTransactionId(), mutations: group.mutations}\n  })\n}\n"],"names":["finalize","share","timer","ReplaySubject","combineLatest","lodashPartition","EMPTY_ARRAY","scan","switchMap","concat","of","mergeMap","throwError","concatMap","EMPTY","catchError","map","scheduled","asyncScheduler","BehaviorSubject","Subject","filter","bufferWhen","takeUntil","Observable","defer","merge","takeWhile","keyBy","assignId","nanoid","hasId","applyPatchMutation","patch","applyPatch","decodeAll","sortedIndex","tap","uuid","NEVER","partition","encodeAll","from","encodeTransaction","stringify","startsWith","applyNodePatch","getAtPath","stringifyPatches","makePatches","groupBy","applyPatches","lastValueFrom","toArray"],"mappings":"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"}