@portabletext/plugin-sdk-value 7.1.1 → 7.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7,7 +7,18 @@ import { useEditDocument, useSanityInstance, useApplyDocumentActions, getDocumen
7
7
  import { useActorRef } from "@xstate/react";
8
8
  import "react";
9
9
  import { fromCallback, setup } from "xstate";
10
- const ARRAYIFY_ERROR_MESSAGE = "Unexpected path format from diffValue output. Please report this issue.";
10
+ import rawDebug from "debug";
11
+ const rootName = "pte:plugin-sdk-value:";
12
+ function createDebugger(name) {
13
+ const namespace = `${rootName}${name}`;
14
+ return rawDebug && rawDebug.enabled(namespace) ? rawDebug(namespace) : rawDebug(rootName);
15
+ }
16
+ const debug = {
17
+ mutation: createDebugger("mutation"),
18
+ push: createDebugger("push"),
19
+ remote: createDebugger("remote"),
20
+ repair: createDebugger("repair")
21
+ }, ARRAYIFY_ERROR_MESSAGE = "Unexpected path format from diffValue output. Please report this issue.";
11
22
  function* getSegments(node) {
12
23
  node.base && (yield* getSegments(node.base)), node.segment.type !== "This" && (yield node.segment);
13
24
  }
@@ -306,16 +317,34 @@ function scopeRemotePatches(patches, fieldPath) {
306
317
  }
307
318
  return scoped;
308
319
  }
309
- function syncDebugEnabled() {
310
- return globalThis.__PTE_SYNC_DEBUG === !0;
311
- }
312
- function syncDebug(kind, detail) {
313
- syncDebugEnabled() && console.debug(`[pte-sync] ${kind} ${JSON.stringify(detail())}`);
314
- }
315
320
  function debugTextOf(value) {
316
321
  return Array.isArray(value) ? value.map((block) => Array.isArray(block.children) ? (block.children ?? []).map((child) => child.text ?? "").join("") : "").join(`
317
322
  `) : "";
318
323
  }
