@portabletext/editor 1.1.1 → 1.1.2

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 (51) hide show
  1. package/README.md +3 -0
  2. package/lib/index.d.mts +1667 -0
  3. package/lib/index.d.ts +1667 -0
  4. package/lib/index.esm.js +305 -153
  5. package/lib/index.esm.js.map +1 -1
  6. package/lib/index.js +305 -154
  7. package/lib/index.js.map +1 -1
  8. package/lib/index.mjs +305 -153
  9. package/lib/index.mjs.map +1 -1
  10. package/package.json +23 -22
  11. package/src/editor/Editable.tsx +30 -31
  12. package/src/editor/PortableTextEditor.tsx +23 -6
  13. package/src/editor/__tests__/PortableTextEditor.test.tsx +9 -9
  14. package/src/editor/__tests__/PortableTextEditorTester.tsx +2 -5
  15. package/src/editor/__tests__/RangeDecorations.test.tsx +2 -2
  16. package/src/editor/__tests__/handleClick.test.tsx +27 -7
  17. package/src/editor/__tests__/insert-block.test.tsx +4 -4
  18. package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +7 -7
  19. package/src/editor/__tests__/self-solving.test.tsx +176 -0
  20. package/src/editor/components/Leaf.tsx +28 -23
  21. package/src/editor/components/Synchronizer.tsx +60 -32
  22. package/src/editor/editor-machine.ts +195 -0
  23. package/src/editor/hooks/usePortableTextEditorSelection.tsx +11 -13
  24. package/src/editor/hooks/useSyncValue.test.tsx +9 -9
  25. package/src/editor/hooks/useSyncValue.ts +14 -13
  26. package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +1 -1
  27. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +28 -28
  28. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +17 -17
  29. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +8 -8
  30. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +5 -5
  31. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +2 -2
  32. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +46 -46
  33. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +22 -11
  34. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +9 -9
  35. package/src/editor/plugins/createWithInsertData.ts +4 -8
  36. package/src/editor/plugins/createWithObjectKeys.ts +7 -0
  37. package/src/editor/plugins/createWithPatches.ts +5 -6
  38. package/src/editor/plugins/createWithPortableTextBlockStyle.ts +10 -2
  39. package/src/editor/plugins/createWithPortableTextMarkModel.ts +20 -4
  40. package/src/editor/plugins/createWithPortableTextSelections.ts +4 -5
  41. package/src/editor/plugins/createWithSchemaTypes.ts +9 -0
  42. package/src/editor/plugins/index.ts +18 -8
  43. package/src/index.ts +9 -3
  44. package/src/utils/__tests__/dmpToOperations.test.ts +1 -1
  45. package/src/utils/__tests__/operationToPatches.test.ts +61 -61
  46. package/src/utils/__tests__/patchToOperations.test.ts +39 -39
  47. package/src/utils/__tests__/ranges.test.ts +1 -1
  48. package/src/utils/__tests__/valueNormalization.test.tsx +14 -2
  49. package/src/utils/__tests__/values.test.ts +17 -17
  50. package/src/utils/validateValue.ts +0 -22
  51. package/src/editor/__tests__/utils.ts +0 -44
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var jsxRuntime = require("react/jsx-runtime"), isEqual = require("lodash/isEqual.js"), noop = require("lodash/noop.js"), react = require("react"), slate = require("slate"), slateReact = require("slate-react"), debug$m = require("debug"), types = require("@sanity/types"), styledComponents = require("styled-components"), uniq = require("lodash/uniq.js"), rxjs = require("rxjs"), schema = require("@sanity/schema"), patches = require("@portabletext/patches"), get = require("lodash/get.js"), isUndefined = require("lodash/isUndefined.js"), omitBy = require("lodash/omitBy.js"), flatten = require("lodash/flatten.js"), isHotkeyEsm = require("is-hotkey-esm"), blockTools = require("@sanity/block-tools"), isPlainObject = require("lodash/isPlainObject.js"), throttle = require("lodash/throttle.js"), content = require("@sanity/util/content"), debounce = require("lodash/debounce.js");
3
+ var jsxRuntime = require("react/jsx-runtime"), isEqual = require("lodash/isEqual.js"), noop = require("lodash/noop.js"), react = require("react"), slate = require("slate"), slateReact = require("slate-react"), debug$m = require("debug"), types = require("@sanity/types"), styledComponents = require("styled-components"), uniq = require("lodash/uniq.js"), rxjs = require("rxjs"), xstate = require("xstate"), schema = require("@sanity/schema"), patches = require("@portabletext/patches"), get = require("lodash/get.js"), isUndefined = require("lodash/isUndefined.js"), omitBy = require("lodash/omitBy.js"), flatten = require("lodash/flatten.js"), isHotkeyEsm = require("is-hotkey-esm"), blockTools = require("@sanity/block-tools"), isPlainObject = require("lodash/isPlainObject.js"), throttle = require("lodash/throttle.js"), content = require("@sanity/util/content"), debounce = require("lodash/debounce.js");
4
4
  function _interopDefaultCompat(e) {
5
5
  return e && typeof e == "object" && "default" in e ? e : { default: e };
6
6
  }
@@ -110,7 +110,7 @@ function normalizeSelection(selection, value) {
110
110
  const { anchor, focus } = selection;
111
111
  return anchor && value.find((blk) => isEqual__default.default({ _key: blk._key }, anchor.path[0])) && (newAnchor = normalizePoint(anchor, value)), focus && value.find((blk) => isEqual__default.default({ _key: blk._key }, focus.path[0])) && (newFocus = normalizePoint(focus, value)), newAnchor && newFocus ? { anchor: newAnchor, focus: newFocus, backward: selection.backward } : null;
112
112
  }
113
- const EMPTY_MARKDEFS = [], VOID_CHILD_KEY = "void-child";
113
+ const VOID_CHILD_KEY = "void-child";
114
114
  function keepObjectEquality(object, keyMap) {
115
115
  const value = keyMap[object._key];
116
116
  return value && isEqual__default.default(object, value) ? value : (keyMap[object._key] = object, object);
@@ -1694,7 +1694,7 @@ function createWithMaxBlocks(maxBlocks) {
1694
1694
  }, editor;
1695
1695
  };
1696
1696
  }
