{"version":3,"file":"createOptimisticStore.cjs","sources":["../../src/store/utils/getMutationDocumentId.ts","../../src/store/documentMap/applyDocumentMutation.ts","../../src/store/documentMap/applyMutations.ts","../../src/store/documentMap/commit.ts","../../src/store/documentMap/applyMendoza.ts","../../src/store/documentMap/createDocumentMap.ts","../../src/store/utils/createReplayMemoizer.ts","../../src/store/utils/createTransactionId.ts","../../src/store/utils/filterMutationGroups.ts","../../src/store/utils/isEffectEvent.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":["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 {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 {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'\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 {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","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 {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 {uuid} from '@sanity/uuid'\n\nexport function createTransactionId() {\n  return uuid()\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 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","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\nexport interface 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\nexport function 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":["assignId","nanoid","hasId","applyPatchMutation","patch","applyPatch","finalize","share","ReplaySubject","timer","uuid","stringify","startsWith","applyNodePatch","getAtPath","stringifyPatches","makePatches","groupBy","applyPatches","Subject","filter","mergeMap","of","EMPTY","decodeAll","tap","defer","merge","map","lastValueFrom","from","concatMap","toArray"],"mappings":"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"}