324
+ const REPAIR_CONFIRM_DELAY = (
325
+ // @ts-expect-error - dot notation required for Vite to replace at build time
326
+ process.env.NODE_ENV === "test" ? 150 : 1e3
327
+ ), pendingRepairs = /* @__PURE__ */ new WeakMap(), unflushedEdits = /* @__PURE__ */ new WeakMap();
328
+ function computeRepair(editor, remoteValue) {
329
+ const snapshot = editor.getSnapshot().context.value, stateSignature = JSON.stringify([snapshot, remoteValue]);
330
+ try {
331
+ return {
332
+ patches: toEngineSafePatches(convertPatches(diffValue(snapshot, remoteValue)), remoteValue),
333
+ convertible: !0,
334
+ signature: stateSignature
335
+ };
336
+ } catch {
337
+ return {
338
+ patches: [],
339
+ convertible: !1,
340
+ signature: `!${stateSignature}`
341
+ };
342
+ }
343
+ }
344
+ function cancelPendingRepair(editor) {
345
+ const pending = pendingRepairs.get(editor);
346
+ pending && (clearTimeout(pending.timer), pendingRepairs.delete(editor));
347
+ }
319
348
  function applySync({
320
349
  editor,
321
350
  getRemoteValue
@@ -323,55 +352,80 @@ function applySync({
323
352
  const remoteValue = getRemoteValue();
324
353
  if (!remoteValue)
325
354
  return;
326
- const snapshot = editor.getSnapshot().context.value;
327
- if (syncDebugEnabled()) {
328
- const editorText = debugTextOf(snapshot), remoteText = debugTextOf(remoteValue);
329
- editorText !== remoteText && syncDebug("applySync:texts-differ", () => ({
330
- editorText,
331
- remoteText
332
- }));
333
- }
334
- let patches;
335
- try {
336
- patches = toEngineSafePatches(convertPatches(diffValue(snapshot, remoteValue)), remoteValue);
337
- } catch {
338
- editor.send({
339
- type: "update value",
340
- value: remoteValue
341
- });
355
+ const first = computeRepair(editor, remoteValue);
356
+ if (first.convertible && first.patches.length === 0) {
357
+ cancelPendingRepair(editor);
342
358
  return;
343
359
  }
344
- if (patches.length) {
345
- syncDebug("applySync:repair-patches", () => ({
346
- patches
347
- })), editor.send({
360
+ debug.repair.enabled && debug.repair("editor and store texts diverged %o", {
361
+ editorText: debugTextOf(editor.getSnapshot().context.value),
362
+ remoteText: debugTextOf(remoteValue)
363
+ });
364
+ const pending = pendingRepairs.get(editor);
365
+ if (pending && pending.signature === first.signature)
366
+ return;
367
+ cancelPendingRepair(editor);
368
+ const timer = setTimeout(() => {
369
+ if (pendingRepairs.delete(editor), unflushedEdits.get(editor)) {
370
+ applySync({
371
+ editor,
372
+ getRemoteValue
373
+ });
374
+ return;
375
+ }
376
+ const latestRemote = getRemoteValue();
377
+ if (!latestRemote)
378
+ return;
379
+ const second = computeRepair(editor, latestRemote);
380
+ if (second.convertible && second.patches.length === 0)
381
+ return;
382
+ if (second.signature !== first.signature) {
383
+ applySync({
384
+ editor,
385
+ getRemoteValue
386
+ });
387
+ return;
388
+ }
389
+ if (!second.convertible) {
390
+ debug.repair("escalating to whole-value sync (unconvertible diff)"), editor.send({
391
+ type: "update value",
392
+ value: latestRemote
393
+ });
394
+ return;
395
+ }
396
+ const snapshot = editor.getSnapshot().context.value;
397
+ debug.repair("applying confirmed repair patches %o", second.patches), editor.send({
348
398
  type: "patches",
349
- patches,
399
+ patches: second.patches,
350
400
  snapshot
351
401
  });
352
402
  const valueAfterPatches = editor.getSnapshot().context.value;
353
- diffValue(valueAfterPatches, remoteValue).length > 0 && (syncDebug("applySync:escalate-update-value", () => ({
403
+ diffValue(valueAfterPatches, latestRemote).length > 0 && (debug.repair.enabled && debug.repair("escalating to whole-value sync %o", {
354
404
  editorText: debugTextOf(valueAfterPatches),
355
- remoteText: debugTextOf(remoteValue)
356
- })), editor.send({
405
+ remoteText: debugTextOf(latestRemote)
406
+ }), editor.send({
357
407
  type: "update value",
358
- value: remoteValue
408
+ value: latestRemote
359
409
  }));
360
- }
410
+ }, REPAIR_CONFIRM_DELAY);
411
+ pendingRepairs.set(editor, {
412
+ signature: first.signature,
413
+ timer
414
+ });
361
415
  }
362
416
  const listenToEditor = fromCallback(({
363
417
  sendBack,
364
418
  input
365
419
  }) => {
366
420
  const patchSubscription = input.editor.on("patch", () => {
367
- sendBack({
421
+ unflushedEdits.set(input.editor, !0), sendBack({
368
422
  type: "patch emitted"
369
423
  });
370
424
  }), mutationSubscription = input.editor.on("mutation", (event) => {
371
- syncDebug("event:mutation-flushed", () => ({
425
+ unflushedEdits.set(input.editor, !1), debug.mutation.enabled && debug.mutation("flushed %o", {
372
426
  flushText: debugTextOf(event.value),
373
427
  snapshotText: debugTextOf(input.editor.getSnapshot().context.value)
374
- })), sendBack({
428
+ }), sendBack({
375
429
  type: "mutation flushed",
376
430
  value: event.value,
377
431
  patches: event.patches
@@ -427,9 +481,7 @@ const listenToEditor = fromCallback(({
427
481
  }) => {
428
482
  if (event.type !== "remote patches received")
429
483
  return;
430
- syncDebug("apply-remote-patches", () => ({
431
- patches: event.patches
432
- }));
484
+ debug.remote("applying remote patches %o", event.patches);
433
485
  const snapshot = context.editor.getSnapshot().context.value, remoteValue = context.getRemoteValue(), patches = (remoteValue ? toEngineSafePatches(event.patches, remoteValue) : event.patches).filter((patch) => canApplyToValue(patch, snapshot));
434
486
  patches.length !== 0 && context.editor.send({
435
487
  type: "patches",
@@ -650,15 +702,11 @@ function ValueSyncPlugin(props) {
650
702
  if (pushPatches && event.patches.length > 0)
651
703
  try {
652
704
  const mergeable = toMergeableMarkDefsPatches(event.patches, context.getRemoteValue);
653
- syncDebug("push-patches", () => ({
654
- patches: mergeable
655
- })), pushPatches(mergeable);
705
+ debug.push("pushing patches %o", mergeable), pushPatches(mergeable);
656
706
  return;
657
707
  } catch {
658
708
  }
659
- syncDebug("push-whole-value", () => ({
660
- text: debugTextOf(event.value ?? context.editor.getSnapshot().context.value)
661
- })), pushValue(event.value ?? context.editor.getSnapshot().context.value);
709
+ debug.push.enabled && debug.push("pushing whole value %s", debugTextOf(event.value ?? context.editor.getSnapshot().context.value)), pushValue(event.value ?? context.editor.getSnapshot().context.value);
662
710
  }
663
711
  }
664
712
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/plugin.sdk-value.tsx"],"sourcesContent":["import {\n useEditor,\n type Editor,\n type PortableTextBlock,\n type Patch as PtePatch,\n} from '@portabletext/editor'\nimport type {\n JSONValue,\n Path,\n PathSegment,\n InsertPatch as PteInsertPatch,\n} from '@portabletext/patches'\nimport {diffValue, type SanityPatchOperations} from '@sanity/diff-patch'\nimport {\n parsePath,\n type ExprNode,\n type PathNode,\n type SegmentNode,\n type ThisNode,\n} from '@sanity/json-match'\nimport {\n editDocument,\n getDocumentState,\n subscribeDocumentEvents,\n useApplyDocumentActions,\n useEditDocument,\n useSanityInstance,\n type DocumentHandle,\n type EditDocumentAction,\n} from '@sanity/sdk-react'\nimport {useActorRef} from '@xstate/react'\nimport {useCallback} from 'react'\nimport {fromCallback, setup, type AnyEventObject} from 'xstate'\n\ntype InsertPatch = Required<Pick<SanityPatchOperations, 'insert'>>\n\nconst ARRAYIFY_ERROR_MESSAGE =\n 'Unexpected path format from diffValue output. Please report this issue.'\n\nfunction* getSegments(\n node: PathNode,\n): Generator<Exclude<SegmentNode, ThisNode>> {\n if (node.base) {\n yield* getSegments(node.base)\n }\n if (node.segment.type !== 'This') {\n yield node.segment\n }\n}\n\nfunction isKeyPath(node: ExprNode): node is PathNode {\n if (node.type !== 'Path') {\n return false\n }\n if (node.base) {\n return false\n }\n if (node.recursive) {\n return false\n }\n if (node.segment.type !== 'Identifier') {\n return false\n }\n return node.segment.name === '_key'\n}\n\nexport function arrayifyPath(pathExpr: string): Path {\n const node = parsePath(pathExpr)\n if (!node) {\n return []\n }\n if (node.type !== 'Path') {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n\n return Array.from(getSegments(node)).map((segment): PathSegment => {\n if (segment.type === 'Identifier') {\n return segment.name\n }\n if (segment.type !== 'Subscript') {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n if (segment.elements.length !== 1) {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n\n const [element] = segment.elements\n if (element.type === 'Number') {\n return element.value\n }\n\n if (element.type !== 'Comparison') {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n if (element.operator !== '==') {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n const keyPathNode = [element.left, element.right].find(isKeyPath)\n if (!keyPathNode) {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n const other = element.left === keyPathNode ? element.right : element.left\n if (other.type !== 'String') {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n return {_key: other.value}\n })\n}\n\nexport function convertPatches(patches: SanityPatchOperations[]): PtePatch[] {\n return patches.flatMap((p) => {\n return Object.entries(p).flatMap(([type, values]): PtePatch[] => {\n const origin = 'remote'\n\n switch (type) {\n case 'set':\n case 'setIfMissing':\n case 'diffMatchPatch':\n case 'inc':\n case 'dec': {\n return Object.entries(values).map(\n ([pathExpr, value]) =>\n ({type, value, origin, path: arrayifyPath(pathExpr)}) as PtePatch,\n )\n }\n case 'unset': {\n if (!Array.isArray(values)) {\n return []\n }\n return values.map(arrayifyPath).map((path) => ({type, origin, path}))\n }\n case 'insert': {\n const {items, ...rest} = values as InsertPatch['insert']\n type InsertPosition = PteInsertPatch['position']\n const position = Object.keys(rest).at(0) as InsertPosition | undefined\n\n if (!position) {\n return []\n }\n const pathExpr = (rest as {[K in InsertPosition]: string})[position]\n const insertPatch: PteInsertPatch = {\n type,\n origin,\n position,\n path: arrayifyPath(pathExpr),\n items: items as JSONValue[],\n }\n\n return [insertPatch]\n }\n\n default: {\n return []\n }\n }\n })\n })\n}\n\nconst STRINGIFY_ERROR_MESSAGE =\n 'Unable to convert an editor patch path to a Sanity path expression.'\n\n/**\n * Converts a Portable Text Editor patch path (an array of segments) into a\n * Sanity json-match path expression. The inverse of `arrayifyPath`.\n *\n * @internal\n */\nexport function stringifyPatchPath(path: Path): string {\n let result = ''\n for (const segment of path) {\n if (typeof segment === 'string') {\n result = result === '' ? segment : `${result}.${segment}`\n } else if (typeof segment === 'number') {\n result = `${result}[${segment}]`\n } else if (\n typeof segment === 'object' &&\n segment !== null &&\n '_key' in segment\n ) {\n result = `${result}[_key==\"${segment._key}\"]`\n } else {\n throw new Error(STRINGIFY_ERROR_MESSAGE)\n }\n }\n return result\n}\n\nfunction prefixPathExpression(prefix: string, expression: string): string {\n if (expression === '') {\n return prefix\n }\n return expression.startsWith('[')\n ? `${prefix}${expression}`\n : `${prefix}.${expression}`\n}\n\n/**\n * `SanityPatchOperations` from `@sanity/diff-patch` only covers the\n * operations `diffValue` emits; the editor can additionally produce these.\n */\ntype SanityPatchOperationsWithExtras = SanityPatchOperations & {\n setIfMissing?: {[path: string]: unknown}\n inc?: {[path: string]: number}\n dec?: {[path: string]: number}\n}\n\n/**\n * Converts Portable Text Editor patches into Sanity patch operations rooted\n * at the given document field path. Throws if a patch cannot be converted;\n * callers should fall back to pushing the whole value.\n *\n * @internal\n */\nexport function convertPatchesToSanity(\n patches: PtePatch[],\n options: {prefix: string},\n): SanityPatchOperationsWithExtras[] {\n return patches.map((patch): SanityPatchOperationsWithExtras => {\n const pathExpression = prefixPathExpression(\n options.prefix,\n stringifyPatchPath(patch.path),\n )\n\n switch (patch.type) {\n case 'set':\n return {set: {[pathExpression]: patch.value}}\n case 'setIfMissing':\n return {setIfMissing: {[pathExpression]: patch.value}}\n case 'unset':\n // The editor unsets the whole field when it becomes empty. Write an\n // empty array instead: unsetting the field would leave other clients\n // unable to reconcile against it (their remote value disappears).\n if (patch.path.length === 0) {\n return {set: {[pathExpression]: []}}\n }\n return {unset: [pathExpression]}\n case 'diffMatchPatch':\n return {diffMatchPatch: {[pathExpression]: patch.value}}\n case 'inc':\n return {inc: {[pathExpression]: patch.value as number}}\n case 'dec':\n return {dec: {[pathExpression]: patch.value as number}}\n case 'insert':\n return {\n insert: {\n [patch.position]: pathExpression,\n items: patch.items,\n } as SanityPatchOperations['insert'],\n }\n default:\n throw new Error(STRINGIFY_ERROR_MESSAGE)\n }\n })\n}\n\nfunction segmentsEqual(a: PathSegment, b: PathSegment): boolean {\n if (typeof a === 'string' || typeof a === 'number') {\n return a === b\n }\n if (typeof b === 'string' || typeof b === 'number') {\n return false\n }\n if (Array.isArray(a) || Array.isArray(b)) {\n return false\n }\n return a._key === b._key\n}\n\nfunction pathsEqual(a: Path, b: Path): boolean {\n return (\n a.length === b.length &&\n a.every((segment, index) => segmentsEqual(segment, b[index]))\n )\n}\n\n/**\n * The editor engine can only resolve keyed/indexed segments against the\n * root block array and (possibly nested) `children` arrays. Operations\n * that address items of any other array, e.g. a block's `markDefs` or a\n * span's `marks`, misapply. When a patch path enters such a sidecar\n * array, this returns the path of the array itself so callers can fall\n * back to replacing the whole property; returns `null` for paths the\n * engine can apply.\n *\n * @internal\n */\nexport function findSidecarArrayPath(path: Path): Path | null {\n // a keyed/numeric segment is only resolvable first (root block array)\n // or directly after a `children` property\n let expectNode = true\n for (let index = 0; index < path.length; index++) {\n const segment = path[index]\n if (typeof segment === 'string') {\n expectNode = segment === 'children'\n } else {\n if (!expectNode) {\n return path.slice(0, index)\n }\n expectNode = false\n }\n }\n return null\n}\n\nfunction getValueAtPath(value: JSONValue, path: Path): JSONValue | undefined {\n let current: JSONValue | undefined = value\n for (const segment of path) {\n if (current === null || current === undefined) {\n return undefined\n }\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) {\n return undefined\n }\n current = current[segment < 0 ? current.length + segment : segment]\n } else if (typeof segment === 'string') {\n if (typeof current !== 'object' || Array.isArray(current)) {\n return undefined\n }\n current = (current as {[key: string]: JSONValue})[segment]\n } else if (Array.isArray(segment)) {\n // index tuples address ranges, not single values\n return undefined\n } else {\n if (!Array.isArray(current)) {\n return undefined\n }\n current = current.find(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n !Array.isArray(item) &&\n (item as {_key?: unknown})._key === segment._key,\n )\n }\n }\n return current\n}\n\n/**\n * Converts a target-value diff into patches the editor engine can apply.\n * Patches addressing items inside sidecar arrays are coalesced into whole\n * `set`s (or `unset`s) of the owning property, taken from the target\n * value.\n *\n * @internal\n */\nexport function toEngineSafePatches(\n patches: PtePatch[],\n targetValue: PortableTextBlock[],\n): PtePatch[] {\n const safe: PtePatch[] = []\n const sidecarPaths: Path[] = []\n\n for (const patch of patches) {\n const sidecarPath = findSidecarArrayPath(patch.path)\n if (!sidecarPath) {\n safe.push(patch)\n continue\n }\n if (!sidecarPaths.some((existing) => pathsEqual(existing, sidecarPath))) {\n sidecarPaths.push(sidecarPath)\n }\n }\n\n for (const sidecarPath of sidecarPaths) {\n const value = getValueAtPath(\n targetValue as unknown as JSONValue,\n sidecarPath,\n )\n safe.push(\n value === undefined\n ? {type: 'unset', path: sidecarPath, origin: 'remote'}\n : {type: 'set', path: sidecarPath, value, origin: 'remote'},\n )\n }\n\n return safe\n}\n\n/**\n * The editor writes `markDefs` as whole-array `set`s. Two clients\n * formatting the same block concurrently then overwrite each other's\n * arrays at the server (last writer wins) while both clients' span\n * `marks` references survive, stranding marks without definitions.\n * Outgoing `markDefs` sets are therefore decomposed into item-level\n * operations against the store (server truth): new definitions insert,\n * changed definitions set by key, and removed definitions unset by key,\n * except definitions the store's own spans still reference (a diverged\n * client's normalizer prunes those spuriously; a later, converged flush\n * removes them for real). Item-keyed operations merge at the server\n * instead of overwriting.\n *\n * @internal\n */\nexport function toMergeableMarkDefsPatches(\n patches: PtePatch[],\n getCurrentValue: () => PortableTextBlock[] | null | undefined,\n): PtePatch[] {\n return patches.flatMap((patch): PtePatch[] => {\n if (\n patch.type !== 'set' ||\n patch.path.at(-1) !== 'markDefs' ||\n !Array.isArray(patch.value)\n ) {\n return [patch]\n }\n const currentValue = getCurrentValue()\n if (!currentValue) {\n return [patch]\n }\n const root = currentValue as unknown as JSONValue\n const storeMarkDefs = getValueAtPath(root, patch.path)\n const storeBlock = getValueAtPath(root, patch.path.slice(0, -1))\n if (\n !Array.isArray(storeMarkDefs) ||\n typeof storeBlock !== 'object' ||\n storeBlock === null\n ) {\n return [patch]\n }\n\n const local = patch.value as Array<{_key?: string}>\n const store = storeMarkDefs as Array<{_key?: string}>\n if (local.some((item) => item._key === undefined)) {\n return [patch]\n }\n\n const referencedKeys = new Set(\n (\n (storeBlock as {children?: Array<{marks?: string[]}>}).children ?? []\n ).flatMap((child) => child.marks ?? []),\n )\n const storeByKey = new Map(store.map((item) => [item._key, item]))\n const localKeys = new Set(local.map((item) => item._key))\n const origin = patch.origin\n\n const ops: PtePatch[] = []\n\n const inserted = local.filter((item) => !storeByKey.has(item._key))\n if (inserted.length > 0) {\n ops.push({\n type: 'insert',\n origin,\n position: 'after',\n path: [...patch.path, -1],\n items: inserted as JSONValue[],\n })\n }\n\n for (const item of local) {\n const existing = storeByKey.get(item._key)\n if (existing && JSON.stringify(existing) !== JSON.stringify(item)) {\n ops.push({\n type: 'set',\n origin,\n path: [...patch.path, {_key: item._key as string}],\n value: item as JSONValue,\n })\n }\n }\n\n for (const item of store) {\n if (\n item._key !== undefined &&\n !localKeys.has(item._key) &&\n !referencedKeys.has(item._key)\n ) {\n ops.push({\n type: 'unset',\n origin,\n path: [...patch.path, {_key: item._key}],\n })\n }\n }\n\n return ops\n })\n}\n\n/**\n * Whether a remote patch can resolve against the given editor value.\n * Concurrent edits routinely produce operations addressing nodes another\n * client has already removed or not yet created; sending those into the\n * engine fails loudly (console errors) before being skipped. Callers drop\n * unresolvable patches up front and rely on the follow-up repair sync to\n * converge instead.\n *\n * @internal\n */\nexport function canApplyToValue(\n patch: PtePatch,\n value: PortableTextBlock[] | undefined,\n): boolean {\n if (!value) {\n return true\n }\n const root = value as unknown as JSONValue\n switch (patch.type) {\n // unset needs the node itself; insert needs the sibling at `path`;\n // diffMatchPatch needs the existing string\n case 'unset':\n case 'insert':\n case 'diffMatchPatch':\n return getValueAtPath(root, patch.path) !== undefined\n // set creates its target property, so only the parent must resolve\n case 'set':\n return (\n patch.path.length === 0 ||\n getValueAtPath(root, patch.path.slice(0, -1)) !== undefined\n )\n default:\n return true\n }\n}\n\n/**\n * Scopes document-rooted Sanity patches to the given field path, returning\n * field-relative Portable Text Editor patches. Patches outside the field are\n * dropped. Returns `null` when the field (or an ancestor of it) is replaced\n * wholesale, in which case the caller should fall back to a full value sync.\n * Throws when a path expression cannot be converted.\n *\n * @internal\n */\nexport function scopeRemotePatches(\n patches: SanityPatchOperations[],\n fieldPath: string,\n): PtePatch[] | null {\n const prefix = arrayifyPath(fieldPath)\n const converted = convertPatches(patches)\n const scoped: PtePatch[] = []\n\n for (const patch of converted) {\n const overlap = Math.min(patch.path.length, prefix.length)\n let touchesField = true\n for (let index = 0; index < overlap; index++) {\n if (!segmentsEqual(patch.path[index], prefix[index])) {\n touchesField = false\n break\n }\n }\n if (!touchesField) {\n continue\n }\n if (patch.path.length <= prefix.length) {\n // the patch targets the field itself or an ancestor of it, which\n // cannot be expressed as a field-relative operation\n return null\n }\n scoped.push({...patch, path: patch.path.slice(prefix.length)})\n }\n\n return scoped\n}\n\n// Sync diagnostics, disabled unless `globalThis.__PTE_SYNC_DEBUG = true`\n// is set before load. Callers pass a thunk so detail computation is free\n// when the flag is off.\nfunction syncDebugEnabled(): boolean {\n return (globalThis as {__PTE_SYNC_DEBUG?: boolean}).__PTE_SYNC_DEBUG === true\n}\n\nfunction syncDebug(kind: string, detail: () => Record<string, unknown>) {\n if (syncDebugEnabled()) {\n // biome-ignore lint/suspicious/noConsole: opt-in diagnostics channel\n console.debug(`[pte-sync] ${kind} ${JSON.stringify(detail())}`)\n }\n}\n\nfunction debugTextOf(value: unknown): string {\n if (!Array.isArray(value)) {\n return ''\n }\n return value\n .map((block) =>\n Array.isArray((block as {children?: unknown}).children)\n ? ((block as {children: Array<{text?: string}>}).children ?? [])\n .map((child) => child.text ?? '')\n .join('')\n : '',\n )\n .join('\\n')\n}\n\nfunction applySync({\n editor,\n getRemoteValue,\n}: {\n editor: Editor\n getRemoteValue: () => PortableTextBlock[] | null | undefined\n}) {\n const remoteValue = getRemoteValue()\n\n if (!remoteValue) {\n return\n }\n\n const snapshot = editor.getSnapshot().context.value\n if (syncDebugEnabled()) {\n const editorText = debugTextOf(snapshot)\n const remoteText = debugTextOf(remoteValue)\n if (editorText !== remoteText) {\n syncDebug('applySync:texts-differ', () => ({editorText, remoteText}))\n }\n }\n\n let patches: PtePatch[]\n try {\n patches = toEngineSafePatches(\n convertPatches(diffValue(snapshot, remoteValue)),\n remoteValue,\n )\n } catch {\n // diffValue can emit path shapes the converter does not understand\n // (e.g. array slices when multiple items are dropped). Fall back to\n // the full value sync machinery rather than leaving the editor\n // diverged.\n editor.send({type: 'update value', value: remoteValue})\n return\n }\n\n if (patches.length) {\n syncDebug('applySync:repair-patches', () => ({patches}))\n editor.send({type: 'patches', patches, snapshot})\n\n // Patch application is best-effort: the editor skips operations it\n // cannot resolve against its current tree, and concurrent edits to the\n // same range produce keyed operations whose targets no longer exist\n // locally. When the editor is still diverged after the diff-based\n // repair, escalate to the full value sync machinery, which reconciles\n // arbitrary divergence block by block.\n const valueAfterPatches = editor.getSnapshot().context.value\n if (diffValue(valueAfterPatches, remoteValue).length > 0) {\n syncDebug('applySync:escalate-update-value', () => ({\n editorText: debugTextOf(valueAfterPatches),\n remoteText: debugTextOf(remoteValue),\n }))\n editor.send({type: 'update value', value: remoteValue})\n }\n }\n}\n\nconst listenToEditor = fromCallback<AnyEventObject, {editor: Editor}>(\n ({sendBack, input}) => {\n const patchSubscription = input.editor.on('patch', () => {\n sendBack({type: 'patch emitted'})\n })\n\n const mutationSubscription = input.editor.on('mutation', (event) => {\n syncDebug('event:mutation-flushed', () => ({\n flushText: debugTextOf(event.value),\n snapshotText: debugTextOf(input.editor.getSnapshot().context.value),\n }))\n sendBack({\n type: 'mutation flushed',\n value: event.value,\n patches: event.patches,\n })\n })\n\n return () => {\n patchSubscription.unsubscribe()\n mutationSubscription.unsubscribe()\n }\n },\n)\n\nconst listenToRemote = fromCallback<\n AnyEventObject,\n {onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']}\n>(({sendBack, input}) => {\n return input.onRemoteValueChange(() => {\n sendBack({type: 'remote value changed'})\n })\n})\n\nconst listenToRemotePatches = fromCallback<\n AnyEventObject,\n {onRemotePatches: ValueSyncConfig['onRemotePatches']}\n>(({sendBack, input}) => {\n return input.onRemotePatches?.((patches) => {\n sendBack({type: 'remote patches received', patches})\n })\n})\n\n/**\n * How long the machine must sit in 'idle' (no local keystrokes, no store\n * events) before the one-shot whole-value repair runs. Long enough for the\n * editor's external value snapshot to catch up after the last flush; short\n * enough that residual divergence from concurrent editing heals promptly.\n */\nconst QUIESCENT_REPAIR_DELAY = 500\n\nconst valueSyncMachine = setup({\n types: {\n context: {} as {\n editor: Editor\n getRemoteValue: ValueSyncConfig['getRemoteValue']\n onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']\n onRemotePatches: ValueSyncConfig['onRemotePatches']\n },\n input: {} as {\n editor: Editor\n getRemoteValue: ValueSyncConfig['getRemoteValue']\n onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']\n onRemotePatches: ValueSyncConfig['onRemotePatches']\n },\n events: {} as\n | {type: 'patch emitted'}\n | {\n type: 'mutation flushed'\n value: PortableTextBlock[] | undefined\n patches: PtePatch[]\n }\n | {type: 'remote value changed'}\n | {type: 'remote patches received'; patches: PtePatch[]},\n },\n actions: {\n 'send initial value': ({context}) => {\n context.editor.send({\n type: 'update value',\n value: context.getRemoteValue() ?? [],\n })\n },\n 'push to remote': () => {\n throw new Error('push to remote must be provided via .provide()')\n },\n 'apply sync': ({context}) => {\n applySync({\n editor: context.editor,\n getRemoteValue: context.getRemoteValue,\n })\n },\n 'apply remote patches': ({context, event}) => {\n if (event.type !== 'remote patches received') {\n return\n }\n syncDebug('apply-remote-patches', () => ({patches: event.patches}))\n const snapshot = context.editor.getSnapshot().context.value\n // The store already reflects this transaction, so it can serve as\n // the target for coalescing sidecar-array item operations (which\n // the engine misroutes) into whole-property sets.\n const remoteValue = context.getRemoteValue()\n const coalesced = remoteValue\n ? toEngineSafePatches(event.patches, remoteValue)\n : event.patches\n const patches = coalesced.filter((patch) =>\n canApplyToValue(patch, snapshot),\n )\n if (patches.length === 0) {\n return\n }\n context.editor.send({type: 'patches', patches, snapshot})\n },\n },\n actors: {\n 'listen to editor': listenToEditor,\n 'listen to remote': listenToRemote,\n 'listen to remote patches': listenToRemotePatches,\n },\n}).createMachine({\n id: 'value sync',\n context: ({input}) => ({\n editor: input.editor,\n getRemoteValue: input.getRemoteValue,\n onRemoteValueChange: input.onRemoteValueChange,\n onRemotePatches: input.onRemotePatches,\n }),\n entry: ['send initial value'],\n invoke: [\n {\n src: 'listen to editor',\n input: ({context}) => ({editor: context.editor}),\n },\n {\n src: 'listen to remote',\n input: ({context}) => ({\n onRemoteValueChange: context.onRemoteValueChange,\n }),\n },\n {\n src: 'listen to remote patches',\n input: ({context}) => ({\n onRemotePatches: context.onRemotePatches,\n }),\n },\n ],\n // Two invariants, learned the hard way:\n //\n // 1. EVERY 'mutation flushed' event must be pushed, in every state. The\n // editor emits mutation events in bursts (one per input batch, e.g.\n // each backspace of a quick delete), and any state without a handler\n // silently drops the flush. A dropped flush permanently diverges the\n // store from the editor, and the whole-value repair then \"heals\" the\n // editor backwards, resurrecting deleted text.\n // 2. The whole-value repair must only run when no local edits can be in\n // flight (quiescent 'idle'). Running it mid-typing diffs the editor\n // against a store that lags the user's keystrokes and stomps them.\n //\n // Operational patches from other clients still apply immediately in\n // every state; the editor merges them with in-flight local changes.\n initial: 'idle',\n states: {\n 'idle': {\n // One-shot repair after a quiet period. Covers divergence left by\n // best-effort patch application while local edits were in flight\n // (those states never repair; see below) when no further store\n // event arrives to trigger the on-change repair.\n after: {\n [QUIESCENT_REPAIR_DELAY]: {\n actions: ['apply sync'],\n },\n },\n on: {\n 'patch emitted': {\n target: 'local write',\n },\n // Mutation events arrive in bursts (one per input batch), so a\n // flush can land after a sibling flush already advanced the state.\n 'mutation flushed': {\n target: 'pushing to remote',\n actions: ['push to remote'],\n },\n 'remote value changed': {\n actions: ['apply sync'],\n },\n // No immediate repair here: every remote patch batch also updates\n // the store value, so the accompanying 'remote value changed'\n // event runs the whole-value repair right after.\n 'remote patches received': {\n actions: ['apply remote patches'],\n },\n },\n },\n 'local write': {\n on: {\n 'patch emitted': {},\n 'mutation flushed': {\n target: 'pushing to remote',\n actions: ['push to remote'],\n },\n 'remote value changed': {\n target: 'pending sync',\n },\n 'remote patches received': {\n target: 'pending sync',\n actions: ['apply remote patches'],\n },\n },\n },\n 'pushing to remote': {\n on: {\n 'patch emitted': {\n target: 'local write',\n },\n 'mutation flushed': {\n actions: ['push to remote'],\n },\n // No repair on the push acknowledgment: the editor snapshot can\n // lag the live document while the user keeps typing, so a diff\n // against the store here resurrects deleted text and duplicates\n // in-flight keystrokes. Once truly idle, the store change or the\n // quiescent delay runs the repair with a caught-up snapshot.\n 'remote value changed': {\n target: 'idle',\n },\n 'remote patches received': {\n actions: ['apply remote patches'],\n },\n },\n },\n 'pending sync': {\n on: {\n 'patch emitted': {},\n 'mutation flushed': {\n target: 'pushing to remote',\n actions: ['push to remote'],\n },\n 'remote value changed': {},\n 'remote patches received': {\n actions: ['apply remote patches'],\n },\n },\n },\n },\n})\n\ninterface SDKValuePluginProps extends DocumentHandle {\n path: string\n}\n\n/**\n * The shape of the `remote-patches` document event emitted by\n * `@sanity/sdk` >= 2.17. Declared structurally so the plugin stays\n * compatible with older SDK typings until its dependency is bumped.\n */\ntype RemotePatchesDocumentEvent = {\n type: 'remote-patches'\n documentId: string\n transactionId: string\n timestamp: string\n previousRev?: string\n patches: SanityPatchOperations[]\n origin: 'local' | 'remote'\n}\n\nfunction isRemotePatchesEvent(event: {\n type: string\n}): event is RemotePatchesDocumentEvent {\n return event.type === 'remote-patches'\n}\n\nfunction getPublishedDocumentId(id: string): string {\n if (id.startsWith('drafts.')) {\n return id.slice('drafts.'.length)\n }\n if (id.startsWith('versions.')) {\n return id.split('.').slice(2).join('.')\n }\n return id\n}\n\n/**\n * @public\n */\nexport function SDKValuePlugin(props: SDKValuePluginProps) {\n const {documentId, documentType, path} = props\n const setSdkValue = useEditDocument(props)\n const instance = useSanityInstance(props)\n const applyActions = useApplyDocumentActions()\n\n const handle = {documentId, documentType, path}\n const {getCurrent, subscribe} = getDocumentState<PortableTextBlock[]>(\n instance,\n handle,\n )\n\n const onRemotePatches = useCallback(\n (callback: (patches: PtePatch[]) => void) => {\n return subscribeDocumentEvents(instance, {\n eventHandler: (event) => {\n // widen before narrowing: `remote-patches` is not part of the\n // `DocumentEvent` union in older SDK typings\n const candidate: {type: string} = event\n if (!isRemotePatchesEvent(candidate)) {\n return\n }\n // our own transactions are already reflected in the editor\n if (candidate.origin !== 'remote') {\n return\n }\n if (\n getPublishedDocumentId(candidate.documentId) !==\n getPublishedDocumentId(documentId)\n ) {\n return\n }\n\n let patches: PtePatch[] | null\n try {\n patches = scopeRemotePatches(candidate.patches, path)\n } catch {\n // unconvertible patch shapes fall back to the whole-value sync\n // driven by `onRemoteValueChange`\n return\n }\n if (patches && patches.length > 0) {\n callback(patches)\n }\n },\n })\n },\n [instance, documentId, path],\n )\n\n const pushPatches = useCallback(\n (patches: PtePatch[]) => {\n const sanityPatches = convertPatchesToSanity(patches, {prefix: path})\n // `preserveOperations` ships in @sanity/sdk >= 2.17; the intersection\n // type keeps the plugin compatible with older SDK typings\n const action: EditDocumentAction & {preserveOperations?: boolean} = {\n ...editDocument(\n {documentId, documentType},\n sanityPatches as Parameters<typeof editDocument>[1],\n ),\n preserveOperations: true,\n }\n applyActions(action)\n },\n [applyActions, documentId, documentType, path],\n )\n\n return (\n <ValueSyncPlugin\n getRemoteValue={getCurrent}\n pushValue={setSdkValue}\n onRemoteValueChange={subscribe}\n onRemotePatches={onRemotePatches}\n pushPatches={pushPatches}\n />\n )\n}\n\n/**\n * @internal\n */\ntype ValueSyncConfig = {\n getRemoteValue: () => PortableTextBlock[] | null | undefined\n pushValue: (value: PortableTextBlock[]) => void\n onRemoteValueChange: (callback: () => void) => () => void\n /**\n * Optional patch channel. When provided, operational patches from other\n * clients are applied directly to the editor (in every state) instead of\n * waiting for a whole-value diff, and local editor patches are pushed\n * through `pushPatches`. The whole-value sync remains as a fallback for\n * anything the patch channel cannot express.\n */\n onRemotePatches?: (\n callback: (patches: PtePatch[]) => void,\n ) => (() => void) | undefined\n /**\n * Pushes the editor's own operational patches to the remote store. May\n * throw when a patch cannot be converted, in which case the plugin falls\n * back to pushing the whole value.\n */\n pushPatches?: (patches: PtePatch[]) => void\n}\n\n/**\n * NOTE: You are probably looking for SDKValuePlugin instead of this.\n * This is a lower-level plugin that only handles syncing the value\n * between the editor and a remote source. It does not know anything\n * about Sanity documents or how to fetch/update them.\n *\n * May be removed in the future, do not rely on this directly.\n *\n * @internal\n */\nexport function ValueSyncPlugin(props: ValueSyncConfig) {\n const {\n getRemoteValue,\n pushValue,\n onRemoteValueChange,\n onRemotePatches,\n pushPatches,\n } = props\n const editor = useEditor()\n\n useActorRef(\n valueSyncMachine.provide({\n actions: {\n 'push to remote': ({context, event}) => {\n if (event.type !== 'mutation flushed') {\n return\n }\n\n if (pushPatches && event.patches.length > 0) {\n try {\n const mergeable = toMergeableMarkDefsPatches(\n event.patches,\n context.getRemoteValue,\n )\n syncDebug('push-patches', () => ({patches: mergeable}))\n pushPatches(mergeable)\n return\n } catch {\n // fall back to pushing the whole value below\n }\n }\n\n syncDebug('push-whole-value', () => ({\n text: debugTextOf(\n event.value ?? context.editor.getSnapshot().context.value,\n ),\n }))\n pushValue(event.value ?? context.editor.getSnapshot().context.value)\n },\n },\n }),\n {\n input: {\n editor,\n getRemoteValue,\n onRemoteValueChange,\n onRemotePatches,\n },\n },\n )\n\n return null\n}\n"],"names":["ARRAYIFY_ERROR_MESSAGE","getSegments","node","base","segment","type","isKeyPath","recursive","name","arrayifyPath","pathExpr","parsePath","Error","Array","from","map","elements","length","element","value","operator","keyPathNode","left","right","find","other","_key","convertPatches","patches","flatMap","p","Object","entries","values","origin","path","isArray","items","rest","position","keys","at","STRINGIFY_ERROR_MESSAGE","stringifyPatchPath","result","prefixPathExpression","prefix","expression","startsWith","convertPatchesToSanity","options","patch","pathExpression","set","setIfMissing","unset","diffMatchPatch","inc","dec","insert","segmentsEqual","a","b","pathsEqual","every","index","findSidecarArrayPath","expectNode","slice","getValueAtPath","current","item","toEngineSafePatches","targetValue","safe","sidecarPaths","sidecarPath","push","some","existing","undefined","toMergeableMarkDefsPatches","getCurrentValue","currentValue","root","storeMarkDefs","storeBlock","local","store","referencedKeys","Set","children","child","marks","storeByKey","Map","localKeys","ops","inserted","filter","has","get","JSON","stringify","canApplyToValue","scopeRemotePatches","fieldPath","converted","scoped","overlap","Math","min","touchesField","syncDebugEnabled","globalThis","__PTE_SYNC_DEBUG","syncDebug","kind","detail","console","debug","debugTextOf","block","text","join","applySync","editor","getRemoteValue","remoteValue","snapshot","getSnapshot","context","editorText","remoteText","diffValue","send","valueAfterPatches","listenToEditor","fromCallback","sendBack","input","patchSubscription","on","mutationSubscription","event","flushText","snapshotText","unsubscribe","listenToRemote","onRemoteValueChange","listenToRemotePatches","onRemotePatches","QUIESCENT_REPAIR_DELAY","valueSyncMachine","setup","types","events","actions","send initial value","push to remote","apply sync","apply remote patches","actors","createMachine","id","entry","invoke","src","initial","states","after","target","isRemotePatchesEvent","getPublishedDocumentId","split","SDKValuePlugin","props","$","_c","documentId","documentType","setSdkValue","useEditDocument","instance","useSanityInstance","applyActions","useApplyDocumentActions","t0","getDocumentState","getCurrent","subscribe","t1","callback","subscribeDocumentEvents","eventHandler","candidate","t2","patches_0","sanityPatches","action","editDocument","preserveOperations","pushPatches","t3","ValueSyncPlugin","pushValue","useEditor","provide","mergeable","useActorRef"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/debug.ts","../src/plugin.sdk-value.tsx"],"sourcesContent":["import rawDebug from 'debug'\n\n// Keep in sync with `packages/editor/src/internal-utils/debug.ts`: sharing\n// the `pte:` root lets `localStorage.debug = 'pte:*'` interleave this\n// plugin's sync traces with the editor's own output on one timeline.\nconst rootName = 'pte:plugin-sdk-value:'\n\nfunction createDebugger(name: string): rawDebug.Debugger {\n const namespace = `${rootName}${name}`\n if (rawDebug && rawDebug.enabled(namespace)) {\n return rawDebug(namespace)\n }\n return rawDebug(rootName)\n}\n\nexport const debug = {\n mutation: createDebugger('mutation'),\n push: createDebugger('push'),\n remote: createDebugger('remote'),\n repair: createDebugger('repair'),\n}\n","import {\n useEditor,\n type Editor,\n type PortableTextBlock,\n type Patch as PtePatch,\n} from '@portabletext/editor'\nimport type {\n JSONValue,\n Path,\n PathSegment,\n InsertPatch as PteInsertPatch,\n} from '@portabletext/patches'\nimport {diffValue, type SanityPatchOperations} from '@sanity/diff-patch'\nimport {\n parsePath,\n type ExprNode,\n type PathNode,\n type SegmentNode,\n type ThisNode,\n} from '@sanity/json-match'\nimport {\n editDocument,\n getDocumentState,\n subscribeDocumentEvents,\n useApplyDocumentActions,\n useEditDocument,\n useSanityInstance,\n type DocumentHandle,\n type EditDocumentAction,\n} from '@sanity/sdk-react'\nimport {useActorRef} from '@xstate/react'\nimport {useCallback} from 'react'\nimport {fromCallback, setup, type AnyEventObject} from 'xstate'\nimport {debug} from './debug'\n\ntype InsertPatch = Required<Pick<SanityPatchOperations, 'insert'>>\n\nconst ARRAYIFY_ERROR_MESSAGE =\n 'Unexpected path format from diffValue output. Please report this issue.'\n\nfunction* getSegments(\n node: PathNode,\n): Generator<Exclude<SegmentNode, ThisNode>> {\n if (node.base) {\n yield* getSegments(node.base)\n }\n if (node.segment.type !== 'This') {\n yield node.segment\n }\n}\n\nfunction isKeyPath(node: ExprNode): node is PathNode {\n if (node.type !== 'Path') {\n return false\n }\n if (node.base) {\n return false\n }\n if (node.recursive) {\n return false\n }\n if (node.segment.type !== 'Identifier') {\n return false\n }\n return node.segment.name === '_key'\n}\n\nexport function arrayifyPath(pathExpr: string): Path {\n const node = parsePath(pathExpr)\n if (!node) {\n return []\n }\n if (node.type !== 'Path') {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n\n return Array.from(getSegments(node)).map((segment): PathSegment => {\n if (segment.type === 'Identifier') {\n return segment.name\n }\n if (segment.type !== 'Subscript') {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n if (segment.elements.length !== 1) {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n\n const [element] = segment.elements\n if (element.type === 'Number') {\n return element.value\n }\n\n if (element.type !== 'Comparison') {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n if (element.operator !== '==') {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n const keyPathNode = [element.left, element.right].find(isKeyPath)\n if (!keyPathNode) {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n const other = element.left === keyPathNode ? element.right : element.left\n if (other.type !== 'String') {\n throw new Error(ARRAYIFY_ERROR_MESSAGE)\n }\n return {_key: other.value}\n })\n}\n\nexport function convertPatches(patches: SanityPatchOperations[]): PtePatch[] {\n return patches.flatMap((p) => {\n return Object.entries(p).flatMap(([type, values]): PtePatch[] => {\n const origin = 'remote'\n\n switch (type) {\n case 'set':\n case 'setIfMissing':\n case 'diffMatchPatch':\n case 'inc':\n case 'dec': {\n return Object.entries(values).map(\n ([pathExpr, value]) =>\n ({type, value, origin, path: arrayifyPath(pathExpr)}) as PtePatch,\n )\n }\n case 'unset': {\n if (!Array.isArray(values)) {\n return []\n }\n return values.map(arrayifyPath).map((path) => ({type, origin, path}))\n }\n case 'insert': {\n const {items, ...rest} = values as InsertPatch['insert']\n type InsertPosition = PteInsertPatch['position']\n const position = Object.keys(rest).at(0) as InsertPosition | undefined\n\n if (!position) {\n return []\n }\n const pathExpr = (rest as {[K in InsertPosition]: string})[position]\n const insertPatch: PteInsertPatch = {\n type,\n origin,\n position,\n path: arrayifyPath(pathExpr),\n items: items as JSONValue[],\n }\n\n return [insertPatch]\n }\n\n default: {\n return []\n }\n }\n })\n })\n}\n\nconst STRINGIFY_ERROR_MESSAGE =\n 'Unable to convert an editor patch path to a Sanity path expression.'\n\n/**\n * Converts a Portable Text Editor patch path (an array of segments) into a\n * Sanity json-match path expression. The inverse of `arrayifyPath`.\n *\n * @internal\n */\nexport function stringifyPatchPath(path: Path): string {\n let result = ''\n for (const segment of path) {\n if (typeof segment === 'string') {\n result = result === '' ? segment : `${result}.${segment}`\n } else if (typeof segment === 'number') {\n result = `${result}[${segment}]`\n } else if (\n typeof segment === 'object' &&\n segment !== null &&\n '_key' in segment\n ) {\n result = `${result}[_key==\"${segment._key}\"]`\n } else {\n throw new Error(STRINGIFY_ERROR_MESSAGE)\n }\n }\n return result\n}\n\nfunction prefixPathExpression(prefix: string, expression: string): string {\n if (expression === '') {\n return prefix\n }\n return expression.startsWith('[')\n ? `${prefix}${expression}`\n : `${prefix}.${expression}`\n}\n\n/**\n * `SanityPatchOperations` from `@sanity/diff-patch` only covers the\n * operations `diffValue` emits; the editor can additionally produce these.\n */\ntype SanityPatchOperationsWithExtras = SanityPatchOperations & {\n setIfMissing?: {[path: string]: unknown}\n inc?: {[path: string]: number}\n dec?: {[path: string]: number}\n}\n\n/**\n * Converts Portable Text Editor patches into Sanity patch operations rooted\n * at the given document field path. Throws if a patch cannot be converted;\n * callers should fall back to pushing the whole value.\n *\n * @internal\n */\nexport function convertPatchesToSanity(\n patches: PtePatch[],\n options: {prefix: string},\n): SanityPatchOperationsWithExtras[] {\n return patches.map((patch): SanityPatchOperationsWithExtras => {\n const pathExpression = prefixPathExpression(\n options.prefix,\n stringifyPatchPath(patch.path),\n )\n\n switch (patch.type) {\n case 'set':\n return {set: {[pathExpression]: patch.value}}\n case 'setIfMissing':\n return {setIfMissing: {[pathExpression]: patch.value}}\n case 'unset':\n // The editor unsets the whole field when it becomes empty. Write an\n // empty array instead: unsetting the field would leave other clients\n // unable to reconcile against it (their remote value disappears).\n if (patch.path.length === 0) {\n return {set: {[pathExpression]: []}}\n }\n return {unset: [pathExpression]}\n case 'diffMatchPatch':\n return {diffMatchPatch: {[pathExpression]: patch.value}}\n case 'inc':\n return {inc: {[pathExpression]: patch.value as number}}\n case 'dec':\n return {dec: {[pathExpression]: patch.value as number}}\n case 'insert':\n return {\n insert: {\n [patch.position]: pathExpression,\n items: patch.items,\n } as SanityPatchOperations['insert'],\n }\n default:\n throw new Error(STRINGIFY_ERROR_MESSAGE)\n }\n })\n}\n\nfunction segmentsEqual(a: PathSegment, b: PathSegment): boolean {\n if (typeof a === 'string' || typeof a === 'number') {\n return a === b\n }\n if (typeof b === 'string' || typeof b === 'number') {\n return false\n }\n if (Array.isArray(a) || Array.isArray(b)) {\n return false\n }\n return a._key === b._key\n}\n\nfunction pathsEqual(a: Path, b: Path): boolean {\n return (\n a.length === b.length &&\n a.every((segment, index) => segmentsEqual(segment, b[index]))\n )\n}\n\n/**\n * The editor engine can only resolve keyed/indexed segments against the\n * root block array and (possibly nested) `children` arrays. Operations\n * that address items of any other array, e.g. a block's `markDefs` or a\n * span's `marks`, misapply. When a patch path enters such a sidecar\n * array, this returns the path of the array itself so callers can fall\n * back to replacing the whole property; returns `null` for paths the\n * engine can apply.\n *\n * @internal\n */\nexport function findSidecarArrayPath(path: Path): Path | null {\n // a keyed/numeric segment is only resolvable first (root block array)\n // or directly after a `children` property\n let expectNode = true\n for (let index = 0; index < path.length; index++) {\n const segment = path[index]\n if (typeof segment === 'string') {\n expectNode = segment === 'children'\n } else {\n if (!expectNode) {\n return path.slice(0, index)\n }\n expectNode = false\n }\n }\n return null\n}\n\nfunction getValueAtPath(value: JSONValue, path: Path): JSONValue | undefined {\n let current: JSONValue | undefined = value\n for (const segment of path) {\n if (current === null || current === undefined) {\n return undefined\n }\n if (typeof segment === 'number') {\n if (!Array.isArray(current)) {\n return undefined\n }\n current = current[segment < 0 ? current.length + segment : segment]\n } else if (typeof segment === 'string') {\n if (typeof current !== 'object' || Array.isArray(current)) {\n return undefined\n }\n current = (current as {[key: string]: JSONValue})[segment]\n } else if (Array.isArray(segment)) {\n // index tuples address ranges, not single values\n return undefined\n } else {\n if (!Array.isArray(current)) {\n return undefined\n }\n current = current.find(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n !Array.isArray(item) &&\n (item as {_key?: unknown})._key === segment._key,\n )\n }\n }\n return current\n}\n\n/**\n * Converts a target-value diff into patches the editor engine can apply.\n * Patches addressing items inside sidecar arrays are coalesced into whole\n * `set`s (or `unset`s) of the owning property, taken from the target\n * value.\n *\n * @internal\n */\nexport function toEngineSafePatches(\n patches: PtePatch[],\n targetValue: PortableTextBlock[],\n): PtePatch[] {\n const safe: PtePatch[] = []\n const sidecarPaths: Path[] = []\n\n for (const patch of patches) {\n const sidecarPath = findSidecarArrayPath(patch.path)\n if (!sidecarPath) {\n safe.push(patch)\n continue\n }\n if (!sidecarPaths.some((existing) => pathsEqual(existing, sidecarPath))) {\n sidecarPaths.push(sidecarPath)\n }\n }\n\n for (const sidecarPath of sidecarPaths) {\n const value = getValueAtPath(\n targetValue as unknown as JSONValue,\n sidecarPath,\n )\n safe.push(\n value === undefined\n ? {type: 'unset', path: sidecarPath, origin: 'remote'}\n : {type: 'set', path: sidecarPath, value, origin: 'remote'},\n )\n }\n\n return safe\n}\n\n/**\n * The editor writes `markDefs` as whole-array `set`s. Two clients\n * formatting the same block concurrently then overwrite each other's\n * arrays at the server (last writer wins) while both clients' span\n * `marks` references survive, stranding marks without definitions.\n * Outgoing `markDefs` sets are therefore decomposed into item-level\n * operations against the store (server truth): new definitions insert,\n * changed definitions set by key, and removed definitions unset by key,\n * except definitions the store's own spans still reference (a diverged\n * client's normalizer prunes those spuriously; a later, converged flush\n * removes them for real). Item-keyed operations merge at the server\n * instead of overwriting.\n *\n * @internal\n */\nexport function toMergeableMarkDefsPatches(\n patches: PtePatch[],\n getCurrentValue: () => PortableTextBlock[] | null | undefined,\n): PtePatch[] {\n return patches.flatMap((patch): PtePatch[] => {\n if (\n patch.type !== 'set' ||\n patch.path.at(-1) !== 'markDefs' ||\n !Array.isArray(patch.value)\n ) {\n return [patch]\n }\n const currentValue = getCurrentValue()\n if (!currentValue) {\n return [patch]\n }\n const root = currentValue as unknown as JSONValue\n const storeMarkDefs = getValueAtPath(root, patch.path)\n const storeBlock = getValueAtPath(root, patch.path.slice(0, -1))\n if (\n !Array.isArray(storeMarkDefs) ||\n typeof storeBlock !== 'object' ||\n storeBlock === null\n ) {\n return [patch]\n }\n\n const local = patch.value as Array<{_key?: string}>\n const store = storeMarkDefs as Array<{_key?: string}>\n if (local.some((item) => item._key === undefined)) {\n return [patch]\n }\n\n const referencedKeys = new Set(\n (\n (storeBlock as {children?: Array<{marks?: string[]}>}).children ?? []\n ).flatMap((child) => child.marks ?? []),\n )\n const storeByKey = new Map(store.map((item) => [item._key, item]))\n const localKeys = new Set(local.map((item) => item._key))\n const origin = patch.origin\n\n const ops: PtePatch[] = []\n\n const inserted = local.filter((item) => !storeByKey.has(item._key))\n if (inserted.length > 0) {\n ops.push({\n type: 'insert',\n origin,\n position: 'after',\n path: [...patch.path, -1],\n items: inserted as JSONValue[],\n })\n }\n\n for (const item of local) {\n const existing = storeByKey.get(item._key)\n if (existing && JSON.stringify(existing) !== JSON.stringify(item)) {\n ops.push({\n type: 'set',\n origin,\n path: [...patch.path, {_key: item._key as string}],\n value: item as JSONValue,\n })\n }\n }\n\n for (const item of store) {\n if (\n item._key !== undefined &&\n !localKeys.has(item._key) &&\n !referencedKeys.has(item._key)\n ) {\n ops.push({\n type: 'unset',\n origin,\n path: [...patch.path, {_key: item._key}],\n })\n }\n }\n\n return ops\n })\n}\n\n/**\n * Whether a remote patch can resolve against the given editor value.\n * Concurrent edits routinely produce operations addressing nodes another\n * client has already removed or not yet created; sending those into the\n * engine fails loudly (console errors) before being skipped. Callers drop\n * unresolvable patches up front and rely on the follow-up repair sync to\n * converge instead.\n *\n * @internal\n */\nexport function canApplyToValue(\n patch: PtePatch,\n value: PortableTextBlock[] | undefined,\n): boolean {\n if (!value) {\n return true\n }\n const root = value as unknown as JSONValue\n switch (patch.type) {\n // unset needs the node itself; insert needs the sibling at `path`;\n // diffMatchPatch needs the existing string\n case 'unset':\n case 'insert':\n case 'diffMatchPatch':\n return getValueAtPath(root, patch.path) !== undefined\n // set creates its target property, so only the parent must resolve\n case 'set':\n return (\n patch.path.length === 0 ||\n getValueAtPath(root, patch.path.slice(0, -1)) !== undefined\n )\n default:\n return true\n }\n}\n\n/**\n * Scopes document-rooted Sanity patches to the given field path, returning\n * field-relative Portable Text Editor patches. Patches outside the field are\n * dropped. Returns `null` when the field (or an ancestor of it) is replaced\n * wholesale, in which case the caller should fall back to a full value sync.\n * Throws when a path expression cannot be converted.\n *\n * @internal\n */\nexport function scopeRemotePatches(\n patches: SanityPatchOperations[],\n fieldPath: string,\n): PtePatch[] | null {\n const prefix = arrayifyPath(fieldPath)\n const converted = convertPatches(patches)\n const scoped: PtePatch[] = []\n\n for (const patch of converted) {\n const overlap = Math.min(patch.path.length, prefix.length)\n let touchesField = true\n for (let index = 0; index < overlap; index++) {\n if (!segmentsEqual(patch.path[index], prefix[index])) {\n touchesField = false\n break\n }\n }\n if (!touchesField) {\n continue\n }\n if (patch.path.length <= prefix.length) {\n // the patch targets the field itself or an ancestor of it, which\n // cannot be expressed as a field-relative operation\n return null\n }\n scoped.push({...patch, path: patch.path.slice(prefix.length)})\n }\n\n return scoped\n}\n\nfunction debugTextOf(value: unknown): string {\n if (!Array.isArray(value)) {\n return ''\n }\n return value\n .map((block) =>\n Array.isArray((block as {children?: unknown}).children)\n ? ((block as {children: Array<{text?: string}>}).children ?? [])\n .map((child) => child.text ?? '')\n .join('')\n : '',\n )\n .join('\\n')\n}\n\n/**\n * How long an editor-versus-store divergence must persist, unchanged,\n * before the whole-value repair acts on it. When a remote transaction\n * arrives interleaved with the listener echoes of this client's own recent\n * edits, the store value is transiently wrong until the echo returns and\n * the rebase corrects it. A repair fired inside that window copies the\n * garbage into the editor and a follow-up repair restores the text at a\n * drifted offset, scrambling words the user typed in the meantime. The\n * window therefore has to outlast a slow listener echo round trip; real\n * divergence is stable and loses nothing by being repaired a beat later.\n *\n * Tests use a short window: their mock stores are synchronous, so echo\n * transients cannot occur, and waiting the production interval would only\n * slow every repair assertion down.\n */\nconst REPAIR_CONFIRM_DELAY =\n // @ts-expect-error - dot notation required for Vite to replace at build time\n process.env.NODE_ENV === 'test' ? 150 : 1000\n\ntype PendingRepair = {signature: string; timer: ReturnType<typeof setTimeout>}\nconst pendingRepairs = new WeakMap<Editor, PendingRepair>()\n\n/**\n * Local edits the editor has emitted but not yet flushed into a mutation.\n * While any exist, the store necessarily lags the editor and a repair diff\n * would \"repair away\" the user's unflushed keystrokes, so repairs must wait.\n */\nconst unflushedEdits = new WeakMap<Editor, boolean>()\n\nfunction computeRepair(\n editor: Editor,\n remoteValue: PortableTextBlock[],\n): {patches: PtePatch[]; convertible: boolean; signature: string} {\n const snapshot = editor.getSnapshot().context.value\n // The signature covers the full (editor, store) state, not just the diff:\n // with repetitive text, two different transients can produce an identical\n // diff, and a repair must only act when the world actually stood still.\n const stateSignature = JSON.stringify([snapshot, remoteValue])\n try {\n const patches = toEngineSafePatches(\n convertPatches(diffValue(snapshot, remoteValue)),\n remoteValue,\n )\n return {patches, convertible: true, signature: stateSignature}\n } catch {\n // diffValue can emit path shapes the converter does not understand\n // (e.g. array slices when multiple items are dropped). The repair then\n // has to fall back to a whole-value update.\n return {patches: [], convertible: false, signature: `!${stateSignature}`}\n }\n}\n\nfunction cancelPendingRepair(editor: Editor) {\n const pending = pendingRepairs.get(editor)\n if (pending) {\n clearTimeout(pending.timer)\n pendingRepairs.delete(editor)\n }\n}\n\nfunction applySync({\n editor,\n getRemoteValue,\n}: {\n editor: Editor\n getRemoteValue: () => PortableTextBlock[] | null | undefined\n}) {\n const remoteValue = getRemoteValue()\n\n if (!remoteValue) {\n return\n }\n\n const first = computeRepair(editor, remoteValue)\n if (first.convertible && first.patches.length === 0) {\n cancelPendingRepair(editor)\n return\n }\n\n if (debug.repair.enabled) {\n debug.repair('editor and store texts diverged %o', {\n editorText: debugTextOf(editor.getSnapshot().context.value),\n remoteText: debugTextOf(remoteValue),\n })\n }\n\n // Same divergence already awaiting confirmation: let that timer decide.\n const pending = pendingRepairs.get(editor)\n if (pending && pending.signature === first.signature) {\n return\n }\n cancelPendingRepair(editor)\n\n const timer = setTimeout(() => {\n pendingRepairs.delete(editor)\n\n // Unflushed local keystrokes mean the store lags the editor by design;\n // a repair now would delete them. Re-arm and wait for the flush (the\n // divergence either disappears once the push round-trips, or persists\n // and gets repaired then).\n if (unflushedEdits.get(editor)) {\n applySync({editor, getRemoteValue})\n return\n }\n\n // Recompute from scratch: the store may have corrected itself (the\n // transient case) or the user may have typed (their edits will push\n // and reconverge through the normal flow); only a divergence that is\n // still byte-for-byte identical is real and safe to repair.\n const latestRemote = getRemoteValue()\n if (!latestRemote) {\n return\n }\n const second = computeRepair(editor, latestRemote)\n if (second.convertible && second.patches.length === 0) {\n return\n }\n if (second.signature !== first.signature) {\n // Still diverged but differently: re-arm so a stable state eventually\n // confirms. Transients converge to the empty diff; genuine divergence\n // stabilizes to a fixed signature within one flush cycle.\n applySync({editor, getRemoteValue})\n return\n }\n\n if (!second.convertible) {\n debug.repair('escalating to whole-value sync (unconvertible diff)')\n editor.send({type: 'update value', value: latestRemote})\n return\n }\n\n const snapshot = editor.getSnapshot().context.value\n debug.repair('applying confirmed repair patches %o', second.patches)\n editor.send({type: 'patches', patches: second.patches, snapshot})\n\n // Patch application is best-effort: the editor skips operations it\n // cannot resolve against its current tree, and concurrent edits to the\n // same range produce keyed operations whose targets no longer exist\n // locally. When the editor is still diverged after the diff-based\n // repair, escalate to the full value sync machinery, which reconciles\n // arbitrary divergence block by block.\n const valueAfterPatches = editor.getSnapshot().context.value\n if (diffValue(valueAfterPatches, latestRemote).length > 0) {\n if (debug.repair.enabled) {\n debug.repair('escalating to whole-value sync %o', {\n editorText: debugTextOf(valueAfterPatches),\n remoteText: debugTextOf(latestRemote),\n })\n }\n editor.send({type: 'update value', value: latestRemote})\n }\n }, REPAIR_CONFIRM_DELAY)\n\n pendingRepairs.set(editor, {signature: first.signature, timer})\n}\n\nconst listenToEditor = fromCallback<AnyEventObject, {editor: Editor}>(\n ({sendBack, input}) => {\n const patchSubscription = input.editor.on('patch', () => {\n // Every 'patch' event is a local edit (remote application suppresses\n // patch generation), so the store now lags the editor until the next\n // mutation flush.\n unflushedEdits.set(input.editor, true)\n sendBack({type: 'patch emitted'})\n })\n\n const mutationSubscription = input.editor.on('mutation', (event) => {\n unflushedEdits.set(input.editor, false)\n if (debug.mutation.enabled) {\n debug.mutation('flushed %o', {\n flushText: debugTextOf(event.value),\n snapshotText: debugTextOf(input.editor.getSnapshot().context.value),\n })\n }\n sendBack({\n type: 'mutation flushed',\n value: event.value,\n patches: event.patches,\n })\n })\n\n return () => {\n patchSubscription.unsubscribe()\n mutationSubscription.unsubscribe()\n }\n },\n)\n\nconst listenToRemote = fromCallback<\n AnyEventObject,\n {onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']}\n>(({sendBack, input}) => {\n return input.onRemoteValueChange(() => {\n sendBack({type: 'remote value changed'})\n })\n})\n\nconst listenToRemotePatches = fromCallback<\n AnyEventObject,\n {onRemotePatches: ValueSyncConfig['onRemotePatches']}\n>(({sendBack, input}) => {\n return input.onRemotePatches?.((patches) => {\n sendBack({type: 'remote patches received', patches})\n })\n})\n\n/**\n * How long the machine must sit in 'idle' (no local keystrokes, no store\n * events) before the one-shot whole-value repair runs. Long enough for the\n * editor's external value snapshot to catch up after the last flush; short\n * enough that residual divergence from concurrent editing heals promptly.\n */\nconst QUIESCENT_REPAIR_DELAY = 500\n\nconst valueSyncMachine = setup({\n types: {\n context: {} as {\n editor: Editor\n getRemoteValue: ValueSyncConfig['getRemoteValue']\n onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']\n onRemotePatches: ValueSyncConfig['onRemotePatches']\n },\n input: {} as {\n editor: Editor\n getRemoteValue: ValueSyncConfig['getRemoteValue']\n onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']\n onRemotePatches: ValueSyncConfig['onRemotePatches']\n },\n events: {} as\n | {type: 'patch emitted'}\n | {\n type: 'mutation flushed'\n value: PortableTextBlock[] | undefined\n patches: PtePatch[]\n }\n | {type: 'remote value changed'}\n | {type: 'remote patches received'; patches: PtePatch[]},\n },\n actions: {\n 'send initial value': ({context}) => {\n context.editor.send({\n type: 'update value',\n value: context.getRemoteValue() ?? [],\n })\n },\n 'push to remote': () => {\n throw new Error('push to remote must be provided via .provide()')\n },\n 'apply sync': ({context}) => {\n applySync({\n editor: context.editor,\n getRemoteValue: context.getRemoteValue,\n })\n },\n 'apply remote patches': ({context, event}) => {\n if (event.type !== 'remote patches received') {\n return\n }\n debug.remote('applying remote patches %o', event.patches)\n const snapshot = context.editor.getSnapshot().context.value\n // The store already reflects this transaction, so it can serve as\n // the target for coalescing sidecar-array item operations (which\n // the engine misroutes) into whole-property sets.\n const remoteValue = context.getRemoteValue()\n const coalesced = remoteValue\n ? toEngineSafePatches(event.patches, remoteValue)\n : event.patches\n const patches = coalesced.filter((patch) =>\n canApplyToValue(patch, snapshot),\n )\n if (patches.length === 0) {\n return\n }\n context.editor.send({type: 'patches', patches, snapshot})\n },\n },\n actors: {\n 'listen to editor': listenToEditor,\n 'listen to remote': listenToRemote,\n 'listen to remote patches': listenToRemotePatches,\n },\n}).createMachine({\n id: 'value sync',\n context: ({input}) => ({\n editor: input.editor,\n getRemoteValue: input.getRemoteValue,\n onRemoteValueChange: input.onRemoteValueChange,\n onRemotePatches: input.onRemotePatches,\n }),\n entry: ['send initial value'],\n invoke: [\n {\n src: 'listen to editor',\n input: ({context}) => ({editor: context.editor}),\n },\n {\n src: 'listen to remote',\n input: ({context}) => ({\n onRemoteValueChange: context.onRemoteValueChange,\n }),\n },\n {\n src: 'listen to remote patches',\n input: ({context}) => ({\n onRemotePatches: context.onRemotePatches,\n }),\n },\n ],\n // Two invariants, learned the hard way:\n //\n // 1. EVERY 'mutation flushed' event must be pushed, in every state. The\n // editor emits mutation events in bursts (one per input batch, e.g.\n // each backspace of a quick delete), and any state without a handler\n // silently drops the flush. A dropped flush permanently diverges the\n // store from the editor, and the whole-value repair then \"heals\" the\n // editor backwards, resurrecting deleted text.\n // 2. The whole-value repair must only run when no local edits can be in\n // flight (quiescent 'idle'). Running it mid-typing diffs the editor\n // against a store that lags the user's keystrokes and stomps them.\n //\n // Operational patches from other clients still apply immediately in\n // every state; the editor merges them with in-flight local changes.\n initial: 'idle',\n states: {\n 'idle': {\n // One-shot repair after a quiet period. Covers divergence left by\n // best-effort patch application while local edits were in flight\n // (those states never repair; see below) when no further store\n // event arrives to trigger the on-change repair.\n after: {\n [QUIESCENT_REPAIR_DELAY]: {\n actions: ['apply sync'],\n },\n },\n on: {\n 'patch emitted': {\n target: 'local write',\n },\n // Mutation events arrive in bursts (one per input batch), so a\n // flush can land after a sibling flush already advanced the state.\n 'mutation flushed': {\n target: 'pushing to remote',\n actions: ['push to remote'],\n },\n 'remote value changed': {\n actions: ['apply sync'],\n },\n // No immediate repair here: every remote patch batch also updates\n // the store value, so the accompanying 'remote value changed'\n // event runs the whole-value repair right after.\n 'remote patches received': {\n actions: ['apply remote patches'],\n },\n },\n },\n 'local write': {\n on: {\n 'patch emitted': {},\n 'mutation flushed': {\n target: 'pushing to remote',\n actions: ['push to remote'],\n },\n 'remote value changed': {\n target: 'pending sync',\n },\n 'remote patches received': {\n target: 'pending sync',\n actions: ['apply remote patches'],\n },\n },\n },\n 'pushing to remote': {\n on: {\n 'patch emitted': {\n target: 'local write',\n },\n 'mutation flushed': {\n actions: ['push to remote'],\n },\n // No repair on the push acknowledgment: the editor snapshot can\n // lag the live document while the user keeps typing, so a diff\n // against the store here resurrects deleted text and duplicates\n // in-flight keystrokes. Once truly idle, the store change or the\n // quiescent delay runs the repair with a caught-up snapshot.\n 'remote value changed': {\n target: 'idle',\n },\n 'remote patches received': {\n actions: ['apply remote patches'],\n },\n },\n },\n 'pending sync': {\n on: {\n 'patch emitted': {},\n 'mutation flushed': {\n target: 'pushing to remote',\n actions: ['push to remote'],\n },\n 'remote value changed': {},\n 'remote patches received': {\n actions: ['apply remote patches'],\n },\n },\n },\n },\n})\n\ninterface SDKValuePluginProps extends DocumentHandle {\n path: string\n}\n\n/**\n * The shape of the `remote-patches` document event emitted by\n * `@sanity/sdk` >= 2.17. Declared structurally so the plugin stays\n * compatible with older SDK typings until its dependency is bumped.\n */\ntype RemotePatchesDocumentEvent = {\n type: 'remote-patches'\n documentId: string\n transactionId: string\n timestamp: string\n previousRev?: string\n patches: SanityPatchOperations[]\n origin: 'local' | 'remote'\n}\n\nfunction isRemotePatchesEvent(event: {\n type: string\n}): event is RemotePatchesDocumentEvent {\n return event.type === 'remote-patches'\n}\n\nfunction getPublishedDocumentId(id: string): string {\n if (id.startsWith('drafts.')) {\n return id.slice('drafts.'.length)\n }\n if (id.startsWith('versions.')) {\n return id.split('.').slice(2).join('.')\n }\n return id\n}\n\n/**\n * @public\n */\nexport function SDKValuePlugin(props: SDKValuePluginProps) {\n const {documentId, documentType, path} = props\n const setSdkValue = useEditDocument(props)\n const instance = useSanityInstance(props)\n const applyActions = useApplyDocumentActions()\n\n const handle = {documentId, documentType, path}\n const {getCurrent, subscribe} = getDocumentState<PortableTextBlock[]>(\n instance,\n handle,\n )\n\n const onRemotePatches = useCallback(\n (callback: (patches: PtePatch[]) => void) => {\n return subscribeDocumentEvents(instance, {\n eventHandler: (event) => {\n // widen before narrowing: `remote-patches` is not part of the\n // `DocumentEvent` union in older SDK typings\n const candidate: {type: string} = event\n if (!isRemotePatchesEvent(candidate)) {\n return\n }\n // our own transactions are already reflected in the editor\n if (candidate.origin !== 'remote') {\n return\n }\n if (\n getPublishedDocumentId(candidate.documentId) !==\n getPublishedDocumentId(documentId)\n ) {\n return\n }\n\n let patches: PtePatch[] | null\n try {\n patches = scopeRemotePatches(candidate.patches, path)\n } catch {\n // unconvertible patch shapes fall back to the whole-value sync\n // driven by `onRemoteValueChange`\n return\n }\n if (patches && patches.length > 0) {\n callback(patches)\n }\n },\n })\n },\n [instance, documentId, path],\n )\n\n const pushPatches = useCallback(\n (patches: PtePatch[]) => {\n const sanityPatches = convertPatchesToSanity(patches, {prefix: path})\n // `preserveOperations` ships in @sanity/sdk >= 2.17; the intersection\n // type keeps the plugin compatible with older SDK typings\n const action: EditDocumentAction & {preserveOperations?: boolean} = {\n ...editDocument(\n {documentId, documentType},\n sanityPatches as Parameters<typeof editDocument>[1],\n ),\n preserveOperations: true,\n }\n applyActions(action)\n },\n [applyActions, documentId, documentType, path],\n )\n\n return (\n <ValueSyncPlugin\n getRemoteValue={getCurrent}\n pushValue={setSdkValue}\n onRemoteValueChange={subscribe}\n onRemotePatches={onRemotePatches}\n pushPatches={pushPatches}\n />\n )\n}\n\n/**\n * @internal\n */\ntype ValueSyncConfig = {\n getRemoteValue: () => PortableTextBlock[] | null | undefined\n pushValue: (value: PortableTextBlock[]) => void\n onRemoteValueChange: (callback: () => void) => () => void\n /**\n * Optional patch channel. When provided, operational patches from other\n * clients are applied directly to the editor (in every state) instead of\n * waiting for a whole-value diff, and local editor patches are pushed\n * through `pushPatches`. The whole-value sync remains as a fallback for\n * anything the patch channel cannot express.\n */\n onRemotePatches?: (\n callback: (patches: PtePatch[]) => void,\n ) => (() => void) | undefined\n /**\n * Pushes the editor's own operational patches to the remote store. May\n * throw when a patch cannot be converted, in which case the plugin falls\n * back to pushing the whole value.\n */\n pushPatches?: (patches: PtePatch[]) => void\n}\n\n/**\n * NOTE: You are probably looking for SDKValuePlugin instead of this.\n * This is a lower-level plugin that only handles syncing the value\n * between the editor and a remote source. It does not know anything\n * about Sanity documents or how to fetch/update them.\n *\n * May be removed in the future, do not rely on this directly.\n *\n * @internal\n */\nexport function ValueSyncPlugin(props: ValueSyncConfig) {\n const {\n getRemoteValue,\n pushValue,\n onRemoteValueChange,\n onRemotePatches,\n pushPatches,\n } = props\n const editor = useEditor()\n\n useActorRef(\n valueSyncMachine.provide({\n actions: {\n 'push to remote': ({context, event}) => {\n if (event.type !== 'mutation flushed') {\n return\n }\n\n if (pushPatches && event.patches.length > 0) {\n try {\n const mergeable = toMergeableMarkDefsPatches(\n event.patches,\n context.getRemoteValue,\n )\n debug.push('pushing patches %o', mergeable)\n pushPatches(mergeable)\n return\n } catch {\n // fall back to pushing the whole value below\n }\n }\n\n if (debug.push.enabled) {\n debug.push(\n 'pushing whole value %s',\n debugTextOf(\n event.value ?? context.editor.getSnapshot().context.value,\n ),\n )\n }\n pushValue(event.value ?? context.editor.getSnapshot().context.value)\n },\n },\n }),\n {\n input: {\n editor,\n getRemoteValue,\n onRemoteValueChange,\n onRemotePatches,\n },\n },\n )\n\n return null\n}\n"],"names":["rootName","createDebugger","name","namespace","rawDebug","enabled","debug","mutation","push","remote","repair","ARRAYIFY_ERROR_MESSAGE","getSegments","node","base","segment","type","isKeyPath","recursive","arrayifyPath","pathExpr","parsePath","Error","Array","from","map","elements","length","element","value","operator","keyPathNode","left","right","find","other","_key","convertPatches","patches","flatMap","p","Object","entries","values","origin","path","isArray","items","rest","position","keys","at","STRINGIFY_ERROR_MESSAGE","stringifyPatchPath","result","prefixPathExpression","prefix","expression","startsWith","convertPatchesToSanity","options","patch","pathExpression","set","setIfMissing","unset","diffMatchPatch","inc","dec","insert","segmentsEqual","a","b","pathsEqual","every","index","findSidecarArrayPath","expectNode","slice","getValueAtPath","current","item","toEngineSafePatches","targetValue","safe","sidecarPaths","sidecarPath","some","existing","undefined","toMergeableMarkDefsPatches","getCurrentValue","currentValue","root","storeMarkDefs","storeBlock","local","store","referencedKeys","Set","children","child","marks","storeByKey","Map","localKeys","ops","inserted","filter","has","get","JSON","stringify","canApplyToValue","scopeRemotePatches","fieldPath","converted","scoped","overlap","Math","min","touchesField","debugTextOf","block","text","join","REPAIR_CONFIRM_DELAY","process","env","NODE_ENV","pendingRepairs","WeakMap","unflushedEdits","computeRepair","editor","remoteValue","snapshot","getSnapshot","context","stateSignature","diffValue","convertible","signature","cancelPendingRepair","pending","clearTimeout","timer","delete","applySync","getRemoteValue","first","editorText","remoteText","setTimeout","latestRemote","second","send","valueAfterPatches","listenToEditor","fromCallback","sendBack","input","patchSubscription","on","mutationSubscription","event","flushText","snapshotText","unsubscribe","listenToRemote","onRemoteValueChange","listenToRemotePatches","onRemotePatches","QUIESCENT_REPAIR_DELAY","valueSyncMachine","setup","types","events","actions","send initial value","push to remote","apply sync","apply remote patches","actors","createMachine","id","entry","invoke","src","initial","states","after","target","isRemotePatchesEvent","getPublishedDocumentId","split","SDKValuePlugin","props","$","_c","documentId","documentType","setSdkValue","useEditDocument","instance","useSanityInstance","applyActions","useApplyDocumentActions","t0","getDocumentState","getCurrent","subscribe","t1","callback","subscribeDocumentEvents","eventHandler","candidate","t2","patches_0","sanityPatches","action","editDocument","preserveOperations","pushPatches","t3","ValueSyncPlugin","pushValue","useEditor","provide","mergeable","useActorRef"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/plugin-sdk-value",
3
- "version": "7.1.1",
3
+ "version": "7.1.3",
4
4
  "description": "Connect a Portable Text Editor with a Sanity document using the SDK",
5
5
  "keywords": [
6
6
  "@sanity/sdk",
@@ -37,6 +37,7 @@
37
37
  "@sanity/diff-patch": "^6.0.0",
38
38
  "@sanity/json-match": "^1.0.5",
39
39
  "@xstate/react": "^6.1.0",
40
+ "debug": "^4.4.3",
40
41
  "xstate": "^5.32.4"
41
42
  },
42
43
  "devDependencies": {
@@ -44,6 +45,7 @@
44
45
  "@sanity/pkg-utils": "^10.8.2",
45
46
  "@sanity/sdk-react": "^2.13.0",
46
47
  "@sanity/tsconfig": "^2.1.0",
48
+ "@types/debug": "^4.1.12",
47
49
  "@types/react": "^19.2.17",
48
50
  "@types/react-dom": "^19.2.3",
49
51
  "@vitejs/plugin-react": "^5.2.0",
@@ -57,9 +59,10 @@
57
59
  "react-dom": "^19.2.7",
58
60
  "typescript": "6.0.3",
59
61
  "typescript-eslint": "^8.62.0",
62
+ "vite": "^7.3.5",
60
63
  "vitest": "^4.1.10",
61
64
  "vitest-browser-react": "^2.2.0",
62
- "@portabletext/editor": "^7.10.9",
65
+ "@portabletext/editor": "^7.10.11",
63
66
  "@portabletext/patches": "^2.0.5",
64
67
  "@portabletext/schema": "^2.2.3",
65
68
  "@portabletext/test": "^1.0.4"
@@ -68,7 +71,7 @@
68
71
  "@sanity/sdk-react": "^2.1.2",
69
72
  "react": "^19.2",
70
73
  "react-dom": "^19.2",
71
- "@portabletext/editor": "^7.10.9"
74
+ "@portabletext/editor": "^7.10.11"
72
75
  },
73
76
  "engines": {
74
77
  "node": ">=20.19 <22 || >=22.12"