1697
- function createWithObjectKeys(schemaTypes, keyGenerator) {
1697
+ function createWithObjectKeys(editorActor, schemaTypes, keyGenerator) {
1698
1698
  return function(editor) {
1699
1699
  const { apply: apply2, normalizeNode } = editor;
1700
1700
  return editor.apply = (operation) => {
@@ -1730,10 +1730,13 @@ function createWithObjectKeys(schemaTypes, keyGenerator) {
1730
1730
  }, editor.normalizeNode = (entry) => {
1731
1731
  const [node, path] = entry;
1732
1732
  if (slate.Element.isElement(node) && node._type === schemaTypes.block.name) {
1733
- node._key || slate.Transforms.setNodes(editor, { _key: keyGenerator() }, { at: path });
1733
+ if (!node._key) {
1734
+ editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(editor, { _key: keyGenerator() }, { at: path }), editorActor.send({ type: "done normalizing" });
1735
+ return;
1736
+ }
1734
1737
  for (const [child, childPath] of slate.Node.children(editor, path))
1735
1738
  if (!child._key) {
1736
- slate.Transforms.setNodes(editor, { _key: keyGenerator() }, { at: childPath });
1739
+ editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(editor, { _key: keyGenerator() }, { at: childPath }), editorActor.send({ type: "done normalizing" });
1737
1740
  return;
1738
1741
  }
1739
1742
  }
@@ -2890,7 +2893,7 @@ function findOperationTargetBlock(editor, operation) {
2890
2893
  }
2891
2894
  const debug$g = debugWithName("plugin:withPatches");
2892
2895
  function createWithPatches({
2893
- change$,
2896
+ editorActor,
2894
2897
  patches$,
2895
2898
  patchFunctions,
2896
2899
  readOnly,
@@ -3019,7 +3022,7 @@ function createWithPatches({
3019
3022
  }
3020
3023
  return !editorWasEmpty && editorIsEmpty && ["merge_node", "set_node", "remove_text", "remove_node"].includes(
3021
3024
  operation.type
3022
- ) && (patches$1 = [...patches$1, patches.unset([])], change$.next({
3025
+ ) && (patches$1 = [...patches$1, patches.unset([])], editorActor.send({
3023
3026
  type: "unset",
3024
3027
  previousValue: fromSlateValue(
3025
3028
  previousChildren,
@@ -3027,7 +3030,7 @@ function createWithPatches({
3027
3030
  KEY_TO_VALUE_ELEMENT.get(editor)
3028
3031
  )
3029
3032
  })), editorWasEmpty && patches$1.length > 0 && (patches$1 = [patches.setIfMissing([], []), ...patches$1]), patches$1.length > 0 && patches$1.forEach((patch) => {
3030
- change$.next({
3033
+ editorActor.send({
3031
3034
  type: "patch",
3032
3035
  patch: { ...patch, origin: "local" }
3033
3036
  });
@@ -3063,25 +3066,25 @@ function createWithPlaceholderBlock() {
3063
3066
  };
3064
3067
  }
3065
3068
  const debug$e = debugWithName("plugin:withPortableTextBlockStyle");
3066
- function createWithPortableTextBlockStyle(types2) {
3069
+ function createWithPortableTextBlockStyle(editorActor, types2) {
3067
3070
  const defaultStyle = types2.styles[0].value;
3068
3071
  return function(editor) {
3069
3072
  const { normalizeNode } = editor;
3070
3073
  return editor.normalizeNode = (nodeEntry) => {
3071
- normalizeNode(nodeEntry);
3072
3074
  const [, path] = nodeEntry;
3073
3075
  for (const op of editor.operations)
3074
3076
  if (op.type === "split_node" && op.path.length === 1 && editor.isTextBlock(op.properties) && op.properties.style !== defaultStyle && op.path[0] === path[0] && !slate.Path.equals(path, op.path)) {
3075
3077
  const [child] = slate.Editor.node(editor, [op.path[0] + 1, 0]);
3076
3078
  if (slate.Text.isText(child) && child.text === "") {
3077
- debug$e(`Normalizing split node to ${defaultStyle} style`, op), slate.Transforms.setNodes(
3079
+ debug$e(`Normalizing split node to ${defaultStyle} style`, op), editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(
3078
3080
  editor,
3079
3081
  { style: defaultStyle },
3080
3082
  { at: [op.path[0] + 1], voids: !1 }
3081
- );
3082
- break;
3083
+ ), editorActor.send({ type: "done normalizing" });
3084
+ return;
3083
3085
  }
3084
3086
  }
3087
+ normalizeNode(nodeEntry);
3085
3088
  }, editor.pteHasBlockStyle = (style) => editor.selection ? [
3086
3089
  ...slate.Editor.nodes(editor, {
3087
3090
  at: editor.selection,
@@ -3226,7 +3229,7 @@ function isPortableTextBlock(node) {
3226
3229
  );
3227
3230
  }
3228
3231
  const debug$c = debugWithName("plugin:withPortableTextMarkModel");
3229
- function createWithPortableTextMarkModel(types2, change$, keyGenerator) {
3232
+ function createWithPortableTextMarkModel(editorActor, types2, keyGenerator) {
3230
3233
  return function(editor) {
3231
3234
  const { apply: apply2, normalizeNode } = editor, decorators = types2.decorators.map((t) => t.value), forceNewSelection = () => {
3232
3235
  editor.selection && (slate.Transforms.select(editor, { ...editor.selection }), editor.selection = { ...editor.selection });
@@ -3235,7 +3238,7 @@ function createWithPortableTextMarkModel(types2, change$, keyGenerator) {
3235
3238
  editor.selection,
3236
3239
  types2
3237
3240
  );
3238
- change$.next({ type: "selection", selection: ptRange });
3241
+ editorActor.send({ type: "selection", selection: ptRange });
3239
3242
  };
3240
3243
  return editor.normalizeNode = (nodeEntry) => {
3241
3244
  const [node, path] = nodeEntry;
@@ -3248,20 +3251,20 @@ function createWithPortableTextMarkModel(types2, change$, keyGenerator) {
3248
3251
  "Merging spans",
3249
3252
  JSON.stringify(child, null, 2),
3250
3253
  JSON.stringify(nextNode, null, 2)
3251
- ), slate.Transforms.mergeNodes(editor, {
3254
+ ), editorActor.send({ type: "normalizing" }), slate.Transforms.mergeNodes(editor, {
3252
3255
  at: [childPath[0], childPath[1] + 1],
3253
3256
  voids: !0
3254
- });
3257
+ }), editorActor.send({ type: "done normalizing" });
3255
3258
  return;
3256
3259
  }
3257
3260
  }
3258
3261
  }
3259
3262
  if (editor.isTextBlock(node) && !Array.isArray(node.markDefs)) {
3260
- debug$c("Adding .markDefs to block node"), slate.Transforms.setNodes(editor, { markDefs: [] }, { at: path });
3263
+ debug$c("Adding .markDefs to block node"), editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(editor, { markDefs: [] }, { at: path }), editorActor.send({ type: "done normalizing" });
3261
3264
  return;
3262
3265
  }
3263
3266
  if (editor.isTextSpan(node) && !Array.isArray(node.marks)) {
3264
- debug$c("Adding .marks to span node"), slate.Transforms.setNodes(editor, { marks: [] }, { at: path });
3267
+ debug$c("Adding .marks to span node"), editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(editor, { marks: [] }, { at: path }), editorActor.send({ type: "done normalizing" });
3265
3268
  return;
3266
3269
  }
3267
3270
  if (editor.isTextSpan(node)) {
@@ -3269,11 +3272,11 @@ function createWithPortableTextMarkModel(types2, change$, keyGenerator) {
3269
3272
  (mark) => !decorators2.includes(mark)
3270
3273
  );
3271
3274
  if (editor.isTextBlock(block) && node.text === "" && annotations && annotations.length > 0) {
3272
- debug$c("Removing annotations from empty span node"), slate.Transforms.setNodes(
3275
+ debug$c("Removing annotations from empty span node"), editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(
3273
3276
  editor,
3274
3277
  { marks: node.marks?.filter((mark) => decorators2.includes(mark)) },
3275
3278
  { at: path }
3276
- );
3279
+ ), editorActor.send({ type: "done normalizing" });
3277
3280
  return;
3278
3281
  }
3279
3282
  }
@@ -3283,7 +3286,7 @@ function createWithPortableTextMarkModel(types2, change$, keyGenerator) {
3283
3286
  if (editor.isTextSpan(child)) {
3284
3287
  const marks = child.marks ?? [], orphanedAnnotations = marks.filter((mark) => !decorators2.includes(mark) && !node.markDefs?.find((def) => def._key === mark));
3285
3288
  if (orphanedAnnotations.length > 0) {
3286
- debug$c("Removing orphaned annotations from span node"), slate.Transforms.setNodes(
3289
+ debug$c("Removing orphaned annotations from span node"), editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(
3287
3290
  editor,
3288
3291
  {
3289
3292
  marks: marks.filter(
@@ -3291,7 +3294,7 @@ function createWithPortableTextMarkModel(types2, change$, keyGenerator) {
3291
3294
  )
3292
3295
  },
3293
3296
  { at: childPath }
3294
- );
3297
+ ), editorActor.send({ type: "done normalizing" });
3295
3298
  return;
3296
3299
  }
3297
3300
  }
@@ -3303,7 +3306,7 @@ function createWithPortableTextMarkModel(types2, change$, keyGenerator) {
3303
3306
  (decorator) => decorator.value
3304
3307
  ), marks = node.marks ?? [], orphanedAnnotations = marks.filter((mark) => !decorators2.includes(mark) && !block.markDefs?.find((def) => def._key === mark));
3305
3308
  if (orphanedAnnotations.length > 0) {
3306
- debug$c("Removing orphaned annotations from span node"), slate.Transforms.setNodes(
3309
+ debug$c("Removing orphaned annotations from span node"), editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(
3307
3310
  editor,
3308
3311
  {
3309
3312
  marks: marks.filter(
@@ -3311,7 +3314,7 @@ function createWithPortableTextMarkModel(types2, change$, keyGenerator) {
3311
3314
  )
3312
3315
  },
3313
3316
  { at: path }
3314
- );
3317
+ ), editorActor.send({ type: "done normalizing" });
3315
3318
  return;
3316
3319
  }
3317
3320
  }
@@ -3320,20 +3323,23 @@ function createWithPortableTextMarkModel(types2, change$, keyGenerator) {
3320
3323
  const markDefs = node.markDefs ?? [], markDefKeys = /* @__PURE__ */ new Set(), newMarkDefs = [];
3321
3324
  for (const markDef of markDefs)
3322
3325
  markDefKeys.has(markDef._key) || (markDefKeys.add(markDef._key), newMarkDefs.push(markDef));
3323
- markDefs.length !== newMarkDefs.length && (debug$c("Removing duplicate markDefs"), slate.Transforms.setNodes(editor, { markDefs: newMarkDefs }, { at: path }));
3326
+ if (markDefs.length !== newMarkDefs.length) {
3327
+ debug$c("Removing duplicate markDefs"), editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(editor, { markDefs: newMarkDefs }, { at: path }), editorActor.send({ type: "done normalizing" });
3328
+ return;
3329
+ }
3324
3330
  }
3325
3331
  if (editor.isTextBlock(node) && !editor.operations.some(
3326
3332
  (op) => op.type === "merge_node" && "markDefs" in op.properties && op.path.length === 1
3327
3333
  )) {
3328
3334
  const newMarkDefs = (node.markDefs || []).filter((def) => node.children.find((child) => slate.Text.isText(child) && Array.isArray(child.marks) && child.marks.includes(def._key)));
3329
3335
  if (node.markDefs && !isEqual__default.default(newMarkDefs, node.markDefs)) {
3330
- debug$c("Removing markDef not in use"), slate.Transforms.setNodes(
3336
+ debug$c("Removing markDef not in use"), editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(
3331
3337
  editor,
3332
3338
  {
3333
3339
  markDefs: newMarkDefs
3334
3340
  },
3335
3341
  { at: path }
3336
- );
3342
+ ), editorActor.send({ type: "done normalizing" });
3337
3343
  return;
3338
3344
  }
3339
3345
  }
@@ -3566,7 +3572,7 @@ function createWithPortableTextMarkModel(types2, change$, keyGenerator) {
3566
3572
  };
3567
3573
  }
3568
3574
  const debug$b = debugWithName("plugin:withPortableTextSelections"), debugVerbose$2 = debug$b.enabled && !1;
3569
- function createWithPortableTextSelections(change$, types2) {
3575
+ function createWithPortableTextSelections(editorActor, types2) {
3570
3576
  let prevSelection = null;
3571
3577
  return function(editor) {
3572
3578
  const emitPortableTextSelection = () => {
@@ -3585,7 +3591,7 @@ function createWithPortableTextSelections(change$, types2) {
3585
3591
  `Emitting selection ${JSON.stringify(ptRange || null)} (${JSON.stringify(
3586
3592
  editor.selection
3587
3593
  )})`
3588
- ), ptRange ? change$.next({ type: "selection", selection: ptRange }) : change$.next({ type: "selection", selection: null });
3594
+ ), ptRange ? editorActor.send({ type: "selection", selection: ptRange }) : editorActor.send({ type: "selection", selection: null });
3589
3595
  }
3590
3596
  prevSelection = editor.selection;
3591
3597
  }, { onChange } = editor;
@@ -3597,6 +3603,7 @@ function createWithPortableTextSelections(change$, types2) {
3597
3603
  }
3598
3604
  const debug$a = debugWithName("plugin:withSchemaTypes");
3599
3605
  function createWithSchemaTypes({
3606
+ editorActor,
3600
3607
  schemaTypes,
3601
3608
  keyGenerator
3602
3609
  }) {
@@ -3608,16 +3615,18 @@ function createWithSchemaTypes({
3608
3615
  if (node._type === void 0 && path.length === 2) {
3609
3616
  debug$a("Setting span type on text node without a type");
3610
3617
  const span = node, key = span._key || keyGenerator();
3611
- slate.Transforms.setNodes(
3618
+ editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(
3612
3619
  editor,
3613
3620
  { ...span, _type: schemaTypes.span.name, _key: key },
3614
3621
  { at: path }
3615
- );
3622
+ ), editorActor.send({ type: "done normalizing" });
3623
+ return;
3616
3624
  }
3617
3625
  if (node._key === void 0 && (path.length === 1 || path.length === 2)) {
3618
3626
  debug$a("Setting missing key on child node without a key");
3619
3627
  const key = keyGenerator();
3620
- slate.Transforms.setNodes(editor, { _key: key }, { at: path });
3628
+ editorActor.send({ type: "normalizing" }), slate.Transforms.setNodes(editor, { _key: key }, { at: path }), editorActor.send({ type: "done normalizing" });
3629
+ return;
3621
3630
  }
3622
3631
  normalizeNode(entry);
3623
3632
  }, editor;
@@ -3925,22 +3934,6 @@ function validateValue(value, types$1, keyGenerator) {
3925
3934
  }
3926
3935
  }, !0;
3927
3936
  }
3928
- if (blk.markDefs && !Array.isArray(blk.markDefs))
3929
- return resolution = {
3930
- patches: [
3931
- patches.set({ ...textBlock, markDefs: EMPTY_MARKDEFS }, [
3932
- { _key: textBlock._key }
3933
- ])
3934
- ],
3935
- description: "Block has invalid required property 'markDefs'.",
3936
- action: "Add empty markDefs array",
3937
- item: textBlock,
3938
- i18n: {
3939
- description: "inputs.portable-text.invalid-value.missing-or-invalid-markdefs.description",
3940
- action: "inputs.portable-text.invalid-value.missing-or-invalid-markdefs.action",
3941
- values: { key: textBlock._key }
3942
- }
3943
- }, !0;
3944
3937
  const allUsedMarks = uniq__default.default(
3945
3938
  flatten__default.default(
3946
3939
  textBlock.children.filter((cld) => cld._type === types$1.span.name).map((cld) => cld.marks || [])
@@ -4085,7 +4078,7 @@ function validateValue(value, types$1, keyGenerator) {
4085
4078
  }) && (valid = !1), { valid, resolution, value });
4086
4079
  }
4087
4080
  const debug$7 = debugWithName("plugin:withInsertData");
4088
- function createWithInsertData(change$, schemaTypes, keyGenerator) {
4081
+ function createWithInsertData(editorActor, schemaTypes, keyGenerator) {
4089
4082
  return function(editor) {
4090
4083
  const blockTypeName = schemaTypes.block.name, spanTypeName = schemaTypes.span.name, whitespaceOnPasteMode = schemaTypes.block.options.unstable_whitespaceOnPasteMode, toPlainText = (blocks) => blocks.map((block) => editor.isTextBlock(block) ? block.children.map((child) => child._type === spanTypeName ? child.text : `[${schemaTypes.inlineObjects.find((t) => t.name === child._type)?.title || "Object"}]`).join("") : `[${schemaTypes.blockObjects.find((t) => t.name === block._type)?.title || "Object"}]`).join(`
4091
4084
 
@@ -4139,9 +4132,8 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
4139
4132
  ), validation = validateValue(parsed, schemaTypes, keyGenerator);
4140
4133
  if (!validation.valid && !validation.resolution?.autoResolve) {
4141
4134
  const errorDescription = `${validation.resolution?.description}`;
4142
- return change$.next({
4135
+ return editorActor.send({
4143
4136
  type: "error",
4144
- level: "warning",
4145
4137
  name: "pasteError",
4146
4138
  description: errorDescription,
4147
4139
  data: validation
@@ -4154,7 +4146,6 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
4154
4146
  }, editor.insertTextOrHTMLData = (data) => {
4155
4147
  if (!editor.selection)
4156
4148
  return debug$7("No selection, not inserting"), !1;
4157
- change$.next({ type: "loading", isLoading: !0 });
4158
4149
  const html = data.getData("text/html"), text = data.getData("text/plain");
4159
4150
  if (html || text) {
4160
4151
  debug$7("Inserting data", data);
@@ -4185,9 +4176,8 @@ function createWithInsertData(change$, schemaTypes, keyGenerator) {
4185
4176
  const errorDescription = `Could not validate the resulting portable text to insert.
4186
4177
  ${validation.resolution?.description}
4187
4178
  Try to insert as plain text (shift-paste) instead.`;
4188
- return change$.next({
4179
+ return editorActor.send({
4189
4180
  type: "error",
4190
- level: "warning",
4191
4181
  name: "pasteError",
4192
4182
  description: errorDescription,
4193
4183
  data: validation
@@ -4195,9 +4185,9 @@ Try to insert as plain text (shift-paste) instead.`;
4195
4185
  }
4196
4186
  return debug$7(
4197
4187
  `Inserting ${insertedType} fragment at ${JSON.stringify(editor.selection)}`
4198
- ), _insertFragment(editor, fragment, schemaTypes), change$.next({ type: "loading", isLoading: !1 }), !0;
4188
+ ), _insertFragment(editor, fragment, schemaTypes), !0;
4199
4189
  }
4200
- return change$.next({ type: "loading", isLoading: !1 }), !1;
4190
+ return !1;
4201
4191
  }, editor.insertData = (data) => {
4202
4192
  editor.insertPortableTextData(data) || editor.insertTextOrHTMLData(data);
4203
4193
  }, editor.insertFragmentData = (data) => {
@@ -4284,18 +4274,26 @@ function _insertFragment(editor, fragment, schemaTypes) {
4284
4274
  }), editor.onChange();
4285
4275
  }
4286
4276
  const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, options) => {
4287
- const e = editor, { keyGenerator, portableTextEditor, patches$, readOnly, maxBlocks } = options, { schemaTypes, change$ } = portableTextEditor;
4277
+ const e = editor, { keyGenerator, portableTextEditor, patches$, readOnly, maxBlocks } = options, { editorActor, schemaTypes } = portableTextEditor;
4288
4278
  e.subscriptions = [], e.destroy ? e.destroy() : originalFnMap.set(e, {
4289
4279
  apply: e.apply,
4290
4280
  onChange: e.onChange,
4291
4281
  normalizeNode: e.normalizeNode
4292
4282
  });
4293
- const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(schemaTypes, keyGenerator), withSchemaTypes = createWithSchemaTypes({ schemaTypes, keyGenerator }), withEditableAPI = createWithEditableAPI(
4283
+ const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(
4284
+ editorActor,
4285
+ schemaTypes,
4286
+ keyGenerator
4287
+ ), withSchemaTypes = createWithSchemaTypes({
4288
+ editorActor,
4289
+ schemaTypes,
4290
+ keyGenerator
4291
+ }), withEditableAPI = createWithEditableAPI(
4294
4292
  portableTextEditor,
4295
4293
  schemaTypes,
4296
4294
  keyGenerator
4297
4295
  ), withPatches = createWithPatches({
4298
- change$,
4296
+ editorActor,
4299
4297
  keyGenerator,
4300
4298
  patches$,
4301
4299
  patchFunctions: operationToPatches,
@@ -4306,15 +4304,18 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
4306
4304
  patches$,
4307
4305
  blockSchemaType: schemaTypes.block
4308
4306
  }), withPortableTextMarkModel = createWithPortableTextMarkModel(
4307
+ editorActor,
4309
4308
  schemaTypes,
4310
- change$,
4311
4309
  keyGenerator
4312
- ), withPortableTextBlockStyle = createWithPortableTextBlockStyle(schemaTypes), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(schemaTypes, keyGenerator), withUtils = createWithUtils({
4310
+ ), withPortableTextBlockStyle = createWithPortableTextBlockStyle(
4311
+ editorActor,
4312
+ schemaTypes
4313
+ ), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(schemaTypes, keyGenerator), withUtils = createWithUtils({
4313
4314
  keyGenerator,
4314
4315
  schemaTypes,
4315
4316
  portableTextEditor
4316
4317
  }), withPortableTextSelections = createWithPortableTextSelections(
4317
- change$,
4318
+ editorActor,
4318
4319
  schemaTypes
4319
4320
  );
4320
4321
  return e.destroy = () => {
@@ -4431,7 +4432,7 @@ const defaultKeyGenerator = () => content.randomKey(12), PortableTextEditorKeyGe
4431
4432
  return readOnly;
4432
4433
  }, debug$5 = debugWithName("hook:useSyncValue"), CURRENT_VALUE = /* @__PURE__ */ new WeakMap();
4433
4434
  function useSyncValue(props) {
4434
- const { portableTextEditor, readOnly, keyGenerator } = props, { change$, schemaTypes } = portableTextEditor, previousValue = react.useRef(), slateEditor = slateReact.useSlate(), updateValueFunctionRef = react.useRef(), updateFromCurrentValue = react.useCallback(() => {
4435
+ const { editorActor, portableTextEditor, readOnly, keyGenerator } = props, { schemaTypes } = portableTextEditor, previousValue = react.useRef(), slateEditor = slateReact.useSlate(), updateValueFunctionRef = react.useRef(), updateFromCurrentValue = react.useCallback(() => {
4435
4436
  const currentValue = CURRENT_VALUE.get(portableTextEditor);
4436
4437
  if (previousValue.current === currentValue) {
4437
4438
  debug$5("Value is the same object as previous, not need to sync");
@@ -4502,7 +4503,7 @@ function useSyncValue(props) {
4502
4503
  !validation.valid && validation.resolution?.autoResolve && validation.resolution?.patches.length > 0 && !readOnly && previousValue.current && previousValue.current !== value && (console.warn(
4503
4504
  `${validation.resolution.action} for block with _key '${validationValue[0]._key}'. ${validation.resolution?.description}`
4504
4505
  ), validation.resolution.patches.forEach((patch) => {
4505
- change$.next({ type: "patch", patch });
4506
+ editorActor.send({ type: "patch", patch });
4506
4507
  })), validation.valid || validation.resolution?.autoResolve ? (oldBlock._key === currentBlock._key ? (debug$5.enabled && debug$5("Updating block", oldBlock, currentBlock), _updateBlock(
4507
4508
  slateEditor,
4508
4509
  currentBlock,
@@ -4512,8 +4513,8 @@ function useSyncValue(props) {
4512
4513
  slateEditor,
4513
4514
  currentBlock,
4514
4515
  currentBlockIndex
4515
- )), isChanged = !0) : (change$.next({
4516
- type: "invalidValue",
4516
+ )), isChanged = !0) : (editorActor.send({
4517
+ type: "invalid value",
4517
4518
  resolution: validation.resolution,
4518
4519
  value
4519
4520
  }), isValid = !1);
@@ -4529,8 +4530,8 @@ function useSyncValue(props) {
4529
4530
  currentBlock
4530
4531
  ), validation.valid || validation.resolution?.autoResolve ? slate.Transforms.insertNodes(slateEditor, currentBlock, {
4531
4532
  at: [currentBlockIndex]
4532
- }) : (debug$5("Invalid", validation), change$.next({
4533
- type: "invalidValue",
4533
+ }) : (debug$5("Invalid", validation), editorActor.send({
4534
+ type: "invalid value",
4534
4535
  resolution: validation.resolution,
4535
4536
  value
4536
4537
  }), isValid = !1);
@@ -4551,8 +4552,8 @@ function useSyncValue(props) {
4551
4552
  try {
4552
4553
  slateEditor.onChange();
4553
4554
  } catch (err) {
4554
- console.error(err), change$.next({
4555
- type: "invalidValue",
4555
+ console.error(err), editorActor.send({
4556
+ type: "invalid value",
4556
4557
  resolution: null,
4557
4558
  value
4558
4559
  });
@@ -4561,14 +4562,14 @@ function useSyncValue(props) {
4561
4562
  hadSelection && !slateEditor.selection && (slate.Transforms.select(slateEditor, {
4562
4563
  anchor: { path: [0, 0], offset: 0 },
4563
4564
  focus: { path: [0, 0], offset: 0 }
4564
- }), slateEditor.onChange()), change$.next({ type: "value", value });
4565
+ }), slateEditor.onChange()), editorActor.send({ type: "value changed", value });
4565
4566
  } else
4566
4567
  debug$5("Server value and editor value is equal, no need to sync.");
4567
4568
  previousValue.current = value;
4568
4569
  };
4569
4570
  return updateValueFunctionRef.current = updateFunction, updateFunction;
4570
4571
  }, [
4571
- change$,
4572
+ editorActor,
4572
4573
  keyGenerator,
4573
4574
  portableTextEditor,
4574
4575
  readOnly,
@@ -4637,9 +4638,9 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
4637
4638
  }
4638
4639
  const debug$4 = debugWithName("component:PortableTextEditor:Synchronizer"), debugVerbose$1 = debug$4.enabled && !1, FLUSH_PATCHES_THROTTLED_MS = process.env.NODE_ENV === "test" ? 500 : 1e3;
4639
4640
  function Synchronizer(props) {
4640
- const portableTextEditor = usePortableTextEditor(), keyGenerator = usePortableTextEditorKeyGenerator(), readOnly = usePortableTextEditorReadOnlyStatus(), { change$, getValue, onChange, value } = props, pendingPatches = react.useRef([]), syncValue = useSyncValue({
4641
+ const portableTextEditor = usePortableTextEditor(), keyGenerator = usePortableTextEditorKeyGenerator(), readOnly = usePortableTextEditorReadOnlyStatus(), { editorActor, getValue, onChange, value } = props, pendingPatches = react.useRef([]), syncValue = useSyncValue({
4642
+ editorActor,
4641
4643
  keyGenerator,
4642
- onChange,
4643
4644
  portableTextEditor,
4644
4645
  readOnly
4645
4646
  }), slateEditor = slateReact.useSlate();
@@ -4651,14 +4652,14 @@ function Synchronizer(props) {
4651
4652
  debug$4("Flushing pending patches"), debugVerbose$1 && debug$4(`Patches:
4652
4653
  ${JSON.stringify(pendingPatches.current, null, 2)}`);
4653
4654
  const snapshot = getValue();
4654
- change$.next({
4655
+ editorActor.send({
4655
4656
  type: "mutation",
4656
4657
  patches: pendingPatches.current,
4657
4658
  snapshot
4658
4659
  }), pendingPatches.current = [];
4659
4660
  }
4660
4661
  IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, !1);
4661
- }, [slateEditor, getValue, change$]), onFlushPendingPatchesThrottled = react.useMemo(() => throttle__default.default(
4662
+ }, [editorActor, slateEditor, getValue]), onFlushPendingPatchesThrottled = react.useMemo(() => throttle__default.default(
4662
4663
  () => {
4663
4664
  if (slate.Editor.isNormalizing(slateEditor)) {
4664
4665
  onFlushPendingPatches();
@@ -4675,34 +4676,174 @@ ${JSON.stringify(pendingPatches.current, null, 2)}`);
4675
4676
  react.useEffect(() => () => {
4676
4677
  onFlushPendingPatches();
4677
4678
  }, [onFlushPendingPatches]), react.useEffect(() => {
4678
- debug$4("Subscribing to editor changes$");
4679
- const sub = change$.subscribe((next) => {
4680
- switch (next.type) {
4679
+ debug$4("Subscribing to editor changes");
4680
+ const sub = editorActor.on("*", (event) => {
4681
+ switch (event.type) {
4681
4682
  case "patch":
4682
- IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, !0), pendingPatches.current.push(next.patch), onFlushPendingPatchesThrottled(), onChange(next);
4683
+ IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, !0), pendingPatches.current.push(event.patch), onFlushPendingPatchesThrottled(), onChange(event);
4684
+ break;
4685
+ case "loading": {
4686
+ onChange({ type: "loading", isLoading: !0 });
4687
+ break;
4688
+ }
4689
+ case "done loading": {
4690
+ onChange({ type: "loading", isLoading: !1 });
4691
+ break;
4692
+ }
4693
+ case "offline": {
4694
+ onChange({ type: "connection", value: "offline" });
4695
+ break;
4696
+ }
4697
+ case "online": {
4698
+ onChange({ type: "connection", value: "online" });
4699
+ break;
4700
+ }
4701
+ case "value changed": {
4702
+ onChange({ type: "value", value: event.value });
4703
+ break;
4704
+ }
4705
+ case "invalid value": {
4706
+ onChange({
4707
+ type: "invalidValue",
4708
+ resolution: event.resolution,
4709
+ value: event.value
4710
+ });
4683
4711
  break;
4712
+ }
4713
+ case "error": {
4714
+ onChange({
4715
+ ...event,
4716
+ level: "warning"
4717
+ });
4718
+ break;
4719
+ }
4684
4720
  default:
4685
- onChange(next);
4721
+ onChange(event);
4686
4722
  }
4687
4723
  });
4688
4724
  return () => {
4689
- debug$4("Unsubscribing to changes$"), sub.unsubscribe();
4725
+ debug$4("Unsubscribing to changes"), sub.unsubscribe();
4690
4726
  };
4691
- }, [change$, onChange, onFlushPendingPatchesThrottled, slateEditor]);
4727
+ }, [editorActor, onFlushPendingPatchesThrottled, slateEditor]);
4692
4728
  const handleOnline = react.useCallback(() => {
4693
- debug$4("Editor is online, syncing from props.value"), change$.next({ type: "connection", value: "online" }), syncValue(value);
4694
- }, [change$, syncValue, value]), handleOffline = react.useCallback(() => {
4695
- debug$4("Editor is offline"), change$.next({ type: "connection", value: "offline" });
4696
- }, [change$]);
4697
- react.useEffect(() => (portableTextEditor.props.patches$ && (window.addEventListener("online", handleOnline), window.addEventListener("offline", handleOffline)), () => {
4698
- portableTextEditor.props.patches$ && (window.removeEventListener("online", handleOnline), window.removeEventListener("offline", handleOffline));
4699
- }));
4729
+ debug$4("Editor is online, syncing from props.value"), syncValue(value);
4730
+ }, [syncValue, value]);
4731
+ react.useEffect(() => {
4732
+ const subscription = editorActor.on("online", () => {
4733
+ portableTextEditor.props.patches$ && handleOnline();
4734
+ });
4735
+ return () => {
4736
+ subscription.unsubscribe();
4737
+ };
4738
+ }, [editorActor]);
4700
4739
  const isInitialValueFromProps = react.useRef(!0);
4701
4740
  return react.useEffect(() => {
4702
- debug$4("Value from props changed, syncing new value"), syncValue(value), isInitialValueFromProps.current && (change$.next({ type: "loading", isLoading: !1 }), change$.next({ type: "ready" }), isInitialValueFromProps.current = !1);
4703
- }, [change$, syncValue, value]), null;
4741
+ debug$4("Value from props changed, syncing new value"), syncValue(value), isInitialValueFromProps.current && (editorActor.send({ type: "ready" }), isInitialValueFromProps.current = !1);
4742
+ }, [editorActor, syncValue, value]), null;
4704
4743
  }
4705
- const PortableTextEditorSelectionContext = react.createContext(null), usePortableTextEditorSelection = () => {
4744
+ const networkLogic = xstate.fromCallback(({ sendBack }) => {
4745
+ const onlineHandler = () => {
4746
+ sendBack({ type: "online" });
4747
+ }, offlineHandler = () => {
4748
+ sendBack({ type: "offline" });
4749
+ };
4750
+ return window.addEventListener("online", onlineHandler), window.addEventListener("offline", offlineHandler), () => {
4751
+ window.removeEventListener("online", onlineHandler), window.removeEventListener("offline", offlineHandler);
4752
+ };
4753
+ }), editorMachine = xstate.setup({
4754
+ types: {
4755
+ context: {},
4756
+ events: {},
4757
+ emitted: {}
4758
+ },
4759
+ actions: {
4760
+ "emit patch event": xstate.emit(({ event }) => (xstate.assertEvent(event, "patch"), event)),
4761
+ "emit mutation event": xstate.emit(({ event }) => (xstate.assertEvent(event, "mutation"), event)),
4762
+ "defer event": xstate.assign({
4763
+ pendingEvents: ({ context, event }) => (xstate.assertEvent(event, ["patch", "mutation"]), [...context.pendingEvents, event])
4764
+ }),
4765
+ "emit pending events": xstate.enqueueActions(({ context, enqueue }) => {
4766
+ for (const event of context.pendingEvents)
4767
+ enqueue(xstate.emit(event));
4768
+ }),
4769
+ "clear pending events": xstate.assign({
4770
+ pendingEvents: []
4771
+ })
4772
+ },
4773
+ actors: {
4774
+ networkLogic
4775
+ }
4776
+ }).createMachine({
4777
+ id: "editor",
4778
+ context: {
4779
+ pendingEvents: []
4780
+ },
4781
+ invoke: {
4782
+ id: "networkLogic",
4783
+ src: "networkLogic"
4784
+ },
4785
+ on: {
4786
+ ready: { actions: xstate.emit(({ event }) => event) },
4787
+ unset: { actions: xstate.emit(({ event }) => event) },
4788
+ "value changed": { actions: xstate.emit(({ event }) => event) },
4789
+ "invalid value": { actions: xstate.emit(({ event }) => event) },
4790
+ error: { actions: xstate.emit(({ event }) => event) },
4791
+ selection: { actions: xstate.emit(({ event }) => event) },
4792
+ blur: { actions: xstate.emit(({ event }) => event) },
4793
+ focus: { actions: xstate.emit(({ event }) => event) },
4794
+ online: { actions: xstate.emit({ type: "online" }) },
4795
+ offline: { actions: xstate.emit({ type: "offline" }) },
4796
+ loading: { actions: xstate.emit({ type: "loading" }) },
4797
+ "done loading": { actions: xstate.emit({ type: "done loading" }) }
4798
+ },
4799
+ initial: "pristine",
4800
+ states: {
4801
+ pristine: {
4802
+ initial: "idle",
4803
+ states: {
4804
+ idle: {
4805
+ on: {
4806
+ normalizing: {
4807
+ target: "normalizing"
4808
+ },
4809
+ patch: {
4810
+ actions: "defer event",
4811
+ target: "#editor.dirty"
4812
+ },
4813
+ mutation: {
4814
+ actions: "defer event",
4815
+ target: "#editor.dirty"
4816
+ }
4817
+ }
4818
+ },
4819
+ normalizing: {
4820
+ on: {
4821
+ "done normalizing": {
4822
+ target: "idle"
4823
+ },
4824
+ patch: {
4825
+ actions: "defer event"
4826
+ },
4827
+ mutation: {
4828
+ actions: "defer event"
4829
+ }
4830
+ }
4831
+ }
4832
+ }
4833
+ },
4834
+ dirty: {
4835
+ entry: ["emit pending events", "clear pending events"],
4836
+ on: {
4837
+ patch: {
4838
+ actions: "emit patch event"
4839
+ },
4840
+ mutation: {
4841
+ actions: "emit mutation event"
4842
+ }
4843
+ }
4844
+ }
4845
+ }
4846
+ }), PortableTextEditorSelectionContext = react.createContext(null), usePortableTextEditorSelection = () => {
4706
4847
  const selection = react.useContext(PortableTextEditorSelectionContext);
4707
4848
  if (selection === void 0)
4708
4849
  throw new Error(
@@ -4711,21 +4852,26 @@ const PortableTextEditorSelectionContext = react.createContext(null), usePortabl
4711
4852
  return selection;
4712
4853
  }, debug$3 = debugWithName("component:PortableTextEditor:SelectionProvider"), debugVerbose = debug$3.enabled && !1;
4713
4854
  function PortableTextEditorSelectionProvider(props) {
4714
- const { change$ } = props, [selection, setSelection] = react.useState(null);
4855
+ const [selection, setSelection] = react.useState(null);
4715
4856
  return react.useEffect(() => {
4716
- debug$3("Subscribing to selection changes$");
4717
- const subscription = change$.subscribe((next) => {
4718
- next.type === "selection" && react.startTransition(() => {
4719
- debugVerbose && debug$3("Setting selection"), setSelection(next.selection);
4857
+ debug$3("Subscribing to selection changes");
4858
+ const subscription = props.editorActor.on("selection", (event) => {
4859
+ react.startTransition(() => {
4860
+ debugVerbose && debug$3("Setting selection"), setSelection(event.selection);
4720
4861
  });
4721
4862
  });
4722
4863
  return () => {
4723
- debug$3("Unsubscribing to selection changes$"), subscription.unsubscribe();
4864
+ debug$3("Unsubscribing to selection changes"), subscription.unsubscribe();
4724
4865
  };
4725
- }, [change$]), /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorSelectionContext.Provider, { value: selection, children: props.children });
4866
+ }, [props.editorActor]), /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorSelectionContext.Provider, { value: selection, children: props.children });
4726
4867
  }
4727
4868
  const debug$2 = debugWithName("component:PortableTextEditor");
4728
4869
  class PortableTextEditor extends react.Component {
4870
+ /**
4871
+ * @internal
4872
+ * Don't use this API directly. It's subject to change.
4873
+ */
4874
+ editorActor;
4729
4875
  /**
4730
4876
  * An observable of all the editor changes.
4731
4877
  */
@@ -4743,7 +4889,7 @@ class PortableTextEditor extends react.Component {
4743
4889
  throw new Error('PortableTextEditor: missing "schemaType" property');
4744
4890
  props.incomingPatches$ && console.warn(
4745
4891
  "The prop 'incomingPatches$' is deprecated and renamed to 'patches$'"
4746
- ), this.change$.next({ type: "loading", isLoading: !0 }), this.schemaTypes = getPortableTextMemberSchemaTypes(
4892
+ ), this.editorActor = xstate.createActor(editorMachine), this.editorActor.start(), this.schemaTypes = getPortableTextMemberSchemaTypes(
4747
4893
  props.schemaType.hasOwnProperty("jsonType") ? props.schemaType : compileType(props.schemaType)
4748
4894
  );
4749
4895
  }
@@ -4760,7 +4906,7 @@ class PortableTextEditor extends react.Component {
4760
4906
  return this.editable.getValue();
4761
4907
  };
4762
4908
  render() {
4763
- const { onChange, value, children, patches$, incomingPatches$ } = this.props, { change$ } = this, _patches$ = incomingPatches$ || patches$, maxBlocks = typeof this.props.maxBlocks > "u" ? void 0 : Number.parseInt(this.props.maxBlocks.toString(), 10) || void 0, readOnly = !!this.props.readOnly, keyGenerator = this.props.keyGenerator || defaultKeyGenerator;
4909
+ const { value, children, patches$, incomingPatches$ } = this.props, _patches$ = incomingPatches$ || patches$, maxBlocks = typeof this.props.maxBlocks > "u" ? void 0 : Number.parseInt(this.props.maxBlocks.toString(), 10) || void 0, readOnly = !!this.props.readOnly, keyGenerator = this.props.keyGenerator || defaultKeyGenerator;
4764
4910
  return /* @__PURE__ */ jsxRuntime.jsx(
4765
4911
  SlateContainer,
4766
4912
  {
@@ -4769,18 +4915,26 @@ class PortableTextEditor extends react.Component {
4769
4915
  patches$: _patches$,
4770
4916
  portableTextEditor: this,
4771
4917
  readOnly,
4772
- children: /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorKeyGeneratorContext.Provider, { value: keyGenerator, children: /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs(PortableTextEditorSelectionProvider, { change$, children: [
4773
- /* @__PURE__ */ jsxRuntime.jsx(
4774
- Synchronizer,
4775
- {
4776
- change$,
4777
- getValue: this.getValue,
4778
- onChange,
4779
- value
4780
- }
4781
- ),
4782
- children
4783
- ] }) }) }) })
4918
+ children: /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorKeyGeneratorContext.Provider, { value: keyGenerator, children: /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs(
4919
+ PortableTextEditorSelectionProvider,
4920
+ {
4921
+ editorActor: this.editorActor,
4922
+ children: [
4923
+ /* @__PURE__ */ jsxRuntime.jsx(
4924
+ Synchronizer,
4925
+ {
4926
+ editorActor: this.editorActor,
4927
+ getValue: this.getValue,
4928
+ onChange: (change) => {
4929
+ this.props.onChange(change), this.change$.next(change);
4930
+ },
4931
+ value
4932
+ }
4933
+ ),
4934
+ children
4935
+ ]
4936
+ }
4937
+ ) }) }) })
4784
4938
  }
4785
4939
  );
4786
4940
  }
@@ -4890,20 +5044,19 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
4890
5044
  react.useEffect(() => {
4891
5045
  if (!shouldTrackSelectionAndFocus)
4892
5046
  return;
4893
- const sub = portableTextEditor.change$.subscribe((next) => {
4894
- if (next.type === "blur") {
4895
- setFocused(!1), setSelected(!1);
4896
- return;
5047
+ const onBlur = portableTextEditor.editorActor.on("blur", () => {
5048
+ setFocused(!1), setSelected(!1);
5049
+ }), onFocus = portableTextEditor.editorActor.on("focus", () => {
5050
+ const sel = PortableTextEditor.getSelection(portableTextEditor);
5051
+ sel && isEqual__default.default(sel.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) && setFocused(!0), setSelectedFromRange();
5052
+ }), onSelection = portableTextEditor.editorActor.on(
5053
+ "selection",
5054
+ (event) => {
5055
+ event.selection && isEqual__default.default(event.selection.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) ? setFocused(!0) : setFocused(!1), setSelectedFromRange();
4897
5056
  }
4898
- if (next.type === "focus") {
4899
- const sel = PortableTextEditor.getSelection(portableTextEditor);
4900
- sel && isEqual__default.default(sel.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) && setFocused(!0), setSelectedFromRange();
4901
- return;
4902
- }
4903
- next.type === "selection" && (next.selection && isEqual__default.default(next.selection.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) ? setFocused(!0) : setFocused(!1), setSelectedFromRange());
4904
- });
5057
+ );
4905
5058
  return () => {
4906
- sub.unsubscribe();
5059
+ onBlur.unsubscribe(), onFocus.unsubscribe(), onSelection.unsubscribe();
4907
5060
  };
4908
5061
  }, [
4909
5062
  path,
@@ -5054,9 +5207,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5054
5207
  forwardedRef,
5055
5208
  () => ref.current
5056
5209
  );
5057
- const rangeDecorationsRef = react.useRef(rangeDecorations), { change$, schemaTypes } = portableTextEditor, slateEditor = slateReact.useSlate(), blockTypeName = schemaTypes.block.name, withInsertData = react.useMemo(
5058
- () => createWithInsertData(change$, schemaTypes, keyGenerator),
5059
- [change$, keyGenerator, schemaTypes]
5210
+ const rangeDecorationsRef = react.useRef(rangeDecorations), { editorActor, schemaTypes } = portableTextEditor, slateEditor = slateReact.useSlate(), blockTypeName = schemaTypes.block.name, withInsertData = react.useMemo(
5211
+ () => createWithInsertData(editorActor, schemaTypes, keyGenerator),
5212
+ [editorActor, keyGenerator, schemaTypes]
5060
5213
  ), withHotKeys = react.useMemo(
5061
5214
  () => createWithHotkeys(schemaTypes, portableTextEditor, hotkeys),
5062
5215
  [hotkeys, portableTextEditor, schemaTypes]
@@ -5129,10 +5282,13 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5129
5282
  `Normalized selection from props ${JSON.stringify(normalizedSelection)}`
5130
5283
  );
5131
5284
  const slateRange = toSlateRange(normalizedSelection, slateEditor);
5132
- slateRange && (slate.Transforms.select(slateEditor, slateRange), slateEditor.operations.some((o) => o.type === "set_selection") || change$.next({ type: "selection", selection: normalizedSelection }), slateEditor.onChange());
5285
+ slateRange && (slate.Transforms.select(slateEditor, slateRange), slateEditor.operations.some((o) => o.type === "set_selection") || editorActor.send({
5286
+ type: "selection",
5287
+ selection: normalizedSelection
5288
+ }), slateEditor.onChange());
5133
5289
  }
5134
5290
  }
5135
- }, [propsSelection, slateEditor, blockTypeName, change$]), syncRangeDecorations = react.useCallback(
5291
+ }, [editorActor, propsSelection, slateEditor]), syncRangeDecorations = react.useCallback(
5136
5292
  (operation) => {
5137
5293
  if (rangeDecorations && rangeDecorations.length > 0) {
5138
5294
  const newSlateRanges = [];
@@ -5176,23 +5332,17 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5176
5332
  [portableTextEditor, rangeDecorations, schemaTypes, slateEditor]
5177
5333
  );
5178
5334
  react.useEffect(() => {
5179
- const sub = change$.subscribe((next) => {
5180
- switch (next.type) {
5181
- case "ready":
5182
- restoreSelectionFromProps();
5183
- break;
5184
- case "invalidValue":
5185
- setHasInvalidValue(!0);
5186
- break;
5187
- case "value":
5188
- setHasInvalidValue(!1);
5189
- break;
5190
- }
5335
+ const onReady = editorActor.on("ready", () => {
5336
+ restoreSelectionFromProps();
5337
+ }), onInvalidValue = editorActor.on("invalid value", () => {
5338
+ setHasInvalidValue(!0);
5339
+ }), onValueChanged = editorActor.on("value changed", () => {
5340
+ setHasInvalidValue(!1);
5191
5341
  });
5192
5342
  return () => {
5193
- sub.unsubscribe();
5343
+ onReady.unsubscribe(), onInvalidValue.unsubscribe(), onValueChanged.unsubscribe();
5194
5344
  };
5195
- }, [change$, restoreSelectionFromProps]), react.useEffect(() => {
5345
+ }, [editorActor, restoreSelectionFromProps]), react.useEffect(() => {
5196
5346
  propsSelection && !hasInvalidValue && restoreSelectionFromProps();
5197
5347
  }, [hasInvalidValue, propsSelection, restoreSelectionFromProps]);
5198
5348
  const originalApply = react.useMemo(() => slateEditor.apply, [slateEditor]), [syncedRangeDecorations, setSyncedRangeDecorations] = react.useState(!1);
@@ -5223,7 +5373,7 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5223
5373
  slateEditor.selection,
5224
5374
  schemaTypes
5225
5375
  )?.focus.path || [], onPasteResult = onPaste({ event, value, path, schemaTypes });
5226
- onPasteResult === void 0 ? (debug("No result from custom paste handler, pasting normally"), slateEditor.insertData(event.clipboardData)) : (change$.next({ type: "loading", isLoading: !0 }), Promise.resolve(onPasteResult).then((result) => {
5376
+ onPasteResult === void 0 ? (debug("No result from custom paste handler, pasting normally"), slateEditor.insertData(event.clipboardData)) : (editorActor.send({ type: "loading" }), Promise.resolve(onPasteResult).then((result) => {
5227
5377
  debug("Custom paste function from client resolved", result), !result || !result.insert ? (debug("No result from custom paste handler, pasting normally"), slateEditor.insertData(event.clipboardData)) : result.insert ? slateEditor.insertFragment(
5228
5378
  toSlateValue(result.insert, {
5229
5379
  schemaTypes
@@ -5233,23 +5383,23 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5233
5383
  result
5234
5384
  );
5235
5385
  }).catch((error) => (console.error(error), error)).finally(() => {
5236
- change$.next({ type: "loading", isLoading: !1 });
5386
+ editorActor.send({ type: "done loading" });
5237
5387
  }));
5238
5388
  },
5239
- [change$, onPaste, portableTextEditor, schemaTypes, slateEditor]
5389
+ [onPaste, portableTextEditor, schemaTypes, slateEditor]
5240
5390
  ), handleOnFocus = react.useCallback(
5241
5391
  (event) => {
5242
5392
  if (onFocus && onFocus(event), !event.isDefaultPrevented()) {
5243
5393
  const selection = PortableTextEditor.getSelection(portableTextEditor);
5244
- selection === null && (slate.Transforms.select(slateEditor, slate.Editor.start(slateEditor, [])), slateEditor.onChange()), change$.next({ type: "focus", event });
5394
+ selection === null && (slate.Transforms.select(slateEditor, slate.Editor.start(slateEditor, [])), slateEditor.onChange()), editorActor.send({ type: "focus", event });
5245
5395
  const newSelection = PortableTextEditor.getSelection(portableTextEditor);
5246
- selection === newSelection && change$.next({
5396
+ selection === newSelection && editorActor.send({
5247
5397
  type: "selection",
5248
5398
  selection
5249
5399
  });
5250
5400
  }
5251
5401
  },
5252
- [onFocus, portableTextEditor, change$, slateEditor]
5402
+ [editorActor, onFocus, portableTextEditor, slateEditor]
5253
5403
  ), handleClick = react.useCallback(
5254
5404
  (event) => {
5255
5405
  if (onClick && onClick(event), slateEditor.selection && event.target === event.currentTarget) {
@@ -5266,9 +5416,9 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5266
5416
  [onClick, slateEditor]
5267
5417
  ), handleOnBlur = react.useCallback(
5268
5418
  (event) => {
5269
- onBlur && onBlur(event), event.isPropagationStopped() || change$.next({ type: "blur", event });
5419
+ onBlur && onBlur(event), event.isPropagationStopped() || editorActor.send({ type: "blur", event });
5270
5420
  },
5271
- [change$, onBlur]
5421
+ [editorActor, onBlur]
5272
5422
  ), handleOnBeforeInput = react.useCallback(
5273
5423
  (event) => {
5274
5424
  onBeforeInput && onBeforeInput(event);
@@ -5373,6 +5523,7 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5373
5523
  });
5374
5524
  exports.PortableTextEditable = PortableTextEditable;
5375
5525
  exports.PortableTextEditor = PortableTextEditor;
5526
+ exports.editorMachine = editorMachine;
5376
5527
  exports.keyGenerator = defaultKeyGenerator;
5377
5528
  exports.usePortableTextEditor = usePortableTextEditor;
5378
5529
  exports.usePortableTextEditorSelection = usePortableTextEditorSelection;