@sanity/visual-editing
Version:
[](https://npm-stat.com/charts.html?package=@sanity/visual-editing) [](https://
1 lines • 37.8 kB
Source Map (JSON)
{"version":3,"file":"mutations.cjs","sources":["../../../../node_modules/.pnpm/@sanity+types@3.68.3_@types+react@18.3.18/node_modules/@sanity/types/lib/index.mjs","../../../../node_modules/.pnpm/@sanity+util@3.68.3_@types+react@18.3.18/node_modules/@sanity/util/lib/paths.mjs","../../src/util/documents.ts","../../src/react/useOptimisticActor.ts","../../src/react/useDocuments.ts","../../src/util/randomKey.ts","../../src/util/mutations.ts"],"sourcesContent":["function isObject(obj) {\n return typeof obj == \"object\" && obj !== null && !Array.isArray(obj);\n}\nfunction isReference(reference) {\n return isObject(reference) && typeof reference._ref == \"string\";\n}\nfunction isImage(value) {\n return isObject(value) && isReference(value.asset) && value.asset._ref.startsWith(\"image-\");\n}\nfunction isCrossDatasetReference(reference) {\n return isObject(reference) && typeof reference._ref == \"string\" && typeof reference._dataset == \"string\" && typeof reference._projectId == \"string\";\n}\nfunction isSanityDocument(document) {\n return isObject(document) && typeof document._id == \"string\" && typeof document._type == \"string\";\n}\nfunction isTypedObject(obj) {\n return isObject(obj) && typeof obj._type == \"string\";\n}\nfunction isKeyedObject(obj) {\n return isObject(obj) && typeof obj._key == \"string\";\n}\nfunction isValidationErrorMarker(marker) {\n return marker.level === \"error\";\n}\nfunction isValidationWarningMarker(marker) {\n return marker.level === \"warning\";\n}\nfunction isValidationInfoMarker(marker) {\n return marker.level === \"info\";\n}\nfunction isCreateMutation(mutation) {\n return \"create\" in mutation;\n}\nfunction isCreateIfNotExistsMutation(mutation) {\n return \"createIfNotExists\" in mutation;\n}\nfunction isCreateOrReplaceMutation(mutation) {\n return \"createOrReplace\" in mutation;\n}\nfunction isDeleteMutation(mutation) {\n return \"delete\" in mutation;\n}\nfunction isPatchMutation(mutation) {\n return \"patch\" in mutation;\n}\nconst reKeySegment = /_key\\s*==\\s*['\"](.*)['\"]/, reIndexTuple = /^\\d*:\\d*$/;\nfunction isIndexSegment(segment) {\n return typeof segment == \"number\" || typeof segment == \"string\" && /^\\[\\d+\\]$/.test(segment);\n}\nfunction isKeySegment(segment) {\n return typeof segment == \"string\" ? reKeySegment.test(segment.trim()) : typeof segment == \"object\" && \"_key\" in segment;\n}\nfunction isIndexTuple(segment) {\n if (typeof segment == \"string\" && reIndexTuple.test(segment))\n return !0;\n if (!Array.isArray(segment) || segment.length !== 2)\n return !1;\n const [from, to] = segment;\n return (typeof from == \"number\" || from === \"\") && (typeof to == \"number\" || to === \"\");\n}\nfunction isRecord$1(value) {\n return !!value && (typeof value == \"object\" || typeof value == \"function\");\n}\nfunction isPortableTextTextBlock(value) {\n return isRecord$1(value) && typeof value._type == \"string\" && // block types can be named, so expect anything here.\n Array.isArray(value.children) && value.children.every((child) => isRecord$1(child)) && (\"markDefs\" in value ? Array.isArray(value.markDefs) && value.markDefs.every((def) => isRecord$1(def)) : !0) && (\"style\" in value ? typeof value.style == \"string\" : !0);\n}\nfunction isPortableTextSpan(value) {\n return isRecord$1(value) && value._type === \"span\" && typeof value.text == \"string\" && (\"marks\" in value ? Array.isArray(value.marks) && value.marks.every((mark) => typeof mark == \"string\") : !0);\n}\nfunction isPortableTextListBlock(value) {\n return isPortableTextTextBlock(value) && \"listItem\" in value && typeof value.listItem == \"string\" && \"level\" in value && Number.isInteger(value.level);\n}\nfunction isRecord(value) {\n return !!value && (typeof value == \"object\" || typeof value == \"function\");\n}\nfunction isDocumentSchemaType(type) {\n if (!isObjectSchemaType(type))\n return !1;\n let current = type;\n for (; current; ) {\n if (current.name === \"document\")\n return !0;\n current = current.type;\n }\n return !1;\n}\nfunction isObjectSchemaType(type) {\n return isRecord(type) ? type.jsonType === \"object\" : !1;\n}\nfunction isArraySchemaType(type) {\n return isRecord(type) ? type.jsonType === \"array\" : !1;\n}\nfunction isArrayOfBlocksSchemaType(type) {\n return isArraySchemaType(type) && type.of.some((memberType) => isBlockSchemaType(memberType));\n}\nfunction isArrayOfObjectsSchemaType(type) {\n return isArraySchemaType(type) && type.of.every((memberType) => isObjectSchemaType(memberType));\n}\nfunction isArrayOfPrimitivesSchemaType(type) {\n return isArraySchemaType(type) && type.of.every((memberType) => isPrimitiveSchemaType(memberType));\n}\nfunction isBooleanSchemaType(type) {\n return isRecord(type) ? type.jsonType === \"boolean\" : !1;\n}\nfunction isStringSchemaType(type) {\n return isRecord(type) ? type.jsonType === \"string\" : !1;\n}\nfunction isNumberSchemaType(type) {\n return isRecord(type) ? type.jsonType === \"number\" : !1;\n}\nfunction isPrimitiveSchemaType(type) {\n return isBooleanSchemaType(type) || isStringSchemaType(type) || isNumberSchemaType(type);\n}\nfunction isReferenceSchemaType(type) {\n return isRecord(type) && (type.name === \"reference\" || isReferenceSchemaType(type.type));\n}\nfunction isImageSchemaType(type) {\n return isRecord(type) && (type.name === \"image\" || isImageSchemaType(type.type));\n}\nfunction isFileSchemaType(type) {\n return isRecord(type) && (type.name === \"file\" || isFileSchemaType(type.type));\n}\nfunction isDeprecatedSchemaType(type) {\n return isRecord(type) ? typeof type.deprecated < \"u\" : !1;\n}\nfunction isDeprecationConfiguration(type) {\n return isRecord(type) ? typeof type.deprecated < \"u\" : !1;\n}\nfunction isCrossDatasetReferenceSchemaType(type) {\n return isRecord(type) && (type.name === \"crossDatasetReference\" || isCrossDatasetReferenceSchemaType(type.type));\n}\nfunction isTitledListValue(item) {\n return typeof item == \"object\" && item !== null && \"title\" in item && \"value\" in item;\n}\nfunction isSpanSchemaType(type) {\n return isRecord(type) ? Array.isArray(type.annotations) && Array.isArray(type.decorators) : !1;\n}\nfunction isBlockSchemaType(type) {\n if (!isRecord(type) || !Array.isArray(type.fields)) return !1;\n const maybeSpanChildren = type.fields.find(isBlockChildrenObjectField), maybeStyle = type.fields.find(isBlockStyleObjectField), maybeList = type.fields.find(isBlockListObjectField);\n return isBlockChildrenObjectField(maybeSpanChildren) && isBlockStyleObjectField(maybeStyle) && isBlockListObjectField(maybeList);\n}\nfunction isBlockStyleObjectField(field) {\n return !isRecord(field) || field.name !== \"style\" ? !1 : isRecord(field.type) && field.type.jsonType === \"string\";\n}\nfunction isBlockListObjectField(field) {\n return !isRecord(field) || field.name !== \"listItem\" ? !1 : isRecord(field.type) && field.type.jsonType === \"string\";\n}\nfunction isBlockChildrenObjectField(field) {\n return !isRecord(field) || field.name !== \"children\" || !isArraySchemaType(field.type) ? !1 : field.type.of.some(isSpanSchemaType);\n}\nfunction defineType(schemaDefinition, defineOptions) {\n return schemaDefinition;\n}\nfunction defineField(schemaField, defineOptions) {\n return schemaField;\n}\nfunction defineArrayMember(arrayOfSchema, defineOptions) {\n return arrayOfSchema;\n}\nfunction typed(input) {\n return input;\n}\nconst searchStrategies = [\"groqLegacy\", \"textSearch\", \"groq2024\"];\nfunction isSearchStrategy(maybeSearchStrategy) {\n return searchStrategies.includes(maybeSearchStrategy);\n}\nfunction isSlug(thing) {\n return isObject(thing) && typeof thing.current == \"string\";\n}\nfunction isCreateSquashedMutation(mutation) {\n return \"createSquashed\" in mutation;\n}\nfunction isValidationError(node) {\n return node.level === \"error\";\n}\nfunction isValidationWarning(node) {\n return node.level === \"warning\";\n}\nfunction isValidationInfo(node) {\n return node.level === \"info\";\n}\nexport {\n defineArrayMember,\n defineField,\n defineType,\n isArrayOfBlocksSchemaType,\n isArrayOfObjectsSchemaType,\n isArrayOfPrimitivesSchemaType,\n isArraySchemaType,\n isBlockChildrenObjectField,\n isBlockListObjectField,\n isBlockSchemaType,\n isBlockStyleObjectField,\n isBooleanSchemaType,\n isCreateIfNotExistsMutation,\n isCreateMutation,\n isCreateOrReplaceMutation,\n isCreateSquashedMutation,\n isCrossDatasetReference,\n isCrossDatasetReferenceSchemaType,\n isDeleteMutation,\n isDeprecatedSchemaType,\n isDeprecationConfiguration,\n isDocumentSchemaType,\n isFileSchemaType,\n isImage,\n isImageSchemaType,\n isIndexSegment,\n isIndexTuple,\n isKeySegment,\n isKeyedObject,\n isNumberSchemaType,\n isObjectSchemaType,\n isPatchMutation,\n isPortableTextListBlock,\n isPortableTextSpan,\n isPortableTextTextBlock,\n isPrimitiveSchemaType,\n isReference,\n isReferenceSchemaType,\n isSanityDocument,\n isSearchStrategy,\n isSlug,\n isSpanSchemaType,\n isStringSchemaType,\n isTitledListValue,\n isTypedObject,\n isValidationError,\n isValidationErrorMarker,\n isValidationInfo,\n isValidationInfoMarker,\n isValidationWarning,\n isValidationWarningMarker,\n searchStrategies,\n typed\n};\n//# sourceMappingURL=index.mjs.map\n","import { isIndexSegment, isKeySegment, isIndexTuple } from \"@sanity/types\";\nconst rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g, reKeySegment = /_key\\s*==\\s*['\"](.*)['\"]/, EMPTY_PATH = [], FOCUS_TERMINATOR = \"$\", GROQ_DATA_TYPE_VALUES = [\"true\", \"false\", \"null\"];\nfunction get(obj, path, defaultVal) {\n const select = typeof path == \"string\" ? fromString(path) : path;\n if (!Array.isArray(select))\n throw new Error(\"Path must be an array or a string\");\n let acc = obj;\n for (let i = 0; i < select.length; i++) {\n const segment = select[i];\n if (isIndexSegment(segment)) {\n if (!Array.isArray(acc))\n return defaultVal;\n acc = acc[segment];\n }\n if (isKeySegment(segment)) {\n if (!Array.isArray(acc))\n return defaultVal;\n acc = acc.find((item) => item._key === segment._key);\n }\n if (typeof segment == \"string\" && (acc = typeof acc == \"object\" && acc !== null ? acc[segment] : void 0), typeof acc > \"u\")\n return defaultVal;\n }\n return acc;\n}\nconst pathsMemo = /* @__PURE__ */ new Map();\nfunction pathFor(path) {\n if (path.length === 0)\n return EMPTY_PATH;\n const asString = toString(path);\n return pathsMemo.has(asString) ? pathsMemo.get(asString) : (pathsMemo.set(asString, path), Object.freeze(path), path);\n}\nfunction isEqual(path, otherPath) {\n return path.length === otherPath.length && path.every((segment, i) => isSegmentEqual(segment, otherPath[i]));\n}\nfunction numEqualSegments(path, otherPath) {\n const length = Math.min(path.length, otherPath.length);\n for (let i = 0; i < length; i++)\n if (!isSegmentEqual(path[i], otherPath[i]))\n return i;\n return length;\n}\nfunction isSegmentEqual(segmentA, segmentB) {\n return isKeySegment(segmentA) && isKeySegment(segmentB) ? segmentA._key === segmentB._key : isIndexSegment(segmentA) ? Number(segmentA) === Number(segmentB) : isIndexTuple(segmentA) && isIndexTuple(segmentB) ? segmentA[0] === segmentB[0] && segmentA[1] === segmentB[1] : segmentA === segmentB;\n}\nfunction hasFocus(focusPath, path) {\n const withoutTerminator = focusPath[focusPath.length - 1] === FOCUS_TERMINATOR ? focusPath.slice(0, -1) : focusPath;\n return isEqual(withoutTerminator, path);\n}\nfunction hasItemFocus(focusPath, item) {\n return focusPath.length === 1 && isSegmentEqual(focusPath[0], item);\n}\nfunction isExpanded(segment, focusPath) {\n const [head, ...tail] = focusPath;\n return tail.length > 0 && isSegmentEqual(segment, head);\n}\nfunction startsWith(prefix, path) {\n return prefix.every((segment, i) => isSegmentEqual(segment, path[i]));\n}\nfunction trimLeft(prefix, path) {\n if (prefix.length === 0 || path.length === 0)\n return path;\n const [prefixHead, ...prefixTail] = prefix, [pathHead, ...pathTail] = path;\n return isSegmentEqual(prefixHead, pathHead) ? pathFor(trimLeft(prefixTail, pathTail)) : path;\n}\nfunction trimRight(suffix, path) {\n const sufLen = suffix.length, pathLen = path.length;\n if (sufLen === 0 || pathLen === 0)\n return path;\n let i = 0;\n for (; i < sufLen && i < pathLen && isSegmentEqual(path[pathLen - i - 1], suffix[sufLen - i - 1]); )\n i++;\n return pathFor(path.slice(0, pathLen - i));\n}\nfunction trimChildPath(path, childPath) {\n return startsWith(path, childPath) ? trimLeft(path, childPath) : EMPTY_PATH;\n}\nfunction toString(path) {\n if (!Array.isArray(path))\n throw new Error(\"Path is not an array\");\n return path.reduce((target, segment, i) => {\n const isHead = i === 0;\n if (typeof segment == \"number\")\n return `${target}[${segment}]`;\n if (typeof segment == \"string\")\n return isHead ? segment : GROQ_DATA_TYPE_VALUES.includes(segment) ? `${target}[\"${segment}\"]` : `${target}.${segment}`;\n if (isKeySegment(segment) && segment._key)\n return `${target}[_key==\"${segment._key}\"]`;\n if (Array.isArray(segment)) {\n const [from, to] = segment;\n return `${target}[${from}:${to}]`;\n }\n throw new Error(`Unsupported path segment \\`${JSON.stringify(segment)}\\``);\n }, \"\");\n}\nfunction _resolveKeyedPath(value, path) {\n if (path.length === 0)\n return path;\n const [next, ...rest] = path;\n if (typeof next == \"number\") {\n if (!Array.isArray(value) || !(next in value))\n return [];\n const item = value[next];\n return [typeof (item == null ? void 0 : item._key) == \"string\" ? { _key: item._key } : next, ..._resolveKeyedPath(item, rest)];\n }\n const nextVal = get(value, [next]);\n return [next, ..._resolveKeyedPath(nextVal, rest)];\n}\nfunction resolveKeyedPath(value, path) {\n if (!Array.isArray(path))\n throw new Error(\"Path is not an array\");\n return pathFor(_resolveKeyedPath(value, path));\n}\nfunction fromString(path) {\n if (typeof path != \"string\")\n throw new Error(\"Path is not a string\");\n const segments = path.match(rePropName);\n if (!segments)\n throw new Error(\"Invalid path string\");\n return segments.map(normalizePathSegment);\n}\nfunction normalizePathSegment(segment) {\n return isIndexSegment(segment) ? normalizeIndexSegment(segment) : isKeySegment(segment) ? normalizeKeySegment(segment) : isIndexTuple(segment) ? normalizeIndexTupleSegment(segment) : segment;\n}\nfunction normalizeIndexSegment(segment) {\n return Number(segment.replace(/[^\\d]/g, \"\"));\n}\nfunction normalizeKeySegment(segment) {\n return { _key: segment.match(reKeySegment)[1] };\n}\nfunction normalizeIndexTupleSegment(segment) {\n const [from, to] = segment.split(\":\").map((seg) => seg === \"\" ? seg : Number(seg));\n return [from, to];\n}\nexport {\n FOCUS_TERMINATOR,\n _resolveKeyedPath,\n fromString,\n get,\n hasFocus,\n hasItemFocus,\n isEqual,\n isExpanded,\n isSegmentEqual,\n numEqualSegments,\n pathFor,\n resolveKeyedPath,\n startsWith,\n toString,\n trimChildPath,\n trimLeft,\n trimRight\n};\n//# sourceMappingURL=paths.mjs.map\n","import {DRAFTS_PREFIX} from '@repo/visual-editing-helpers/csm'\n\nexport function isDraftId(id: string): boolean {\n return id.startsWith(DRAFTS_PREFIX)\n}\n\nexport function getDraftId(id: string): string {\n return isDraftId(id) ? id : DRAFTS_PREFIX + id\n}\n\nexport function getPublishedId(id: string): string {\n return isDraftId(id) ? id.slice(DRAFTS_PREFIX.length) : id\n}\n","import {useCallback, useMemo, useSyncExternalStore} from 'react'\nimport {\n actor,\n emptyActor,\n isEmptyActor,\n listeners,\n type EmptyActor,\n type MutatorActor,\n} from '../optimistic/context'\n\nexport function useOptimisticActor(): MutatorActor | EmptyActor {\n const subscribe = useCallback((listener: () => void) => {\n listeners.add(listener)\n return () => listeners.delete(listener)\n }, [])\n\n const actorRef = useSyncExternalStore(\n subscribe,\n () => actor,\n () => emptyActor,\n )\n\n return actorRef\n}\n\nexport function useOptimisticActorReady(): boolean {\n const actor = useOptimisticActor()\n return useMemo(() => !isEmptyActor(actor), [actor])\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type {SanityDocument} from '@sanity/client'\nimport {createIfNotExists, patch} from '@sanity/mutate'\nimport {get as getAtPath} from '@sanity/util/paths'\nimport {useCallback} from 'react'\nimport {isEmptyActor, type MutatorActor} from '../optimistic/context'\nimport type {\n DocumentsGet,\n DocumentsMutate,\n OptimisticDocumentPatches,\n Path,\n PathValue,\n} from '../optimistic/types'\nimport {getDraftId, getPublishedId} from '../util/documents'\nimport {useOptimisticActor} from './useOptimisticActor'\n\nfunction debounce<F extends (...args: Parameters<F>) => ReturnType<F>>(fn: F, timeout: number): F {\n let timer: ReturnType<typeof setTimeout>\n return ((...args: Parameters<F>) => {\n clearTimeout(timer)\n timer = setTimeout(() => {\n fn.apply(fn, args)\n }, timeout)\n }) as F\n}\n\nfunction getDocumentsAndSnapshot<T extends Record<string, any>>(id: string, actor: MutatorActor) {\n const inFrame = window.self !== window.top || window.opener\n\n if (isEmptyActor(actor) || !inFrame) {\n throw new Error('The `useDocuments` hook cannot be used in this context')\n }\n\n const draftId = getDraftId(id)\n const publishedId = getPublishedId(id)\n const documents = actor.getSnapshot().context?.documents\n\n const draftDoc = documents?.[draftId]\n const publishedDoc = documents?.[publishedId]\n const doc = draftDoc || publishedDoc\n\n if (!doc) {\n throw new Error(`Document \"${id}\" not found`)\n }\n\n // Helper to get the snapshot from the draft document if it exists, otherwise\n // fall back to the published document\n const getDocumentSnapshot = () =>\n (draftDoc.getSnapshot().context?.local || publishedDoc.getSnapshot().context?.local) as\n | SanityDocument<T>\n | null\n | undefined\n\n const snapshot = getDocumentSnapshot()\n const snapshotPromise = new Promise<SanityDocument<T> | null>((resolve) => {\n if (snapshot) {\n resolve(snapshot)\n } else {\n const subscriber = doc.on('ready', (event) => {\n // Assert type here as the original document mutator machine doesn't\n // emit a 'ready' event. We provide a custom action to emit it in this\n // package's internal `createDatasetMutator` function. <3 xstate.\n const {snapshot} = event as unknown as {snapshot: SanityDocument<T> | null | undefined}\n resolve(snapshot || null)\n subscriber.unsubscribe()\n })\n }\n })\n\n const getSnapshot = () => snapshotPromise\n\n return {\n draftDoc,\n draftId,\n getSnapshot,\n publishedDoc,\n publishedId,\n /**\n * @deprecated - use `getSnapshot` instead\n */\n get snapshot() {\n // Maintain original error throwing behaviour, to avoid breaking changes\n if (!snapshot) {\n throw new Error(`Snapshot for document \"${id}\" not found`)\n }\n return snapshot\n },\n }\n}\n\nfunction createDocumentCommit<T extends Record<string, any>>(id: string, actor: MutatorActor) {\n return (): void => {\n const {draftDoc} = getDocumentsAndSnapshot<T>(id, actor)\n draftDoc.send({type: 'submit'})\n }\n}\n\n/**\n * @deprecated - superseded by `createDocumentGetSnapshot`\n */\nfunction createDocumentGet<T extends Record<string, any>>(id: string, actor: MutatorActor) {\n return <P extends Path<T, keyof T>>(\n path?: P,\n ): PathValue<T, P> | SanityDocument<T> | undefined => {\n const {snapshot} = getDocumentsAndSnapshot<T>(id, actor)\n\n return path\n ? (getAtPath(snapshot, path) as PathValue<T, P>)\n : (snapshot as unknown as SanityDocument<T>)\n }\n}\n\nfunction createDocumentGetSnapshot<T extends Record<string, any>>(\n id: string,\n actor: MutatorActor,\n): () => Promise<SanityDocument<T> | null> {\n const {getSnapshot} = getDocumentsAndSnapshot<T>(id, actor)\n return getSnapshot\n}\n\nfunction createDocumentPatch<T extends Record<string, any>>(id: string, actor: MutatorActor) {\n return async (\n patches: OptimisticDocumentPatches<T>,\n options?: {commit?: boolean | {debounce: number}},\n ): Promise<void> => {\n // Destructure the function result in two steps as we need access to the\n // `result.snapshot` property in the getter, but don't want to execute the\n // getter prematurely as it may throw\n const result = getDocumentsAndSnapshot<T>(id, actor)\n const {draftDoc, draftId, getSnapshot, publishedId} = result\n\n const {commit = true} = options || {}\n\n const context = {\n draftId,\n publishedId,\n /**\n * @deprecated - use `getSnapshot` instead\n */\n get snapshot() {\n return result.snapshot\n },\n getSnapshot,\n }\n\n const resolvedPatches = await (typeof patches === 'function' ? patches(context) : patches)\n\n const _snapshot = await getSnapshot()\n\n if (!_snapshot) {\n throw new Error(`Snapshot for document \"${id}\" not found`)\n }\n\n draftDoc.send({\n type: 'mutate',\n mutations: [\n // Attempt to create the draft document, it might not exist if the\n // snapshot was from the published document\n createIfNotExists({..._snapshot, _id: draftId}),\n // Patch the draft document with the resolved patches\n patch(draftId, resolvedPatches),\n ],\n })\n\n if (commit) {\n if (typeof commit === 'object' && 'debounce' in commit) {\n const debouncedCommit = debounce(() => draftDoc.send({type: 'submit'}), commit.debounce)\n debouncedCommit()\n } else {\n draftDoc.send({type: 'submit'})\n }\n }\n }\n}\n\nexport function useDocuments(): {\n getDocument: DocumentsGet\n mutateDocument: DocumentsMutate\n} {\n const actor = useOptimisticActor() as MutatorActor\n\n const getDocument: DocumentsGet = useCallback(\n <T extends Record<string, any>>(documentId: string) => {\n return {\n id: documentId,\n commit: createDocumentCommit(documentId, actor),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore - Type instantiation is excessively deep and possibly infinite.\n get: createDocumentGet(documentId, actor),\n getSnapshot: createDocumentGetSnapshot<T>(documentId, actor),\n patch: createDocumentPatch<T>(documentId, actor),\n }\n },\n [actor],\n )\n\n const mutateDocument: DocumentsMutate = useCallback(\n (id, mutations, options) => {\n const {draftDoc} = getDocumentsAndSnapshot(id, actor)\n const {commit = true} = options || {}\n\n draftDoc.send({\n type: 'mutate',\n mutations: mutations,\n })\n\n if (commit) {\n if (typeof commit === 'object' && 'debounce' in commit) {\n const debouncedCommit = debounce(() => draftDoc.send({type: 'submit'}), commit.debounce)\n debouncedCommit()\n } else {\n draftDoc.send({type: 'submit'})\n }\n }\n },\n [actor],\n )\n\n return {getDocument, mutateDocument}\n}\n","import getRandomValues from 'get-random-values-esm'\n\n// WHATWG crypto RNG - https://w3c.github.io/webcrypto/Overview.html\nfunction whatwgRNG(length = 16) {\n const rnds8 = new Uint8Array(length)\n getRandomValues(rnds8)\n return rnds8\n}\n\nconst getByteHexTable = (() => {\n let table: string[]\n return () => {\n if (table) {\n return table\n }\n table = []\n for (let i = 0; i < 256; ++i) {\n table[i] = (i + 0x100).toString(16).slice(1)\n }\n return table\n }\n})()\n\nexport function randomKey(length?: number): string {\n const table = getByteHexTable()\n return whatwgRNG(length)\n .reduce((str, n) => str + table[n], '')\n .slice(0, length)\n}\n","import type {SanityNode} from '@repo/visual-editing-helpers'\nimport type {SanityDocument} from '@sanity/client'\nimport {at, insert, truncate, type NodePatchList} from '@sanity/mutate'\nimport {get} from '@sanity/util/paths'\nimport type {OptimisticDocument} from '../optimistic/types'\nimport {randomKey} from './randomKey'\n\nexport function getArrayItemKeyAndParentPath(pathOrNode: string | SanityNode): {\n path: string\n key: string\n hasExplicitKey: boolean\n} {\n const elementPath = typeof pathOrNode === 'string' ? pathOrNode : pathOrNode.path\n\n const lastDotIndex = elementPath.lastIndexOf('.')\n const lastPathItem = elementPath.substring(lastDotIndex + 1, elementPath.length)\n\n if (!lastPathItem.indexOf('[')) throw new Error('Invalid path: not an array')\n\n const lastArrayIndex = elementPath.lastIndexOf('[')\n const path = elementPath.substring(0, lastArrayIndex)\n\n let key\n let hasExplicitKey\n\n if (lastPathItem.includes('_key')) {\n // explicit [_key=\"...\"]\n\n const startIndex = lastPathItem.indexOf('\"') + 1\n const endIndex = lastPathItem.indexOf('\"', startIndex)\n\n key = lastPathItem.substring(startIndex, endIndex)\n\n hasExplicitKey = true\n } else {\n // indexes [int]\n const startIndex = lastPathItem.indexOf('[') + 1\n const endIndex = lastPathItem.indexOf(']', startIndex)\n\n key = lastPathItem.substring(startIndex, endIndex)\n\n hasExplicitKey = false\n }\n\n if (!path || !key) throw new Error('Invalid path')\n\n return {\n path,\n key,\n hasExplicitKey,\n }\n}\n\nexport function getArrayDuplicatePatches(\n node: SanityNode,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n snapshot: SanityDocument<Record<string, any>>,\n position: 'before' | 'after' = 'after',\n): NodePatchList {\n const {path: arrayPath, key: itemKey} = getArrayItemKeyAndParentPath(node)\n\n const item = get(snapshot, node.path) as object\n const duplicate = {...item, _key: randomKey()}\n\n return [at(arrayPath, insert(duplicate, position, {_key: itemKey}))]\n}\n\nexport function getArrayRemovePatches(\n node: SanityNode,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n snapshot: SanityDocument<Record<string, any>>,\n): NodePatchList {\n const {path: arrayPath, key: itemKey} = getArrayItemKeyAndParentPath(node)\n const array = get(snapshot, arrayPath) as {_key: string}[]\n const currentIndex = array.findIndex((item) => item._key === itemKey)\n return [at(arrayPath, truncate(currentIndex, currentIndex + 1))]\n}\n\nexport function getArrayInsertPatches(\n node: SanityNode,\n insertType: string,\n position: 'before' | 'after',\n): NodePatchList {\n const {path: arrayPath, key: itemKey} = getArrayItemKeyAndParentPath(node)\n const insertKey = randomKey()\n const referenceItem = {_key: itemKey}\n return [at(arrayPath, insert([{_type: insertType, _key: insertKey}], position, referenceItem))]\n}\n\nexport async function getArrayMovePatches(\n node: SanityNode,\n doc: OptimisticDocument,\n moveTo: 'previous' | 'next' | 'first' | 'last',\n): Promise<NodePatchList> {\n if (!node.type) throw new Error('Node type is missing')\n const {path: arrayPath, key: itemKey} = getArrayItemKeyAndParentPath(node)\n\n const snapshot = await doc.getSnapshot()\n const array = get(snapshot, arrayPath) as {_key: string}[]\n const item = get(snapshot, node.path)\n const currentIndex = array.findIndex((item) => item._key === itemKey)\n\n let nextIndex = -1\n let position: 'before' | 'after' = 'before'\n\n if (moveTo === 'first') {\n if (currentIndex === 0) return []\n nextIndex = 0\n position = 'before'\n } else if (moveTo === 'last') {\n if (currentIndex === array.length - 1) return []\n nextIndex = -1\n position = 'after'\n } else if (moveTo === 'next') {\n if (currentIndex === array.length - 1) return []\n nextIndex = currentIndex\n position = 'after'\n } else if (moveTo === 'previous') {\n if (currentIndex === 0) return []\n nextIndex = currentIndex - 1\n position = 'before'\n }\n\n return [\n at(arrayPath, truncate(currentIndex, currentIndex + 1)),\n at(arrayPath, insert(item, position, nextIndex)),\n ]\n}\n"],"names":["reactCompilerRuntime","require","mutate","context","transformSanityNodeData","React","_interopDefaultCompat","e","default","getRandomValues__default","reKeySegment","reIndexTuple","isIndexSegment","segment","test","isKeySegment","trim","rePropName","get","obj","path","defaultVal","select","Error","segments","match","map","normalizePathSegment","fromString","Array","isArray","acc","i","length","find","item","_key","Number","replace","normalizeIndexSegment","normalizeKeySegment","from","to","isIndexTuple","split","seg","normalizeIndexTupleSegment","isDraftId","id","startsWith","DRAFTS_PREFIX","getDraftId","getPublishedId","slice","useOptimisticActor","useSyncExternalStore","_temp","_temp2","_temp3","emptyActor","actor","listener","listeners","add","delete","debounce","fn","timeout","timer","args","clearTimeout","setTimeout","apply","getDocumentsAndSnapshot","inFrame","window","self","top","opener","isEmptyActor","draftId","publishedId","documents","getSnapshot","draftDoc","publishedDoc","doc","snapshot","local","snapshotPromise","Promise","resolve","subscriber","on","event","unsubscribe","createDocumentCommit","send","type","createDocumentGet","getAtPath","createDocumentGetSnapshot","createDocumentPatch","async","patches","options","result","commit","resolvedPatches","_snapshot","mutations","createIfNotExists","_id","patch","getByteHexTable","table","toString","randomKey","rnds8","Uint8Array","getRandomValues","whatwgRNG","reduce","str","n","getArrayItemKeyAndParentPath","pathOrNode","elementPath","lastDotIndex","lastIndexOf","lastPathItem","substring","indexOf","lastArrayIndex","key","hasExplicitKey","includes","startIndex","endIndex","exports","a","getArrayInsertPatches","node","insertType","position","arrayPath","itemKey","insertKey","at","insert","_type","b","c","d","getArrayMovePatches","moveTo","array","currentIndex","findIndex","nextIndex","truncate","f","getArrayRemovePatches","g","h","duplicate","t0","j","u","$","_c","documentId","getDocument","t1","t2","undefined","mutateDocument"],"mappings":"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","x_google_ignoreList":[0,1]}