@portabletext/editor 8.1.2 → 8.1.4

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.
Files changed (33) hide show
  1. package/lib/{behavior.types.action-C0XDEQnB.d.ts → behavior.types.action-BDNqhLEt.d.ts} +53 -25
  2. package/lib/behavior.types.action-BDNqhLEt.d.ts.map +1 -0
  3. package/lib/behaviors/index.d.ts +1 -1
  4. package/lib/{get-container-D2pN5Npr.js → get-container-CXdmRdiX.js} +3 -3
  5. package/lib/{get-container-D2pN5Npr.js.map → get-container-CXdmRdiX.js.map} +1 -1
  6. package/lib/{get-parent-DgaKcy8-.js → get-parent-BLzi7eLr.js} +39 -14
  7. package/lib/get-parent-BLzi7eLr.js.map +1 -0
  8. package/lib/{get-path-sub-schema-Dd0QYZ0m.js → get-path-sub-schema-DsN1qF_l.js} +9 -5
  9. package/lib/get-path-sub-schema-DsN1qF_l.js.map +1 -0
  10. package/lib/index.d.ts +1 -1
  11. package/lib/index.js +233 -217
  12. package/lib/index.js.map +1 -1
  13. package/lib/plugins/index.d.ts +1 -1
  14. package/lib/{selector.is-selecting-entire-blocks-BFhnnkHf.js → selector.is-selecting-entire-blocks-BHVYIXbI.js} +8 -5
  15. package/lib/selector.is-selecting-entire-blocks-BHVYIXbI.js.map +1 -0
  16. package/lib/selectors/index.d.ts +1 -1
  17. package/lib/selectors/index.js +4 -4
  18. package/lib/traversal/index.d.ts +9 -6
  19. package/lib/traversal/index.d.ts.map +1 -1
  20. package/lib/traversal/index.js +3 -3
  21. package/lib/{util.is-equal-selections-BdK98okY.js → util.is-equal-selections-sCQib0IC.js} +2 -2
  22. package/lib/{util.is-equal-selections-BdK98okY.js.map → util.is-equal-selections-sCQib0IC.js.map} +1 -1
  23. package/lib/{util.slice-blocks-_ElaB53f.js → util.slice-blocks-B-iKFEG7.js} +43 -56
  24. package/lib/util.slice-blocks-B-iKFEG7.js.map +1 -0
  25. package/lib/utils/index.d.ts +1 -1
  26. package/lib/utils/index.js +4 -8
  27. package/lib/utils/index.js.map +1 -1
  28. package/package.json +1 -1
  29. package/lib/behavior.types.action-C0XDEQnB.d.ts.map +0 -1
  30. package/lib/get-parent-DgaKcy8-.js.map +0 -1
  31. package/lib/get-path-sub-schema-Dd0QYZ0m.js.map +0 -1
  32. package/lib/selector.is-selecting-entire-blocks-BFhnnkHf.js.map +0 -1
  33. package/lib/util.slice-blocks-_ElaB53f.js.map +0 -1
package/lib/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { a as getChildren, d as isKeyedSegment, i as resolveNode, n as parentPath, o as getNodeChildren, r as getNode, t as getParent, u as serializePath } from "./get-parent-DgaKcy8-.js";
2
- import { C as getAncestors, S as hasNode, _ as comparePoints, a as isInline, b as isEditableContainer, c as isSpanNode, d as resolveChildEntryIndex, f as isAncestorPath, g as isAfterPoint, h as isBackwardRange, i as getEnclosingBlock, l as getSibling, m as rangeEdges, n as getEnclosingContainer, o as getBlock, p as isTextBlockNode, s as isBlock, t as getPathSubSchema, u as getNodes, v as comparePaths, x as resolveContainerAt, y as isObject } from "./get-path-sub-schema-Dd0QYZ0m.js";
3
- import { _ as getAncestor, a as getTextBlock, c as pathContains, d as isRange, f as isPoint, g as isLeafObject, h as getLeaf, i as getFirstChild, l as getSpan, m as isPath, n as getUnionSchema, o as rangeIntersects, p as isObject$1, r as getLastChild, s as isBeforePoint, t as getContainer, u as getText } from "./get-container-D2pN5Npr.js";
4
- import { a as parseBlocks, b as childAtTextOffset, c as parseSpan, d as getSelectionEndPoint, f as isSelectionCollapsed, g as isEqualSelectionPoints, h as getBlockKeyFromSelectionPoint, i as parseBlock, l as defaultKeyGenerator, m as getBlockEndPoint, n as isListBlock, o as parseInlineObject, p as getBlockStartPoint, r as parseAnnotation, s as parseMarkDefs, u as getSelectionStartPoint, v as blockOffsetToSpanSelectionPoint, x as textOffsetOfChild } from "./util.slice-blocks-_ElaB53f.js";
5
- import { A as getSelectionEndPoint$1, B as getFocusBlock, C as getSelectedTextBlocks, D as getPreviousSpan, F as getSelectionEndBlock, G as rangesOverlap, H as getFocusInlineObject, I as getFragment, L as getSelectedValue, M as isSelectionCollapsed$1, N as isOverlappingSelection, O as getSelectionStartPoint$1, P as getSelectionStartBlock, R as getRootAcceptedTypes, S as getActiveDecorators, T as getMarkState, U as getFocusChild, V as getFocusSpan, a as isActiveListItem, b as getActiveAnnotations, c as getSelectionEndChild, d as getLastBlock, f as getFocusListBlock, i as isActiveStyle, j as isSelectionExpanded, k as getNextSpan, l as getPreviousBlock, m as getCaretWordSelection, n as isAtTheStartOfBlock, o as isActiveDecorator, p as getFocusBlockObject, r as isAtTheEndOfBlock, s as getSelectionStartChild, t as isSelectingEntireBlocks, u as getNextBlock, w as getActiveAnnotationsMarks, x as isActiveAnnotation, z as getFocusTextBlock } from "./selector.is-selecting-entire-blocks-BFhnnkHf.js";
6
- import { n as isEmptyTextBlock, r as getTextBlockText, t as isEqualSelections } from "./util.is-equal-selections-BdK98okY.js";
1
+ import { a as getChildren, d as nodeSegment, f as serializePath, i as resolveNode, n as parentPath, o as getNodeChildren, p as isKeyedSegment, r as getNode, t as getParent, u as hasUsableKey } from "./get-parent-BLzi7eLr.js";
2
+ import { C as getAncestors, S as hasNode, _ as comparePoints, a as isInline, b as isEditableContainer, c as isSpanNode, d as resolveChildEntryIndex, f as isAncestorPath, g as isAfterPoint, h as isBackwardRange, i as getEnclosingBlock, l as getSibling, m as rangeEdges, n as getEnclosingContainer, o as getBlock, p as isTextBlockNode, s as isBlock, t as getPathSubSchema, u as getNodes, v as comparePaths, x as resolveContainerAt, y as isObject } from "./get-path-sub-schema-DsN1qF_l.js";
3
+ import { _ as getAncestor, a as getTextBlock, c as pathContains, d as isRange, f as isPoint, g as isLeafObject, h as getLeaf, i as getFirstChild, l as getSpan, m as isPath, n as getUnionSchema, o as rangeIntersects, p as isObject$1, r as getLastChild, s as isBeforePoint, t as getContainer, u as getText } from "./get-container-CXdmRdiX.js";
4
+ import { a as parseMarkDefs, c as getSelectionStartPoint, d as getBlockStartPoint, f as getBlockEndPoint, g as blockOffsetToSpanSelectionPoint, i as parseInlineObject, l as getSelectionEndPoint, m as isEqualSelectionPoints, n as parseAnnotation, o as parseSpan, p as getBlockKeyFromSelectionPoint, r as parseBlock, s as defaultKeyGenerator, u as isSelectionCollapsed, v as childAtTextOffset, y as textOffsetOfChild } from "./util.slice-blocks-B-iKFEG7.js";
5
+ import { A as getSelectionEndPoint$1, B as getFocusTextBlock, C as getSelectedTextBlocks, D as getPreviousSpan, F as getSelectionStartBlock, H as getFocusSpan, I as getSelectionEndBlock, K as rangesOverlap, L as getFragment, M as isSelectionExpanded, N as isSelectionCollapsed$1, O as getSelectionStartPoint$1, P as isOverlappingSelection, R as getSelectedValue, S as getActiveDecorators, T as getMarkState, U as getFocusInlineObject, V as getFocusBlock, W as getFocusChild, a as isActiveListItem, b as getActiveAnnotations, c as getSelectionEndChild, d as getLastBlock, f as getFocusListBlock, i as isActiveStyle, j as isListBlock, k as getNextSpan, l as getPreviousBlock, m as getCaretWordSelection, n as isAtTheStartOfBlock, o as isActiveDecorator, p as getFocusBlockObject, r as isAtTheEndOfBlock, s as getSelectionStartChild, t as isSelectingEntireBlocks, u as getNextBlock, w as getActiveAnnotationsMarks, x as isActiveAnnotation, z as getRootAcceptedTypes } from "./selector.is-selecting-entire-blocks-BHVYIXbI.js";
6
+ import { n as isEmptyTextBlock, r as getTextBlockText, t as isEqualSelections } from "./util.is-equal-selections-sCQib0IC.js";
7
7
  import { a as raise$1, i as forward, n as effect, t as defineBehavior } from "./behavior.types.behavior-BxSLb73I.js";
8
8
  import { n as EditorContext$1, t as useEditor } from "./use-editor-CwNeVwVC.js";
9
9
  import { c } from "react/compiler-runtime";
@@ -748,6 +748,36 @@ function move(editor, options = {}) {
748
748
  }
749
749
  editor.setSelection(props);
750
750
  }
751
+ /**
752
+ * Reduces the frame stack to an `OperationOrigin` by fixed precedence
753
+ * (undo > redo > normalization > remote > local), regardless of nesting
754
+ * order. Normalization outranks remote so a fix that runs while replaying
755
+ * a remote patch is attributed to the fix, not laundered into looking like
756
+ * an ordinary remote write; `hasRemoteFrame` is the precedence-blind read
757
+ * for callers that need the externally-triggered fact regardless of
758
+ * whether a fix ran on top of it.
759
+ */
760
+ function getOrigin(frames) {
761
+ return frames.some((frame) => frame.kind === "undo") ? "undo" : frames.some((frame) => frame.kind === "redo") ? "redo" : frames.some((frame) => frame.kind === "normalization") ? "normalization" : frames.some((frame) => frame.kind === "remote") ? "remote" : "local";
762
+ }
763
+ /**
764
+ * True while the frame stack carries a `remote` frame at any depth: the
765
+ * editor is applying content that arrived from outside (remote `patches`
766
+ * or value sync), possibly nested inside a normalization fix.
767
+ * `normalize-node`'s readers gate optional fix-ups on it to leave adopted
768
+ * content alone; `apply-operation` skips inverse population; the sync
769
+ * machine treats it as busy.
770
+ */
771
+ function hasRemoteFrame(frames) {
772
+ return frames.some((frame) => frame.kind === "remote");
773
+ }
774
+ /**
775
+ * Precedence-blind: true whenever a `normalization` frame is on the stack,
776
+ * even when an `undo` or `redo` frame outranks it in `getOrigin`.
777
+ */
778
+ function isInNormalization(frames) {
779
+ return frames.some((frame) => frame.kind === "normalization");
780
+ }
751
781
  function subscribeToOperations(editor, listener, options) {
752
782
  let phase = options?.phase ?? "after";
753
783
  return editor.operationListeners[phase] = [...editor.operationListeners[phase], listener], () => {
@@ -763,20 +793,16 @@ function subscribeToOperations(editor, listener, options) {
763
793
  * the apply.
764
794
  */
765
795
  function createOperationEvent(editor, operation) {
766
- let isNormalizingNode = !!editor.isNormalizingNode, isProcessingRemoteChanges = !!editor.isProcessingRemoteChanges, isUndoing = !!editor.isUndoing, isRedoing = !!editor.isRedoing;
767
796
  return {
768
797
  operation,
769
798
  beforeValue: editor.snapshot.context.value,
770
799
  beforeSelection: editor.snapshot.context.selection,
771
800
  operationsInProgress: editor.operations.length > 0,
772
- isNormalizingNode,
773
801
  isPatching: !!editor.isPatching,
774
- isProcessingRemoteChanges,
775
- isUndoing,
776
- isRedoing,
777
802
  withHistory: !!editor.withHistory,
778
803
  undoStepId: editor.undoStepId,
779
- origin: isProcessingRemoteChanges ? "remote" : isUndoing ? "undo" : isRedoing ? "redo" : isNormalizingNode ? "normalization" : "local"
804
+ origin: getOrigin(editor.applyContext),
805
+ context: Object.freeze([...editor.applyContext])
780
806
  };
781
807
  }
782
808
  function emitOperationEvent(listeners, event) {
@@ -4205,7 +4231,7 @@ const engineOperationCallback = ({ input, sendBack }) => subscribeToOperations(i
4205
4231
  event.operation.type !== "set.selection" && sendBack({
4206
4232
  type: "engine operation",
4207
4233
  operation: event.operation,
4208
- origin: event.origin
4234
+ origin: hasRemoteFrame(event.context) ? "remote" : "local"
4209
4235
  });
4210
4236
  }, { phase: "before" });
4211
4237
  function mergeRangeDecoration(leaf, decoration) {
@@ -4268,7 +4294,7 @@ const rangeDecorationsMachine = setup({
4268
4294
  decoratedRange.rangeDecoration.onMoved?.({
4269
4295
  newSelection: null,
4270
4296
  rangeDecoration: decoratedRange.rangeDecoration,
4271
- origin: event.origin === "remote" ? "remote" : "local"
4297
+ origin: event.origin
4272
4298
  });
4273
4299
  continue;
4274
4300
  }
@@ -4276,7 +4302,7 @@ const rangeDecorationsMachine = setup({
4276
4302
  (newRange && newRange !== currentSelection || newRange === null && currentSelection) && decoratedRange.rangeDecoration.onMoved?.({
4277
4303
  newSelection: newRange,
4278
4304
  rangeDecoration: decoratedRange.rangeDecoration,
4279
- origin: event.origin === "remote" ? "remote" : "local"
4305
+ origin: event.origin
4280
4306
  }), newRange !== null && rangeDecorationState.push({
4281
4307
  ...newRange || currentSelection,
4282
4308
  rangeDecoration: {
@@ -5469,16 +5495,7 @@ const PortableTextEditable = forwardRef(function PortableTextEditable(props, for
5469
5495
  type: "behavior event",
5470
5496
  behaviorEvent: {
5471
5497
  type: "insert.blocks",
5472
- blocks: parseBlocks({
5473
- keyGenerator: editorEngine.snapshot.context.keyGenerator,
5474
- schema: editorEngine.snapshot.context.schema,
5475
- blocks: result_1.insert,
5476
- options: {
5477
- normalize: !1,
5478
- removeUnusedMarkDefs: !0,
5479
- validateFields: !1
5480
- }
5481
- }),
5498
+ blocks: result_1.insert,
5482
5499
  placement: "auto"
5483
5500
  },
5484
5501
  editor: editorEngine
@@ -5915,11 +5932,7 @@ const converterJson = defineConverter({
5915
5932
  let parsedBlock = parseBlock({
5916
5933
  keyGenerator: snapshot.context.keyGenerator,
5917
5934
  block,
5918
- options: {
5919
- normalize: !1,
5920
- removeUnusedMarkDefs: !0,
5921
- validateFields: !1
5922
- },
5935
+ profile: "lenient",
5923
5936
  schema: snapshot.context.schema
5924
5937
  });
5925
5938
  return parsedBlock ? [parsedBlock] : [];
@@ -5967,11 +5980,7 @@ const converterJson = defineConverter({
5967
5980
  let parsedBlock = parseBlock({
5968
5981
  keyGenerator: snapshot.context.keyGenerator,
5969
5982
  block,
5970
- options: {
5971
- normalize: !1,
5972
- removeUnusedMarkDefs: !0,
5973
- validateFields: !1
5974
- },
5983
+ profile: "lenient",
5975
5984
  schema: snapshot.context.schema
5976
5985
  });
5977
5986
  return parsedBlock ? [parsedBlock] : [];
@@ -6007,11 +6016,7 @@ const converterJson = defineConverter({
6007
6016
  let parsedBlock = parseBlock({
6008
6017
  keyGenerator: snapshot.context.keyGenerator,
6009
6018
  block,
6010
- options: {
6011
- normalize: !1,
6012
- removeUnusedMarkDefs: !0,
6013
- validateFields: !1
6014
- },
6019
+ profile: "lenient",
6015
6020
  schema: snapshot.context.schema
6016
6021
  });
6017
6022
  return parsedBlock ? [parsedBlock] : [];
@@ -6312,7 +6317,7 @@ function createBehaviorApiPlugin(editorActor) {
6312
6317
  return function behaviorApiPlugin(editor) {
6313
6318
  let { select, setSelection } = editor;
6314
6319
  return editor.select = (location) => {
6315
- if (editor.isNormalizingNode || editor.isPerformingBehaviorOperation) {
6320
+ if (isInNormalization(editor.applyContext) || editor.isPerformingBehaviorOperation) {
6316
6321
  select(location);
6317
6322
  return;
6318
6323
  }
@@ -6333,7 +6338,7 @@ function createBehaviorApiPlugin(editorActor) {
6333
6338
  editor
6334
6339
  });
6335
6340
  }, editor.setSelection = (partialRange) => {
6336
- if (editor.isNormalizingNode || editor.isPerformingBehaviorOperation) {
6341
+ if (isInNormalization(editor.applyContext) || editor.isPerformingBehaviorOperation) {
6337
6342
  setSelection(partialRange);
6338
6343
  return;
6339
6344
  }
@@ -6478,8 +6483,8 @@ function getDirtyPaths(context, op) {
6478
6483
  let levels = [[]];
6479
6484
  if (Array.isArray(op.value)) for (let i = 0; i < op.value.length; i++) {
6480
6485
  let child = op.value[i];
6481
- if (typeof child != "object" || !child || !("_key" in child) || typeof child._key != "string") continue;
6482
- let childNode = child, childPath = [{ _key: childNode._key }];
6486
+ if (typeof child != "object" || !child) continue;
6487
+ let childNode = child, childPath = [nodeSegment(childNode, i)];
6483
6488
  levels.push(childPath), collectDescendantPaths(context, childNode, childPath, levels, context.containers.get(childNode._type));
6484
6489
  }
6485
6490
  return levels;
@@ -6503,11 +6508,11 @@ function getDirtyPaths(context, op) {
6503
6508
  let parentRegistration = resolveContainerAt(context.containers, context.value, nodePath), seed = parentRegistration && "field" in parentRegistration ? parentRegistration : void 0;
6504
6509
  for (let i = 0; i < op.value.length; i++) {
6505
6510
  let child = op.value[i];
6506
- if (typeof child != "object" || !child || !("_key" in child) || typeof child._key != "string") continue;
6511
+ if (typeof child != "object" || !child) continue;
6507
6512
  let childNode = child, childPath = [
6508
6513
  ...nodePath,
6509
6514
  propertyName,
6510
- { _key: childNode._key }
6515
+ nodeSegment(childNode, i)
6511
6516
  ];
6512
6517
  levels.push(childPath), collectDescendantPaths(context, childNode, childPath, levels, seed);
6513
6518
  }
@@ -6583,7 +6588,14 @@ function normalize(editor, options = {}) {
6583
6588
  let entry = getNode(editor.snapshot, dirtyPath);
6584
6589
  if (!entry) continue;
6585
6590
  let entryNode = entry.node;
6586
- isTextBlock({ schema: editor.snapshot.context.schema }, entryNode) && entryNode.children.length === 0 && (editor.isNormalizingNode = !0, editor.normalizeNode([entry.node, entry.path], { operation }), editor.isNormalizingNode = !1);
6591
+ if (isTextBlock({ schema: editor.snapshot.context.schema }, entryNode) && entryNode.children.length === 0) {
6592
+ editor.applyContext.push(Object.freeze({ kind: "normalization" }));
6593
+ try {
6594
+ editor.normalizeNode([entry.node, entry.path], { operation });
6595
+ } finally {
6596
+ editor.applyContext.pop();
6597
+ }
6598
+ }
6587
6599
  }
6588
6600
  let dirtyPaths = getDirtyPaths(editor), initialDirtyPathsLength = dirtyPaths.length, iteration = 0;
6589
6601
  for (; dirtyPaths.length !== 0;) {
@@ -6594,10 +6606,23 @@ function normalize(editor, options = {}) {
6594
6606
  operation
6595
6607
  })) return;
6596
6608
  let dirtyPath = popDirtyPath(editor);
6597
- if (dirtyPath.length === 0) editor.isNormalizingNode = !0, editor.normalizeNode([editor, dirtyPath], { operation }), editor.isNormalizingNode = !1;
6598
- else if (hasNode(editor.snapshot, dirtyPath)) {
6609
+ if (dirtyPath.length === 0) {
6610
+ editor.applyContext.push(Object.freeze({ kind: "normalization" }));
6611
+ try {
6612
+ editor.normalizeNode([editor, dirtyPath], { operation });
6613
+ } finally {
6614
+ editor.applyContext.pop();
6615
+ }
6616
+ } else if (hasNode(editor.snapshot, dirtyPath)) {
6599
6617
  let entry = getNode(editor.snapshot, dirtyPath);
6600
- entry && (editor.isNormalizingNode = !0, editor.normalizeNode([entry.node, entry.path], { operation }), editor.isNormalizingNode = !1);
6618
+ if (entry) {
6619
+ editor.applyContext.push(Object.freeze({ kind: "normalization" }));
6620
+ try {
6621
+ editor.normalizeNode([entry.node, entry.path], { operation });
6622
+ } finally {
6623
+ editor.applyContext.pop();
6624
+ }
6625
+ }
6601
6626
  }
6602
6627
  iteration++, dirtyPaths = getDirtyPaths(editor);
6603
6628
  }
@@ -6766,74 +6791,42 @@ function replaceChildren(xs, index, removeCount, ...newValues) {
6766
6791
  let result = xs.slice();
6767
6792
  return result.splice(index, removeCount, ...newValues), result;
6768
6793
  }
6769
- const removeChildren = replaceChildren;
6770
- /**
6771
- * Find the index of a node in an array by its _key.
6772
- */
6773
- function findIndexByKey(children, key) {
6774
- return children.findIndex((child) => child._key === key);
6775
- }
6776
- /**
6777
- * Extract the keyed segments from a path (skipping field name strings).
6778
- */
6779
- function getKeyedSegments(path) {
6780
- return path.filter(isKeyedSegment);
6781
- }
6782
- /**
6783
- * Replace a descendant with a new node, replacing all ancestors
6784
- */
6785
- const modifyDescendant = (editor, path, f) => {
6794
+ const removeChildren = replaceChildren, modifyDescendant = (editor, path, f) => {
6786
6795
  if (path.length === 0) return;
6787
6796
  let context = {
6788
6797
  schema: editor.snapshot.context.schema,
6789
6798
  containers: editor.snapshot.context.containers
6790
6799
  }, nodeEntry = getNode(editor.snapshot, path);
6791
6800
  if (!nodeEntry) return;
6792
- let node = nodeEntry.node, modifiedNode = f(node), keyedSegments = getKeyedSegments(nodeEntry.path), numericIndices = /* @__PURE__ */ new Map();
6793
- {
6794
- let keyedIdx = 0;
6795
- for (let segment of path) typeof segment == "number" ? (numericIndices.set(keyedIdx, segment), keyedIdx++) : isKeyedSegment(segment) && keyedIdx++;
6796
- }
6797
- let fieldNames = [];
6798
- {
6799
- let currentNode = { value: editor.snapshot.context.value }, currentParent;
6800
- for (let i = 0; i < keyedSegments.length; i++) {
6801
- let result = getNodeChildren(context, currentNode, currentParent);
6802
- if (!result) return;
6803
- fieldNames.push(result.fieldName);
6804
- let numericIndex = numericIndices.get(i), child = numericIndex === void 0 ? result.children.find((c) => c._key === keyedSegments[i]._key) : result.children[numericIndex];
6805
- if (!child) return;
6806
- currentNode = child, currentParent = result.parent;
6807
- }
6808
- }
6809
- for (let level = keyedSegments.length - 2; level >= 0; level--) {
6810
- let childKey = keyedSegments[level + 1]._key, fieldName = fieldNames[level + 1], ancestorPathEnd = -1, keyedCount = 0;
6811
- for (let pi = 0; pi < path.length; pi++) if (typeof path[pi] != "string") {
6812
- if (keyedCount === level) {
6813
- ancestorPathEnd = pi + 1;
6814
- break;
6815
- }
6816
- keyedCount++;
6817
- }
6818
- let ancestorPath = ancestorPathEnd > 0 ? path.slice(0, ancestorPathEnd) : [], ancestorEntry = getNode(editor.snapshot, ancestorPath);
6819
- if (!ancestorEntry) return;
6820
- let ancestorNode = ancestorEntry.node, ancestorRecord = ancestorNode, currentChildren = Array.isArray(ancestorRecord[fieldName]) ? ancestorRecord[fieldName] : [], originalNumericIndex = numericIndices.get(level + 1), childIndex = originalNumericIndex === void 0 ? findIndexByKey(currentChildren, childKey) : originalNumericIndex;
6821
- if (childIndex === -1) return;
6801
+ let resolvedNodeSegments = nodeEntry.path.filter((segment) => typeof segment != "string"), inputNodeSegments = path.filter((segment) => typeof segment != "string"), levels = [], currentNode = { value: editor.snapshot.context.value }, currentParent;
6802
+ for (let i = 0; i < resolvedNodeSegments.length; i++) {
6803
+ let result = getNodeChildren(context, currentNode, currentParent);
6804
+ if (!result) return;
6805
+ let inputSegment = inputNodeSegments[i], resolvedSegment = resolvedNodeSegments[i], index;
6806
+ if (typeof inputSegment == "number") index = inputSegment;
6807
+ else if (typeof resolvedSegment == "number") index = resolvedSegment;
6808
+ else if (isKeyedSegment(resolvedSegment)) index = result.children.findIndex((child) => child._key === resolvedSegment._key);
6809
+ else return;
6810
+ let child = result.children[index];
6811
+ if (!child) return;
6812
+ levels.push({
6813
+ parentNode: currentNode,
6814
+ fieldName: result.fieldName,
6815
+ children: result.children,
6816
+ index
6817
+ }), currentNode = child, currentParent = result.parent;
6818
+ }
6819
+ let deepestLevel = levels.length - 1;
6820
+ if (deepestLevel < 0) return;
6821
+ let modifiedNode = f(currentNode);
6822
+ for (let level = deepestLevel; level >= 1; level--) {
6823
+ let { parentNode, fieldName, children, index } = levels[level];
6822
6824
  modifiedNode = {
6823
- ...ancestorNode,
6824
- [fieldName]: replaceChildren(currentChildren, childIndex, 1, modifiedNode)
6825
+ ...parentNode,
6826
+ [fieldName]: replaceChildren(children, index, 1, modifiedNode)
6825
6827
  };
6826
6828
  }
6827
- let rootIndex, rootNumericIndex = numericIndices.get(0);
6828
- if (rootNumericIndex !== void 0) rootIndex = rootNumericIndex;
6829
- else if (keyedSegments.length > 0) {
6830
- let rootSegment = keyedSegments[0], mapIndex = editor.blockIndexMap.get(serializePath([rootSegment]));
6831
- rootIndex = mapIndex === void 0 ? findIndexByKey(editor.snapshot.context.value, rootSegment._key) : mapIndex;
6832
- } else {
6833
- let firstSegment = path[0];
6834
- rootIndex = typeof firstSegment == "number" ? firstSegment : -1;
6835
- }
6836
- rootIndex === -1 || rootIndex >= editor.snapshot.context.value.length || (editor.snapshot.context.value = replaceChildren(editor.snapshot.context.value, rootIndex, 1, modifiedNode));
6829
+ editor.snapshot.context.value = replaceChildren(editor.snapshot.context.value, levels[0].index, 1, modifiedNode);
6837
6830
  }, modifyChildren = (editor, path, f) => {
6838
6831
  if (path.length === 0) editor.snapshot.context.value = f(editor.snapshot.context.value);
6839
6832
  else {
@@ -6867,7 +6860,7 @@ function applyOperation(editor, op) {
6867
6860
  break;
6868
6861
  }
6869
6862
  modifyChildren(editor, parentPath(path), (children) => {
6870
- !editor.isProcessingRemoteChanges && !editor.isUndoing && !editor.isRedoing && node._key !== void 0 && children.some((sibling) => sibling._key === node._key) && (node = {
6863
+ !editor.applyContext.some((frame) => frame.kind === "remote" || frame.kind === "undo" || frame.kind === "redo") && node._key !== void 0 && children.some((sibling) => sibling._key === node._key) && (node = {
6871
6864
  ...node,
6872
6865
  _key: editor.snapshot.context.keyGenerator()
6873
6866
  }, op.node = node);
@@ -6879,7 +6872,7 @@ function applyOperation(editor, op) {
6879
6872
  } else if (typeof lastSegment == "number") index = op.position === "after" ? lastSegment + 1 : lastSegment;
6880
6873
  else throw Error(`Cannot apply an "insert" operation at path [${path}] because the last segment is a field name.`);
6881
6874
  if (index > children.length) throw Error(`Cannot apply an "insert" operation at path [${path}] because the destination is past the end of the node.`);
6882
- return !op.inverse && !editor.isProcessingRemoteChanges && (op.inverse = {
6875
+ return !op.inverse && !hasRemoteFrame(editor.applyContext) && (op.inverse = {
6883
6876
  type: "unset",
6884
6877
  path: node._key === void 0 ? path : replaceLastSegment(path, { _key: node._key })
6885
6878
  }), insertChildren(children, index, node);
@@ -6912,7 +6905,7 @@ function applyOperation(editor, op) {
6912
6905
  }
6913
6906
  case "set": {
6914
6907
  let { path, value } = op;
6915
- if (!op.inverse && !editor.isProcessingRemoteChanges) {
6908
+ if (!op.inverse && !hasRemoteFrame(editor.applyContext)) {
6916
6909
  let previousValue = getValue(editor.snapshot.context.value, path), inversePath = path[path.length - 1] === "_key" && typeof value == "string" && isKeyedSegment(path[path.length - 2]) ? [
6917
6910
  ...path.slice(0, -2),
6918
6911
  { _key: value },
@@ -6965,7 +6958,7 @@ function applyOperation(editor, op) {
6965
6958
  case "unset": {
6966
6959
  let { path } = op;
6967
6960
  if (path.length === 0) {
6968
- !op.inverse && !editor.isProcessingRemoteChanges && (op.inverse = {
6961
+ !op.inverse && !hasRemoteFrame(editor.applyContext) && (op.inverse = {
6969
6962
  type: "set",
6970
6963
  path,
6971
6964
  value: editor.snapshot.context.value
@@ -6974,7 +6967,7 @@ function applyOperation(editor, op) {
6974
6967
  }
6975
6968
  let lastSegment = path[path.length - 1];
6976
6969
  if ((isKeyedSegment(lastSegment) || typeof lastSegment == "number") && !targetsStructuralChildren(editor, path)) {
6977
- if (!op.inverse && !editor.isProcessingRemoteChanges) {
6970
+ if (!op.inverse && !hasRemoteFrame(editor.applyContext)) {
6978
6971
  let arrayValue = getValue(editor.snapshot.context.value, path.slice(0, -1));
6979
6972
  Array.isArray(arrayValue) && (op.inverse = {
6980
6973
  type: "set",
@@ -7010,7 +7003,7 @@ function applyOperation(editor, op) {
7010
7003
  modifyChildren(editor, parentPath(path), (children) => {
7011
7004
  let index;
7012
7005
  if (index = isKeyedSegment(lastSegment) ? resolveChildIndex$1(editor.blockIndexMap, path.slice(0, -1), lastSegment, children) : lastSegment, index === -1 || index >= children.length) throw Error(`Cannot apply an "unset" (node removal) operation at path [${path}] because the node was not found.`);
7013
- if (!op.inverse && !editor.isProcessingRemoteChanges) {
7006
+ if (!op.inverse && !hasRemoteFrame(editor.applyContext)) {
7014
7007
  let previousSibling = index > 0 ? children[index - 1] : void 0;
7015
7008
  op.inverse = previousSibling?._key ? {
7016
7009
  type: "insert",
@@ -7030,7 +7023,7 @@ function applyOperation(editor, op) {
7030
7023
  }
7031
7024
  let { nodePath: unsetNodePath, propertyPath: unsetPropertyPath } = splitNodePath(path);
7032
7025
  if (unsetPropertyPath.length === 0 || unsetNodePath.length === 0) break;
7033
- if (!op.inverse && !editor.isProcessingRemoteChanges) {
7026
+ if (!op.inverse && !hasRemoteFrame(editor.applyContext)) {
7034
7027
  let previousValue = getValue(editor.snapshot.context.value, path);
7035
7028
  if (previousValue === void 0) break;
7036
7029
  op.inverse = {
@@ -7161,18 +7154,21 @@ function resolveChildIndex$1(blockIndexMap, parentSegments, segment, children) {
7161
7154
  return index !== void 0 && children[index]?._key === segment._key ? index : children.findIndex((child) => child._key === segment._key);
7162
7155
  }
7163
7156
  /**
7164
- * Extract the block key from the first segment of a path.
7157
+ * Extract the root block reference from the first segment of a path:
7158
+ * keyed, or a numeric index for a node normalization has not keyed yet.
7165
7159
  */
7166
7160
  function findBlockSegment(path) {
7167
7161
  let firstSegment = path[0];
7168
- if (isKeyedSegment(firstSegment)) return firstSegment;
7162
+ if (isKeyedSegment(firstSegment) || typeof firstSegment == "number") return firstSegment;
7169
7163
  }
7170
7164
  /**
7171
7165
  * Resolve a root block's index via `blockIndexMap`, falling back to a
7172
7166
  * linear scan when the map misses or disagrees with the tree.
7173
7167
  */
7174
7168
  function resolveBlockIndex(editor, segment) {
7175
- let value = editor.snapshot.context.value, index = editor.blockIndexMap.get(serializePath([segment]));
7169
+ let value = editor.snapshot.context.value;
7170
+ if (typeof segment == "number") return segment < value.length ? segment : -1;
7171
+ let index = editor.blockIndexMap.get(serializePath([segment]));
7176
7172
  return index !== void 0 && value[index]?._key === segment._key ? index : value.findIndex((block) => block._key === segment._key);
7177
7173
  }
7178
7174
  /**
@@ -7276,7 +7272,12 @@ const apply$1 = (editor, op) => {
7276
7272
  };
7277
7273
  function withoutPatching(editor, fn) {
7278
7274
  let prev = editor.isPatching;
7279
- editor.isPatching = !1, fn(), editor.isPatching = prev;
7275
+ editor.isPatching = !1;
7276
+ try {
7277
+ fn();
7278
+ } finally {
7279
+ editor.isPatching = prev;
7280
+ }
7280
7281
  }
7281
7282
  function isEnd(editor, point, at) {
7282
7283
  return pointEquals(point, end(editor, at));
@@ -7856,7 +7857,7 @@ const normalizeNode = (editor, entry) => {
7856
7857
  /**
7857
7858
  * Merge spans with same set of .marks
7858
7859
  */
7859
- if (!editor.isProcessingRemoteChanges && isTextBlock({ schema: editor.snapshot.context.schema }, node)) {
7860
+ if (!hasRemoteFrame(editor.applyContext) && isTextBlock({ schema: editor.snapshot.context.schema }, node)) {
7860
7861
  let children = getChildren(editor.snapshot, path);
7861
7862
  for (let i = 0; i < children.length - 1; i++) {
7862
7863
  let { node: child } = children[i], { node: nextNode, path: nextChildPath } = children[i + 1];
@@ -7891,35 +7892,15 @@ const normalizeNode = (editor, entry) => {
7891
7892
  });
7892
7893
  return;
7893
7894
  }
7894
- if (nodeRecord._key === void 0 && path.length > 0) {
7895
+ if (!hasUsableKey(nodeRecord._key) && path.length > 0) {
7895
7896
  let newKey = editor.snapshot.context.keyGenerator();
7896
- debug.normalization("Setting missing key on node");
7897
- let numericPath = [], currentNode;
7898
- for (let segment of path) {
7899
- if (typeof segment == "string") {
7900
- currentNode && numericPath.push(segment);
7901
- continue;
7902
- }
7903
- let siblings = currentNode ? currentNode[numericPath[numericPath.length - 1]] ?? [] : editor.snapshot.context.value;
7904
- if (isKeyedSegment(segment) && segment._key !== void 0) numericPath.push(segment), currentNode = Array.prototype.find.call(siblings, (child) => child._key === segment._key);
7905
- else {
7906
- let index = typeof segment == "number" ? segment : -1;
7907
- if (index === -1) {
7908
- for (let i = 0; i < siblings.length; i++) if (siblings[i]._key === void 0) {
7909
- index = i;
7910
- break;
7911
- }
7912
- }
7913
- index !== -1 && (numericPath.push(index), currentNode = siblings[index]);
7914
- }
7915
- }
7916
- editor.apply({
7897
+ debug.normalization("Setting missing key on node"), editor.apply({
7917
7898
  type: "set",
7918
- path: [...numericPath, "_key"],
7899
+ path: [...path, "_key"],
7919
7900
  value: newKey,
7920
7901
  inverse: {
7921
7902
  type: "unset",
7922
- path: [...numericPath, "_key"]
7903
+ path: [...path, "_key"]
7923
7904
  }
7924
7905
  });
7925
7906
  return;
@@ -7961,14 +7942,14 @@ const normalizeNode = (editor, entry) => {
7961
7942
  /**
7962
7943
  * Add missing .markDefs to text block nodes
7963
7944
  */
7964
- if (!editor.isProcessingRemoteChanges && isTextBlockNode({ schema: editor.snapshot.context.schema }, node) && !Array.isArray(node.markDefs)) {
7945
+ if (!hasRemoteFrame(editor.applyContext) && isTextBlockNode({ schema: editor.snapshot.context.schema }, node) && !Array.isArray(node.markDefs)) {
7965
7946
  debug.normalization("adding .markDefs to block node"), applyNodeProperties(editor, { markDefs: [] }, path);
7966
7947
  return;
7967
7948
  }
7968
7949
  /**
7969
7950
  * Add missing .style to text block nodes
7970
7951
  */
7971
- if (!editor.isProcessingRemoteChanges && isTextBlockNode({ schema: editor.snapshot.context.schema }, node) && node.style === void 0) {
7952
+ if (!hasRemoteFrame(editor.applyContext) && isTextBlockNode({ schema: editor.snapshot.context.schema }, node) && node.style === void 0) {
7972
7953
  let defaultStyle = getPathSubSchema(editor.snapshot, path).styles.at(0)?.name;
7973
7954
  if (defaultStyle) {
7974
7955
  debug.normalization("adding .style to block node"), applyNodeProperties(editor, { style: defaultStyle }, path);
@@ -7993,14 +7974,14 @@ const normalizeNode = (editor, entry) => {
7993
7974
  /**
7994
7975
  * Add missing .marks to span nodes
7995
7976
  */
7996
- if (!editor.isProcessingRemoteChanges && isSpan({ schema: editor.snapshot.context.schema }, node) && !Array.isArray(node.marks)) {
7977
+ if (!hasRemoteFrame(editor.applyContext) && isSpan({ schema: editor.snapshot.context.schema }, node) && !Array.isArray(node.marks)) {
7997
7978
  debug.normalization("Adding .marks to span node"), applyNodeProperties(editor, { marks: [] }, path);
7998
7979
  return;
7999
7980
  }
8000
7981
  /**
8001
7982
  * Remove annotations from empty spans
8002
7983
  */
8003
- if (!editor.isProcessingRemoteChanges && isSpan({ schema: editor.snapshot.context.schema }, node)) {
7984
+ if (!hasRemoteFrame(editor.applyContext) && isSpan({ schema: editor.snapshot.context.schema }, node)) {
8004
7985
  let blockPath = parentPath(path), blockEntry = getTextBlock(editor.snapshot, blockPath);
8005
7986
  if (!blockEntry) return;
8006
7987
  let annotations = node.marks?.filter((mark) => blockEntry.node.markDefs?.some((markDef) => markDef._key === mark));
@@ -8012,7 +7993,7 @@ const normalizeNode = (editor, entry) => {
8012
7993
  /**
8013
7994
  * Remove duplicate markDefs
8014
7995
  */
8015
- if (!editor.isProcessingRemoteChanges && isTextBlock({ schema: editor.snapshot.context.schema }, node)) {
7996
+ if (!hasRemoteFrame(editor.applyContext) && isTextBlock({ schema: editor.snapshot.context.schema }, node)) {
8016
7997
  let markDefs = node.markDefs ?? [], markDefKeys = /* @__PURE__ */ new Set(), newMarkDefs = [];
8017
7998
  for (let markDef of markDefs) markDefKeys.has(markDef._key) || (markDefKeys.add(markDef._key), newMarkDefs.push(markDef));
8018
7999
  if (markDefs.length !== newMarkDefs.length) {
@@ -8023,7 +8004,7 @@ const normalizeNode = (editor, entry) => {
8023
8004
  /**
8024
8005
  * Remove markDefs not in use
8025
8006
  */
8026
- if (!editor.isProcessingRemoteChanges && isTextBlock({ schema: editor.snapshot.context.schema }, node)) {
8007
+ if (!hasRemoteFrame(editor.applyContext) && isTextBlock({ schema: editor.snapshot.context.schema }, node)) {
8027
8008
  let newMarkDefs = (node.markDefs || []).filter((def) => node.children.find((child) => isSpan({ schema: editor.snapshot.context.schema }, child) && Array.isArray(child.marks) && child.marks.includes(def._key)));
8028
8009
  if (node.markDefs && !isEqualMarkDefs(newMarkDefs, node.markDefs)) {
8029
8010
  debug.normalization("removing markDef not in use"), applyNodeProperties(editor, { markDefs: newMarkDefs }, path);
@@ -8165,7 +8146,7 @@ const normalizeNode = (editor, entry) => {
8165
8146
  { _key: child._key }
8166
8147
  ];
8167
8148
  if (isSpan({ schema: editor.snapshot.context.schema }, child)) {
8168
- if (prev != null && isSpan({ schema: editor.snapshot.context.schema }, prev) && !editor.isProcessingRemoteChanges) {
8149
+ if (prev != null && isSpan({ schema: editor.snapshot.context.schema }, prev) && !hasRemoteFrame(editor.applyContext)) {
8169
8150
  if (child.text === "") {
8170
8151
  editor.apply({
8171
8152
  type: "unset",
@@ -8259,6 +8240,7 @@ const shouldNormalize = (_editor, { iteration, initialDirtyPathsLength }) => {
8259
8240
  }, createEditor = () => {
8260
8241
  let e = {
8261
8242
  [EDITOR_BRAND]: !0,
8243
+ applyContext: [],
8262
8244
  operations: [],
8263
8245
  operationListeners: {
8264
8246
  before: [],
@@ -8352,13 +8334,25 @@ function collectDescendantIndexes(context, node, nodePath, parent, blockIndexMap
8352
8334
  blockIndexMap.has(childKey) || blockIndexMap.set(childKey, i), collectDescendantIndexes(context, child, childPath, result.parent, blockIndexMap);
8353
8335
  }
8354
8336
  }
8355
- function withRemoteChanges(editor, fn) {
8356
- let prev = editor.isProcessingRemoteChanges;
8357
- editor.isProcessingRemoteChanges = !0, fn(), editor.isProcessingRemoteChanges = prev;
8337
+ function withRemoteChanges(editor, source, fn) {
8338
+ editor.applyContext.push(Object.freeze({
8339
+ kind: "remote",
8340
+ source
8341
+ }));
8342
+ try {
8343
+ fn();
8344
+ } finally {
8345
+ editor.applyContext.pop();
8346
+ }
8358
8347
  }
8359
8348
  function pluginWithoutHistory(editor, fn) {
8360
8349
  let prev = editor.withHistory;
8361
- editor.withHistory = !1, fn(), editor.withHistory = prev;
8350
+ editor.withHistory = !1;
8351
+ try {
8352
+ fn();
8353
+ } finally {
8354
+ editor.withHistory = prev;
8355
+ }
8362
8356
  }
8363
8357
  function cloneDiff(diff2) {
8364
8358
  let [type, patch] = diff2;
@@ -9071,7 +9065,7 @@ function diffMatchPatch$1(editor, patch) {
9071
9065
  return !0;
9072
9066
  }
9073
9067
  function insertPatch(context, editor, patch) {
9074
- let { items, position } = patch, editorWasEmptyBefore = patch.path.length === 1 && isEqualToEmptyEditor(context.initialValue, editor.snapshot.context.value, context.schema) && !isEqualValues({ schema: context.schema }, editor.lastSyncedValue, editor.snapshot.context.value), arrayFieldPath = patch.path.slice(0, -1);
9068
+ let { items, position } = patch, editorWasEmptyBefore = patch.path.length === 1 && isEqualToEmptyEditor(context.initialValue, editor.snapshot.context.value, context.schema) && (editor.valueUnsetEmitted || !isEqualValues({ schema: context.schema }, editor.lastSyncedValue, editor.snapshot.context.value)), arrayFieldPath = patch.path.slice(0, -1);
9075
9069
  for (let index = 0; index < items.length; index++) if (index === 0) editor.apply({
9076
9070
  type: "insert",
9077
9071
  path: patch.path,
@@ -9129,7 +9123,7 @@ function setupRemotePatches({ editorActor, subscriptions, editor }) {
9129
9123
  let patches = bufferedPatches;
9130
9124
  bufferedPatches = [];
9131
9125
  let changed = !1;
9132
- withRemoteChanges(editor, () => {
9126
+ withRemoteChanges(editor, "patches", () => {
9133
9127
  withoutNormalizing(editor, () => {
9134
9128
  withoutPatching(editor, () => {
9135
9129
  pluginWithoutHistory(editor, () => {
@@ -9154,10 +9148,10 @@ function setupRemotePatches({ editorActor, subscriptions, editor }) {
9154
9148
  };
9155
9149
  });
9156
9150
  }
9157
- function createUndoSteps({ steps, op, currentUndoStepId, previousUndoStepId, operationsInProgress, isNormalizingNode, selectionBeforeApply }) {
9151
+ function createUndoSteps({ steps, op, currentUndoStepId, previousUndoStepId, operationsInProgress, isInNormalization, selectionBeforeApply }) {
9158
9152
  let lastStep = steps.at(-1);
9159
9153
  if (!lastStep) return createNewStep(steps, op, selectionBeforeApply);
9160
- if (operationsInProgress) return currentUndoStepId === previousUndoStepId || isNormalizingNode ? mergeIntoLastStep(steps, lastStep, op) : createNewStep(steps, op, selectionBeforeApply);
9154
+ if (operationsInProgress) return currentUndoStepId === previousUndoStepId || isInNormalization ? mergeIntoLastStep(steps, lastStep, op) : createNewStep(steps, op, selectionBeforeApply);
9161
9155
  if (op.type === "set.selection" && currentUndoStepId === void 0 && previousUndoStepId !== void 0 || op.type === "set.selection" && currentUndoStepId !== void 0 && previousUndoStepId !== void 0 && previousUndoStepId !== currentUndoStepId) return mergeIntoLastStep(steps, lastStep, op);
9162
9156
  if (currentUndoStepId === void 0 && previousUndoStepId === void 0) {
9163
9157
  if (op.type === "set.selection") return mergeIntoLastStep(steps, lastStep, op);
@@ -9217,7 +9211,7 @@ function subscribeHistory({ editorActor, subscriptions, editor }) {
9217
9211
  subscription.unsubscribe();
9218
9212
  };
9219
9213
  }), subscribeToOperations(editor, (event) => {
9220
- if (editorActor.getSnapshot().matches({ "edit mode": "read only" }) || event.isProcessingRemoteChanges || event.isUndoing || event.isRedoing) return;
9214
+ if (editorActor.getSnapshot().matches({ "edit mode": "read only" }) || hasRemoteFrame(event.context) || event.origin === "undo" || event.origin === "redo") return;
9221
9215
  let currentUndoStepId = event.undoStepId;
9222
9216
  if (!event.withHistory) {
9223
9217
  previousUndoStepId = currentUndoStepId;
@@ -9234,7 +9228,7 @@ function subscribeHistory({ editorActor, subscriptions, editor }) {
9234
9228
  currentUndoStepId,
9235
9229
  previousUndoStepId,
9236
9230
  operationsInProgress: event.operationsInProgress,
9237
- isNormalizingNode: event.isNormalizingNode,
9231
+ isInNormalization: isInNormalization(event.context),
9238
9232
  selectionBeforeApply: event.beforeSelection
9239
9233
  }); editor.history.undos.length > 1e3;) editor.history.undos.shift();
9240
9234
  previousUndoStepId = currentUndoStepId;
@@ -9264,7 +9258,7 @@ function insertNodePatch(operation) {
9264
9258
  function subscribePatchGeneration({ editorActor, editor }) {
9265
9259
  return subscribeToOperations(editor, (event) => {
9266
9260
  if (!event.isPatching) return;
9267
- let operation = event.operation, previousValue = event.beforeValue, patches = [], { initialValue, schema } = editorActor.getSnapshot().context, editorWasEmpty = previousValue.length === 1 && isEqualToEmptyEditor(initialValue, previousValue, schema) && !isEqualValues({ schema }, editor.lastSyncedValue, previousValue), editorIsEmpty = editor.snapshot.context.value.length === 1 && isEqualToEmptyEditor(initialValue, editor.snapshot.context.value, schema) && !isEqualValues({ schema }, editor.lastSyncedValue, editor.snapshot.context.value);
9261
+ let operation = event.operation, previousValue = event.beforeValue, patches = [], { initialValue, schema } = editorActor.getSnapshot().context, editorWasEmpty = previousValue.length === 1 && isEqualToEmptyEditor(initialValue, previousValue, schema) && (editor.valueUnsetEmitted || !isEqualValues({ schema }, editor.lastSyncedValue, previousValue)), editorIsEmpty = editor.snapshot.context.value.length === 1 && isEqualToEmptyEditor(initialValue, editor.snapshot.context.value, schema) && !isEqualValues({ schema }, editor.lastSyncedValue, editor.snapshot.context.value);
9268
9262
  switch (editorWasEmpty && !editorIsEmpty && operation.type !== "set.selection" && patches.push(insert(previousValue, "before", [0])), operation.type) {
9269
9263
  case "insert.text":
9270
9264
  patches = [...patches, ...textPatch(editor.snapshot, operation, previousValue)];
@@ -9280,11 +9274,15 @@ function subscribePatchGeneration({ editorActor, editor }) {
9280
9274
  break;
9281
9275
  case "unset": patches = [...patches, unset(operation.path)];
9282
9276
  }
9283
- if (!editorWasEmpty && editorIsEmpty && [
9277
+ !editorWasEmpty && editorIsEmpty && [
9284
9278
  "set",
9285
9279
  "unset",
9286
9280
  "remove.text"
9287
- ].includes(operation.type) && (patches = [...patches, unset([])]), editorWasEmpty && patches.length > 0 && (patches = [setIfMissing([], []), ...patches]), patches.length > 0) for (let patch of patches) editorActor.send({
9281
+ ].includes(operation.type) && (patches = [...patches, unset([])]), editorWasEmpty && patches.length > 0 && (patches = [setIfMissing([], []), ...patches], isEqualValues({ schema }, editor.lastSyncedValue, previousValue) && (editor.lastSyncedValue = void 0));
9282
+ let [firstPatch] = patches;
9283
+ previousValue.length === 0 && editor.valueUnsetEmitted && firstPatch && !(firstPatch.type === "unset" && firstPatch.path.length === 0 || (firstPatch.type === "setIfMissing" || firstPatch.type === "set") && firstPatch.path.length === 0) && (patches = [setIfMissing([], []), ...patches]);
9284
+ for (let patch of patches) patch.type === "unset" && patch.path.length === 0 ? editor.valueUnsetEmitted = !0 : (patch.type === "setIfMissing" || patch.type === "set") && patch.path.length === 0 && (editor.valueUnsetEmitted = !1);
9285
+ if (patches.length > 0) for (let patch of patches) editorActor.send({
9288
9286
  type: "internal.patch",
9289
9287
  patch: {
9290
9288
  ...patch,
@@ -9674,7 +9672,7 @@ function invalidateVerifiedGroups(groups, operation) {
9674
9672
  */
9675
9673
  function subscribeUpdateValue(context, editor) {
9676
9674
  let unsubscribeNormalizationLog = debug.normalization.enabled ? subscribeToOperations(editor, (event) => {
9677
- event.isNormalizingNode && debug.normalization(`((engine operation))\n${safeStringify(event.operation, 2)}`);
9675
+ isInNormalization(event.context) && debug.normalization(`((engine operation))\n${safeStringify(event.operation, 2)}`);
9678
9676
  }, { phase: "before" }) : void 0, unsubscribeIndexMaps = subscribeToOperations(editor, (event) => {
9679
9677
  let operation = event.operation;
9680
9678
  operation.type !== "set.selection" && operation.type !== "insert.text" && operation.type !== "remove.text" && (transformBlockIndexMap(editor.blockIndexMap, operation, event.beforeValue, editor.snapshot.context.value, {
@@ -9712,7 +9710,7 @@ function createEditorEngine(config) {
9712
9710
  }, editor.containers = /* @__PURE__ */ new Map(), editor.annotations = /* @__PURE__ */ new Map(), editor.blockObjects = /* @__PURE__ */ new Map(), editor.decorators = /* @__PURE__ */ new Map(), editor.inlineObjects = /* @__PURE__ */ new Map(), editor.spans = /* @__PURE__ */ new Map(), editor.textBlocks = /* @__PURE__ */ new Map(), editor.decoratedRanges = [], editor.blockIndexMap = blockIndexMap, editor.history = {
9713
9711
  undos: [],
9714
9712
  redos: []
9715
- }, editor.selectorChannelsPending = { registrations: !1 }, editor.verifiedUniqueChildGroups = /* @__PURE__ */ new Set(), editor.remotePatches = [], editor.undoStepId = void 0, editor.isDeferringMutations = !1, editor.lastSyncedValue = void 0, editor.isNormalizingNode = !1, editor.isPatching = !0, editor.isPerformingBehaviorOperation = !1, editor.isProcessingRemoteChanges = !1, editor.isRedoing = !1, editor.isUndoing = !1, editor.withHistory = !0;
9713
+ }, editor.selectorChannelsPending = { registrations: !1 }, editor.verifiedUniqueChildGroups = /* @__PURE__ */ new Set(), editor.remotePatches = [], editor.undoStepId = void 0, editor.isDeferringMutations = !1, editor.lastSyncedValue = void 0, editor.valueUnsetEmitted = !1, editor.isPatching = !0, editor.isPerformingBehaviorOperation = !1, editor.withHistory = !0;
9716
9714
  let editorEngine = plugins(withDOM(editor), { editorActor: config.editorActor });
9717
9715
  return subscribeUpdateValue(context, editorEngine), subscribePatchGeneration({
9718
9716
  editorActor: config.editorActor,
@@ -11038,7 +11036,7 @@ const coreListBehaviors = {
11038
11036
  let adjustLevel = !0, listStartBlockFound = !1;
11039
11037
  return [raise$1({
11040
11038
  ...event,
11041
- blocks: event.blocks.map((block) => (block._key === insertedListBlock._key && (listStartBlockFound = !0), adjustLevel ? listStartBlockFound && adjustLevel && isListBlock(snapshot.context, block) ? {
11039
+ blocks: event.blocks.map((block) => (block === insertedListBlock && (listStartBlockFound = !0), adjustLevel ? listStartBlockFound && adjustLevel && isListBlock(snapshot.context, block) ? {
11042
11040
  ...block,
11043
11041
  level: Math.min(10, Math.max(1, block.level + levelDifference))
11044
11042
  } : (listStartBlockFound && (adjustLevel = !1), block) : block))
@@ -11066,7 +11064,7 @@ const coreListBehaviors = {
11066
11064
  let adjustListItem = !0, listStartBlockFound = !1;
11067
11065
  return [raise$1({
11068
11066
  ...event,
11069
- blocks: event.blocks.map((block) => (block._key === insertedListBlock._key && (listStartBlockFound = !0), adjustListItem ? listStartBlockFound && adjustListItem && isListBlock(snapshot.context, block) ? {
11067
+ blocks: event.blocks.map((block) => (block === insertedListBlock && (listStartBlockFound = !0), adjustListItem ? listStartBlockFound && adjustListItem && isListBlock(snapshot.context, block) ? {
11070
11068
  ...block,
11071
11069
  listItem: block.level === insertedListBlock.level ? listItem : block.listItem
11072
11070
  } : (listStartBlockFound && (adjustListItem = !1), block) : block))
@@ -11166,7 +11164,12 @@ function createEditorSnapshot({ converters, editor, keyGenerator, readOnly, sche
11166
11164
  }
11167
11165
  function withPerformingBehaviorOperation(editor, fn) {
11168
11166
  let prev = editor.isPerformingBehaviorOperation;
11169
- editor.isPerformingBehaviorOperation = !0, fn(), editor.isPerformingBehaviorOperation = prev;
11167
+ editor.isPerformingBehaviorOperation = !0;
11168
+ try {
11169
+ fn();
11170
+ } finally {
11171
+ editor.isPerformingBehaviorOperation = prev;
11172
+ }
11170
11173
  }
11171
11174
  function withoutNormalizingConditional(editor, predicate, fn) {
11172
11175
  predicate() ? withoutNormalizing(editor, fn) : fn();
@@ -11180,7 +11183,7 @@ const addAnnotationOperationImplementation = ({ snapshot, operation }) => {
11180
11183
  },
11181
11184
  schema: annotationSchema,
11182
11185
  keyGenerator: context.keyGenerator,
11183
- options: { validateFields: !0 }
11186
+ profile: "strict"
11184
11187
  });
11185
11188
  if (!parsedAnnotation) throw Error(`Failed to parse annotation ${safeStringify(operation.annotation)}`);
11186
11189
  if (!effectiveSelection || isCollapsedRange(effectiveSelection)) return;
@@ -11336,7 +11339,7 @@ const blockSetOperationImplementation = ({ snapshot, operation }) => {
11336
11339
  let { markDefs } = parseMarkDefs({
11337
11340
  keyGenerator: context.keyGenerator,
11338
11341
  markDefs: operation.props[key],
11339
- options: { validateFields: !0 },
11342
+ profile: "strict",
11340
11343
  schema: getPathSubSchema(snapshot, blockEntry.path)
11341
11344
  });
11342
11345
  filteredProps[key] = markDefs;
@@ -12360,8 +12363,12 @@ const deleteOperationImplementation = ({ operation }) => {
12360
12363
  });
12361
12364
  };
12362
12365
  function pluginRedoing(editor, fn) {
12363
- let prev = editor.isRedoing;
12364
- editor.isRedoing = !0, fn(), editor.isRedoing = prev;
12366
+ editor.applyContext.push(Object.freeze({ kind: "redo" }));
12367
+ try {
12368
+ fn();
12369
+ } finally {
12370
+ editor.applyContext.pop();
12371
+ }
12365
12372
  }
12366
12373
  /**
12367
12374
  * This will adjust the operation paths and offsets according to the
@@ -12431,7 +12438,7 @@ const historyRedoOperationImplementation = ({ operation }) => {
12431
12438
  console.error(`Could not perform 'history.redo' operation: ${err instanceof Error ? err.message : err}`), editor.remotePatches.splice(0, editor.remotePatches.length), applyDeselect(editor), editor.history = {
12432
12439
  undos: [],
12433
12440
  redos: []
12434
- }, editor.withHistory = !0, editor.isRedoing = !1, editor.onChange();
12441
+ }, editor.onChange();
12435
12442
  return;
12436
12443
  }
12437
12444
  editor.history.undos.push(step), editor.history.redos.pop();
@@ -12439,8 +12446,12 @@ const historyRedoOperationImplementation = ({ operation }) => {
12439
12446
  }
12440
12447
  };
12441
12448
  function pluginUndoing(editor, fn) {
12442
- let prev = editor.isUndoing;
12443
- editor.isUndoing = !0, fn(), editor.isUndoing = prev;
12449
+ editor.applyContext.push(Object.freeze({ kind: "undo" }));
12450
+ try {
12451
+ fn();
12452
+ } finally {
12453
+ editor.applyContext.pop();
12454
+ }
12444
12455
  }
12445
12456
  function inverseOperation(op) {
12446
12457
  switch (op.type) {
@@ -12536,7 +12547,7 @@ const historyUndoOperationImplementation = ({ operation }) => {
12536
12547
  console.error(`Could not perform 'history.undo' operation: ${err instanceof Error ? err.message : err}`), editor.remotePatches.splice(0, editor.remotePatches.length), applyDeselect(editor), editor.history = {
12537
12548
  undos: [],
12538
12549
  redos: []
12539
- }, editor.withHistory = !0, editor.isUndoing = !1, editor.onChange();
12550
+ }, editor.onChange();
12540
12551
  return;
12541
12552
  }
12542
12553
  editor.history.redos.push(step), editor.history.undos.pop();
@@ -12553,11 +12564,7 @@ const historyUndoOperationImplementation = ({ operation }) => {
12553
12564
  let { context } = snapshot, editor = operation.editor, resolved = operation.at ? resolveSelection(editor, operation.at) : resolveSelection(editor, editor.snapshot.context.selection), at = resolved && operation.at && operation.placement !== "auto" ? operation.at : resolved, destinationPath = at ? operation.placement === "before" ? rangeStart(at, editor.snapshot.context).path : rangeEnd(at, editor.snapshot.context).path : editor.snapshot.context.value.length > 0 ? end(editor, []).path : void 0, schema = destinationPath ? getPathSubSchema(snapshot, destinationPath) : context.schema, parsedBlock = parseBlock({
12554
12565
  block: operation.block,
12555
12566
  keyGenerator: context.keyGenerator,
12556
- options: {
12557
- normalize: !0,
12558
- removeUnusedMarkDefs: !0,
12559
- validateFields: !0
12560
- },
12567
+ profile: "strict",
12561
12568
  schema
12562
12569
  });
12563
12570
  if (!parsedBlock) return;
@@ -12957,13 +12964,11 @@ const insertChildOperationImplementation = ({ snapshot, operation }) => {
12957
12964
  ...focusBlockEntry.path,
12958
12965
  "children",
12959
12966
  focusChildSegment
12960
- ], markDefs = focusBlock.markDefs ?? [], markDefKeyMap = /* @__PURE__ */ new Map();
12961
- for (let markDef of markDefs) markDefKeyMap.set(markDef._key, markDef._key);
12962
- let schema = getPathSubSchema(snapshot, focusBlockEntry.path), span = parseSpan({
12967
+ ], markDefs = focusBlock.markDefs ?? [], markDefKeys = new Set(markDefs.map((markDef) => markDef._key)), schema = getPathSubSchema(snapshot, focusBlockEntry.path), span = parseSpan({
12963
12968
  span: operation.child,
12964
12969
  keyGenerator: context.keyGenerator,
12965
- markDefKeyMap,
12966
- options: { validateFields: !0 },
12970
+ markDefKeys,
12971
+ profile: "strict",
12967
12972
  schema
12968
12973
  });
12969
12974
  if (span) {
@@ -12984,7 +12989,7 @@ const insertChildOperationImplementation = ({ snapshot, operation }) => {
12984
12989
  let inlineObject = parseInlineObject({
12985
12990
  inlineObject: operation.child,
12986
12991
  keyGenerator: context.keyGenerator,
12987
- options: { validateFields: !0 },
12992
+ profile: "strict",
12988
12993
  schema
12989
12994
  });
12990
12995
  if (inlineObject) {
@@ -13077,7 +13082,14 @@ const moveBackwardOperationImplementation = ({ operation }) => {
13077
13082
  if (newSelection) {
13078
13083
  let anchorContainer = getContainer(operation.editor.snapshot, newSelection.anchor.path), focusContainer = getContainer(operation.editor.snapshot, newSelection.focus.path), containers = anchorContainer ? [anchorContainer] : [];
13079
13084
  focusContainer && focusContainer.node !== anchorContainer?.node && containers.push(focusContainer), containers.length > 0 && (withoutNormalizing(operation.editor, () => {
13080
- for (let entry of containers) operation.editor.isNormalizingNode = !0, operation.editor.normalizeNode([entry.node, entry.path]), operation.editor.isNormalizingNode = !1;
13085
+ for (let entry of containers) {
13086
+ operation.editor.applyContext.push(Object.freeze({ kind: "normalization" }));
13087
+ try {
13088
+ operation.editor.normalizeNode([entry.node, entry.path]);
13089
+ } finally {
13090
+ operation.editor.applyContext.pop();
13091
+ }
13092
+ }
13081
13093
  }), newSelection = resolveSelection(operation.editor, operation.at));
13082
13094
  }
13083
13095
  newSelection ? applySelect(operation.editor, newSelection) : applyDeselect(operation.editor), operation.editor.focused && operation.editor.snapshot.context.readOnly && (operation.editor.focused = !1);
@@ -14455,11 +14467,7 @@ const abstractInsertBehaviors = [
14455
14467
  endPoint: blockEndPoint
14456
14468
  }),
14457
14469
  keyGenerator: snapshot.context.keyGenerator,
14458
- options: {
14459
- normalize: !1,
14460
- removeUnusedMarkDefs: !0,
14461
- validateFields: !1
14462
- },
14470
+ profile: "lenient",
14463
14471
  schema: getPathSubSchema(snapshot, focusTextBlock.path)
14464
14472
  });
14465
14473
  return newTextBlock ? {
@@ -15275,7 +15283,7 @@ const editorMachine = setup({
15275
15283
  },
15276
15284
  guards: {
15277
15285
  "engine is busy": ({ context }) => context.editorEngine ? context.editorEngine.operations.length > 0 : !1,
15278
- "engine is normalizing node": ({ context }) => context.editorEngine ? context.editorEngine.isNormalizingNode : !1
15286
+ "engine is normalizing node": ({ context }) => context.editorEngine ? isInNormalization(context.editorEngine.applyContext) : !1
15279
15287
  }
15280
15288
  }).createMachine({
15281
15289
  id: "editor",
@@ -15987,7 +15995,7 @@ const syncValueCallback = ({ sendBack, input }) => {
15987
15995
  "clear pending value": assign({ pendingValue: void 0 }),
15988
15996
  "assign previous value": assign({ previousValue: ({ event }) => (assertEvent(event, "done syncing"), event.value) }),
15989
15997
  "record synced value on engine": ({ context, event }) => {
15990
- assertEvent(event, "done syncing"), context.editorEngine.lastSyncedValue = event.value;
15998
+ assertEvent(event, "done syncing"), event.changed && (context.editorEngine.lastSyncedValue = event.value);
15991
15999
  },
15992
16000
  "emit done syncing value": emit({ type: "done syncing value" }),
15993
16001
  "emit syncing value": emit({ type: "syncing value" })
@@ -15995,11 +16003,11 @@ const syncValueCallback = ({ sendBack, input }) => {
15995
16003
  guards: {
15996
16004
  "initial value synced": ({ context }) => context.initialValueSynced,
15997
16005
  "is busy": ({ context }) => {
15998
- let isBusy = context.editorEngine.isDeferringMutations || context.editorEngine.isProcessingRemoteChanges;
16006
+ let isBusy = context.editorEngine.isDeferringMutations || hasRemoteFrame(context.editorEngine.applyContext);
15999
16007
  return debug.syncValue(safeStringify({
16000
16008
  isBusy,
16001
16009
  isDeferringMutations: context.editorEngine.isDeferringMutations,
16002
- isProcessingRemoteChanges: context.editorEngine.isProcessingRemoteChanges
16010
+ hasRemoteFrame: hasRemoteFrame(context.editorEngine.applyContext)
16003
16011
  })), isBusy;
16004
16012
  },
16005
16013
  "is empty value": ({ event }) => event.type === "update value" && event.value === void 0,
@@ -16149,10 +16157,11 @@ const syncValueCallback = ({ sendBack, input }) => {
16149
16157
  }
16150
16158
  });
16151
16159
  async function updateValue({ context, sendBack, editorEngine, streamBlocks, value }) {
16152
- let doneSyncing = !1, isChanged = !1, isValid = !0, hadSelection = !!editorEngine.snapshot.context.selection;
16160
+ let doneSyncing = !1, isChanged = !1, isValid = !0, hadSelection = !!editorEngine.snapshot.context.selection, remoteSource = streamBlocks ? "initial-sync" : "update-value";
16153
16161
  if ((!value || value.length === 0) && (clearEditor({
16154
16162
  editorEngine,
16155
- doneSyncing
16163
+ doneSyncing,
16164
+ remoteSource
16156
16165
  }), isChanged = !0), value && value.length > 0) {
16157
16166
  if (streamBlocks) await new Promise((resolve) => {
16158
16167
  if (doneSyncing) {
@@ -16161,7 +16170,8 @@ async function updateValue({ context, sendBack, editorEngine, streamBlocks, valu
16161
16170
  }
16162
16171
  isChanged = removeExtraBlocks({
16163
16172
  editorEngine,
16164
- value
16173
+ value,
16174
+ remoteSource
16165
16175
  });
16166
16176
  let processBlocks = async () => {
16167
16177
  for await (let [currentBlock, currentBlockIndex] of getStreamedBlocks({ value })) {
@@ -16171,7 +16181,8 @@ async function updateValue({ context, sendBack, editorEngine, streamBlocks, valu
16171
16181
  block: currentBlock,
16172
16182
  index: currentBlockIndex,
16173
16183
  editorEngine,
16174
- value
16184
+ value,
16185
+ remoteSource
16175
16186
  });
16176
16187
  if (isChanged = blockChanged || isChanged, isValid &&= blockValid, !isValid) break;
16177
16188
  }
@@ -16183,7 +16194,8 @@ async function updateValue({ context, sendBack, editorEngine, streamBlocks, valu
16183
16194
  if (doneSyncing) return;
16184
16195
  isChanged = removeExtraBlocks({
16185
16196
  editorEngine,
16186
- value
16197
+ value,
16198
+ remoteSource
16187
16199
  });
16188
16200
  let index = 0;
16189
16201
  for (let block of value) {
@@ -16193,7 +16205,8 @@ async function updateValue({ context, sendBack, editorEngine, streamBlocks, valu
16193
16205
  block,
16194
16206
  index,
16195
16207
  editorEngine,
16196
- value
16208
+ value,
16209
+ remoteSource
16197
16210
  });
16198
16211
  if (isChanged = blockChanged || isChanged, isValid &&= blockValid, !blockValid) break;
16199
16212
  index++;
@@ -16203,7 +16216,8 @@ async function updateValue({ context, sendBack, editorEngine, streamBlocks, valu
16203
16216
  if (!isValid) {
16204
16217
  debug.syncValue("Invalid value, returning"), doneSyncing = !0, sendBack({
16205
16218
  type: "done syncing",
16206
- value
16219
+ value,
16220
+ changed: isChanged
16207
16221
  });
16208
16222
  return;
16209
16223
  }
@@ -16218,7 +16232,8 @@ async function updateValue({ context, sendBack, editorEngine, streamBlocks, valu
16218
16232
  value
16219
16233
  }), doneSyncing = !0, sendBack({
16220
16234
  type: "done syncing",
16221
- value
16235
+ value,
16236
+ changed: isChanged
16222
16237
  });
16223
16238
  return;
16224
16239
  }
@@ -16229,7 +16244,8 @@ async function updateValue({ context, sendBack, editorEngine, streamBlocks, valu
16229
16244
  } else debug.syncValue("remote value and local value are equal, no need to sync");
16230
16245
  doneSyncing = !0, sendBack({
16231
16246
  type: "done syncing",
16232
- value
16247
+ value,
16248
+ changed: isChanged
16233
16249
  });
16234
16250
  }
16235
16251
  async function* getStreamedBlocks({ value }) {
@@ -16239,8 +16255,8 @@ async function* getStreamedBlocks({ value }) {
16239
16255
  /**
16240
16256
  * Unsets every block; normalization then inserts the empty placeholder block.
16241
16257
  */
16242
- function clearEditor({ editorEngine, doneSyncing }) {
16243
- withRemoteChanges(editorEngine, () => {
16258
+ function clearEditor({ editorEngine, doneSyncing, remoteSource }) {
16259
+ withRemoteChanges(editorEngine, remoteSource, () => {
16244
16260
  withoutNormalizing(editorEngine, () => {
16245
16261
  pluginWithoutHistory(editorEngine, () => {
16246
16262
  withoutPatching(editorEngine, () => {
@@ -16262,9 +16278,9 @@ function clearEditor({ editorEngine, doneSyncing }) {
16262
16278
  * Compare the length of the value and the length of the editor's children, and
16263
16279
  * remove blocks that have become superfluous
16264
16280
  */
16265
- function removeExtraBlocks({ editorEngine, value }) {
16281
+ function removeExtraBlocks({ editorEngine, value, remoteSource }) {
16266
16282
  let isChanged = !1;
16267
- return withRemoteChanges(editorEngine, () => {
16283
+ return withRemoteChanges(editorEngine, remoteSource, () => {
16268
16284
  withoutNormalizing(editorEngine, () => {
16269
16285
  withoutPatching(editorEngine, () => {
16270
16286
  let childrenLength = editorEngine.snapshot.context.value.length;
@@ -16282,13 +16298,13 @@ function removeExtraBlocks({ editorEngine, value }) {
16282
16298
  });
16283
16299
  }), isChanged;
16284
16300
  }
16285
- function syncBlock({ context, sendBack, block, index, editorEngine, value }) {
16301
+ function syncBlock({ context, sendBack, block, index, editorEngine, value, remoteSource }) {
16286
16302
  let oldEngineBlock = editorEngine.snapshot.context.value.at(index), oldBlock = editorEngine.snapshot.context.value.at(index);
16287
16303
  if (!oldEngineBlock || !oldBlock) {
16288
16304
  let validation = validateValue([block], context.schema, context.keyGenerator);
16289
16305
  if (debug.syncValue("Validating and inserting new block in the end of the value", block), validation.valid || validation.resolution?.autoResolve) {
16290
16306
  let engineBlock = toEngineBlock(applyAutoResolution(validation, [block], block), { schemaTypes: context.schema });
16291
- return withRemoteChanges(editorEngine, () => {
16307
+ return withRemoteChanges(editorEngine, remoteSource, () => {
16292
16308
  withoutNormalizing(editorEngine, () => {
16293
16309
  withoutPatching(editorEngine, () => {
16294
16310
  editorEngine.apply({
@@ -16330,7 +16346,7 @@ function syncBlock({ context, sendBack, block, index, editorEngine, value }) {
16330
16346
  });
16331
16347
  })), validation.valid || validation.resolution?.autoResolve) {
16332
16348
  let repairedBlock = applyAutoResolution(validation, validationValue, block);
16333
- return oldBlock._key === block._key && oldBlock._type === block._type ? (debug.syncValue("Updating block", oldBlock, repairedBlock), withRemoteChanges(editorEngine, () => {
16349
+ return oldBlock._key === block._key && oldBlock._type === block._type ? (debug.syncValue("Updating block", oldBlock, repairedBlock), withRemoteChanges(editorEngine, remoteSource, () => {
16334
16350
  withoutNormalizing(editorEngine, () => {
16335
16351
  withoutPatching(editorEngine, () => {
16336
16352
  updateBlock({
@@ -16342,7 +16358,7 @@ function syncBlock({ context, sendBack, block, index, editorEngine, value }) {
16342
16358
  });
16343
16359
  });
16344
16360
  });
16345
- })) : (debug.syncValue("Replacing block", oldBlock, repairedBlock), withRemoteChanges(editorEngine, () => {
16361
+ })) : (debug.syncValue("Replacing block", oldBlock, repairedBlock), withRemoteChanges(editorEngine, remoteSource, () => {
16346
16362
  withoutNormalizing(editorEngine, () => {
16347
16363
  withoutPatching(editorEngine, () => {
16348
16364
  replaceBlock({
@@ -16640,7 +16656,7 @@ function createActors(config) {
16640
16656
  isPublicOperation(event.operation) && config.relay.send({
16641
16657
  type: "operation",
16642
16658
  operation: event.operation,
16643
- origin: event.origin === "remote" ? "remote" : "local"
16659
+ origin: hasRemoteFrame(event.context) ? "remote" : "local"
16644
16660
  });
16645
16661
  })), config.subscriptions.push(() => {
16646
16662
  let subscription = syncActor.on("*", (event) => {