@portabletext/editor 1.49.7 → 1.49.9

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.
@@ -14,11 +14,9 @@ import {
14
14
  } from 'react'
15
15
  import {Subject} from 'rxjs'
16
16
  import {Slate} from 'slate-react'
17
- import {useEffectEvent} from 'use-effect-event'
18
- import {createActor} from 'xstate'
19
- import {createCoreConverters} from '../converters/converters.core'
20
17
  import {debugWithName} from '../internal-utils/debug'
21
18
  import {compileType} from '../internal-utils/schema'
19
+ import {stopActor} from '../internal-utils/stop-actor'
22
20
  import type {AddedAnnotationPaths} from '../operations/behavior.operation.annotation.add'
23
21
  import type {
24
22
  EditableAPI,
@@ -29,15 +27,16 @@ import type {
29
27
  PatchObservable,
30
28
  PortableTextMemberSchemaTypes,
31
29
  } from '../types/editor'
32
- import {Synchronizer} from './components/Synchronizer'
33
30
  import {createInternalEditor, type InternalEditor} from './create-editor'
34
31
  import {EditorActorContext} from './editor-actor-context'
35
- import {editorMachine, type EditorActor} from './editor-machine'
32
+ import type {EditorActor} from './editor-machine'
36
33
  import {legacySchemaToEditorSchema} from './editor-schema'
37
34
  import {PortableTextEditorContext} from './hooks/usePortableTextEditor'
38
35
  import {PortableTextEditorSelectionProvider} from './hooks/usePortableTextEditorSelection'
39
- import {defaultKeyGenerator} from './key-generator'
40
36
  import {createLegacySchema} from './legacy-schema'
37
+ import type {MutationActor} from './mutation-machine'
38
+ import {eventToChange} from './route-events-to-changes'
39
+ import type {SyncActor} from './sync-machine'
41
40
 
42
41
  const debug = debugWithName('component:PortableTextEditor')
43
42
 
@@ -133,6 +132,14 @@ export class PortableTextEditor extends Component<
133
132
  */
134
133
  private editable: EditableAPI
135
134
 
135
+ private actors?: {
136
+ editorActor: EditorActor
137
+ mutationActor: MutationActor
138
+ syncActor: SyncActor
139
+ }
140
+
141
+ private unsubscribers: Array<() => void> = []
142
+
136
143
  constructor(props: PortableTextEditorProps) {
137
144
  super(props)
138
145
 
@@ -142,35 +149,60 @@ export class PortableTextEditor extends Component<
142
149
  .getSnapshot()
143
150
  .context.getLegacySchema()
144
151
  } else {
145
- const legacySchema = createLegacySchema(
146
- props.schemaType.hasOwnProperty('jsonType')
147
- ? props.schemaType
148
- : compileType(props.schemaType),
149
- )
150
- const schema = legacySchemaToEditorSchema(legacySchema)
151
- const editorActor = createActor(editorMachine, {
152
- input: {
153
- converters: createCoreConverters(legacySchema),
154
- getLegacySchema: () => legacySchema,
155
- initialValue: props.value,
156
- keyGenerator: props.keyGenerator ?? defaultKeyGenerator,
157
- maxBlocks:
158
- props.maxBlocks === undefined
159
- ? undefined
160
- : Number.parseInt(props.maxBlocks.toString(), 10),
161
- readOnly: props.readOnly,
162
- schema,
163
- },
152
+ const {actors, editor, subscriptions} = createInternalEditor({
153
+ initialValue: props.value,
154
+ keyGenerator: props.keyGenerator,
155
+ maxBlocks:
156
+ props.maxBlocks === undefined
157
+ ? undefined
158
+ : Number.parseInt(props.maxBlocks.toString(), 10),
159
+ readOnly: props.readOnly,
160
+ schema: props.schemaType,
164
161
  })
165
- editorActor.start()
166
162
 
167
- this.editor = createInternalEditor(editorActor)
168
- this.schemaTypes = legacySchema
163
+ this.unsubscribers.push(
164
+ (() => {
165
+ const subscription = actors.editorActor.on('*', (event) => {
166
+ const change = eventToChange(event)
167
+
168
+ if (change) {
169
+ props.onChange(change)
170
+
171
+ this.change$.next(change)
172
+ }
173
+ })
174
+
175
+ return () => {
176
+ subscription.unsubscribe()
177
+ }
178
+ })(),
179
+ )
180
+
181
+ for (const subscription of subscriptions) {
182
+ this.unsubscribers.push(subscription())
183
+ }
184
+
185
+ this.actors = actors
186
+
187
+ this.editor = editor
188
+ this.schemaTypes = actors.editorActor
189
+ .getSnapshot()
190
+ .context.getLegacySchema()
169
191
  }
170
192
 
171
193
  this.editable = this.editor._internal.editable
172
194
  }
173
195
 
196
+ componentDidMount(): void {
197
+ if (!this.actors) {
198
+ return
199
+ }
200
+
201
+ this.actors.editorActor.start()
202
+ this.actors.mutationActor.start()
203
+ this.actors.syncActor.start()
204
+ }
205
+
174
206
  componentDidUpdate(prevProps: PortableTextEditorProps) {
175
207
  // Set up the schema type lookup table again if the source schema type changes
176
208
  if (
@@ -209,7 +241,7 @@ export class PortableTextEditor extends Component<
209
241
  }
210
242
 
211
243
  if (this.props.value !== prevProps.value) {
212
- this.editor._internal.editorActor.send({
244
+ this.editor.send({
213
245
  type: 'update value',
214
246
  value: this.props.value,
215
247
  })
@@ -224,6 +256,18 @@ export class PortableTextEditor extends Component<
224
256
  }
225
257
  }
226
258
 
259
+ componentWillUnmount(): void {
260
+ for (const unsubscribe of this.unsubscribers) {
261
+ unsubscribe()
262
+ }
263
+
264
+ if (this.actors) {
265
+ stopActor(this.actors.editorActor)
266
+ stopActor(this.actors.mutationActor)
267
+ stopActor(this.actors.syncActor)
268
+ }
269
+ }
270
+
227
271
  public setEditable = (editable: EditableAPI) => {
228
272
  this.editor._internal.editable = {
229
273
  ...this.editor._internal.editable,
@@ -244,23 +288,6 @@ export class PortableTextEditor extends Component<
244
288
  patches$={legacyPatches}
245
289
  />
246
290
  ) : null}
247
- <RouteEventsToChanges
248
- editorActor={this.editor._internal.editorActor}
249
- onChange={(change) => {
250
- if (!this.props.editor) {
251
- this.props.onChange(change)
252
- }
253
- /**
254
- * For backwards compatibility, we relay all changes to the
255
- * `change$` Subject as well.
256
- */
257
- this.change$.next(change)
258
- }}
259
- />
260
- <Synchronizer
261
- editorActor={this.editor._internal.editorActor}
262
- slateEditor={this.editor._internal.slateEditor.instance}
263
- />
264
291
  <EditorActorContext.Provider value={this.editor._internal.editorActor}>
265
292
  <Slate
266
293
  editor={this.editor._internal.slateEditor.instance}
@@ -775,84 +802,3 @@ function RoutePatchesObservableToEditorActor(props: {
775
802
 
776
803
  return null
777
804
  }
778
-
779
- export function RouteEventsToChanges(props: {
780
- editorActor: EditorActor
781
- onChange: (change: EditorChange) => void
782
- }) {
783
- // We want to ensure that _when_ `props.onChange` is called, it uses the current value.
784
- // But we don't want to have the `useEffect` run setup + teardown + setup every time the prop might change, as that's unnecessary.
785
- // So we use our own polyfill that lets us use an upcoming React hook that solves this exact problem.
786
- // https://19.react.dev/learn/separating-events-from-effects#declaring-an-effect-event
787
- const handleChange = useEffectEvent((change: EditorChange) =>
788
- props.onChange(change),
789
- )
790
-
791
- useEffect(() => {
792
- debug('Subscribing to editor changes')
793
- const sub = props.editorActor.on('*', (event) => {
794
- switch (event.type) {
795
- case 'blurred': {
796
- handleChange({type: 'blur', event: event.event})
797
- break
798
- }
799
- case 'patch':
800
- handleChange(event)
801
- break
802
- case 'loading': {
803
- handleChange({type: 'loading', isLoading: true})
804
- break
805
- }
806
- case 'done loading': {
807
- handleChange({type: 'loading', isLoading: false})
808
- break
809
- }
810
- case 'focused': {
811
- handleChange({type: 'focus', event: event.event})
812
- break
813
- }
814
- case 'value changed': {
815
- handleChange({type: 'value', value: event.value})
816
- break
817
- }
818
- case 'invalid value': {
819
- handleChange({
820
- type: 'invalidValue',
821
- resolution: event.resolution,
822
- value: event.value,
823
- })
824
- break
825
- }
826
- case 'error': {
827
- handleChange({
828
- ...event,
829
- level: 'warning',
830
- })
831
- break
832
- }
833
- case 'mutation': {
834
- handleChange(event)
835
- break
836
- }
837
- case 'ready': {
838
- handleChange(event)
839
- break
840
- }
841
- case 'selection': {
842
- handleChange(event)
843
- break
844
- }
845
- case 'unset': {
846
- handleChange(event)
847
- break
848
- }
849
- }
850
- })
851
- return () => {
852
- debug('Unsubscribing to changes')
853
- sub.unsubscribe()
854
- }
855
- }, [props.editorActor])
856
-
857
- return null
858
- }
@@ -43,6 +43,7 @@ describe('initialization', () => {
43
43
  autocorrect="false"
44
44
  class="pt-editable"
45
45
  contenteditable="true"
46
+ data-read-only="false"
46
47
  data-slate-editor="true"
47
48
  data-slate-node="value"
48
49
  role="textbox"
@@ -1,11 +1,16 @@
1
+ import {createActor} from 'xstate'
1
2
  import {createCoreConverters} from '../converters/converters.core'
2
3
  import type {Editor, EditorConfig} from '../editor'
4
+ import {debugWithName} from '../internal-utils/debug'
3
5
  import {compileType} from '../internal-utils/schema'
6
+ import {fromSlateValue} from '../internal-utils/values'
7
+ import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
4
8
  import {corePriority} from '../priority/priority.core'
5
9
  import {createEditorPriority} from '../priority/priority.types'
6
- import type {EditableAPI} from '../types/editor'
10
+ import type {EditableAPI, PortableTextSlateEditor} from '../types/editor'
7
11
  import {createSlateEditor, type SlateEditor} from './create-slate-editor'
8
12
  import type {EditorActor} from './editor-machine'
13
+ import {editorMachine} from './editor-machine'
9
14
  import {
10
15
  compileSchemaDefinitionToLegacySchema,
11
16
  legacySchemaToEditorSchema,
@@ -13,7 +18,11 @@ import {
13
18
  import {getEditorSnapshot} from './editor-selector'
14
19
  import {defaultKeyGenerator} from './key-generator'
15
20
  import {createLegacySchema} from './legacy-schema'
21
+ import {mutationMachine, type MutationActor} from './mutation-machine'
16
22
  import {createEditableAPI} from './plugins/createWithEditableAPI'
23
+ import {syncMachine, type SyncActor} from './sync-machine'
24
+
25
+ const debug = debugWithName('setup')
17
26
 
18
27
  export type InternalEditor = Editor & {
19
28
  _internal: {
@@ -53,11 +62,30 @@ export function editorConfigToMachineInput(config: EditorConfig) {
53
62
  } as const
54
63
  }
55
64
 
56
- export function createInternalEditor(editorActor: EditorActor): InternalEditor {
57
- const slateEditor = createSlateEditor({editorActor})
65
+ export function createInternalEditor(config: EditorConfig): {
66
+ actors: {
67
+ editorActor: EditorActor
68
+ mutationActor: MutationActor
69
+ syncActor: SyncActor
70
+ }
71
+ editor: InternalEditor
72
+ subscriptions: Array<() => () => void>
73
+ } {
74
+ debug('Creating new Editor instance')
75
+
76
+ const subscriptions: Array<() => () => void> = []
77
+ const editorActor = createActor(editorMachine, {
78
+ input: editorConfigToMachineInput(config),
79
+ })
80
+ const slateEditor = createSlateEditor({editorActor, subscriptions})
58
81
  const editable = createEditableAPI(slateEditor.instance, editorActor)
82
+ const {mutationActor, syncActor} = createActors({
83
+ editorActor,
84
+ slateEditor: slateEditor.instance,
85
+ subscriptions,
86
+ })
59
87
 
60
- return {
88
+ const editor = {
61
89
  getSnapshot: () =>
62
90
  getEditorSnapshot({
63
91
  editorActorSnapshot: editorActor.getSnapshot(),
@@ -90,10 +118,13 @@ export function createInternalEditor(editorActor: EditorActor): InternalEditor {
90
118
  },
91
119
  send: (event) => {
92
120
  switch (event.type) {
121
+ case 'update value':
122
+ syncActor.send(event)
123
+ break
124
+
93
125
  case 'update key generator':
94
126
  case 'update readOnly':
95
127
  case 'patches':
96
- case 'update value':
97
128
  case 'update schema':
98
129
  case 'update maxBlocks':
99
130
  editorActor.send(event)
@@ -164,5 +195,128 @@ export function createInternalEditor(editorActor: EditorActor): InternalEditor {
164
195
  editorActor,
165
196
  slateEditor,
166
197
  },
198
+ } satisfies InternalEditor
199
+
200
+ return {
201
+ actors: {
202
+ editorActor,
203
+ mutationActor,
204
+ syncActor,
205
+ },
206
+ editor,
207
+ subscriptions,
208
+ }
209
+ }
210
+
211
+ function createActors(config: {
212
+ editorActor: EditorActor
213
+ slateEditor: PortableTextSlateEditor
214
+ subscriptions: Array<() => () => void>
215
+ }): {
216
+ syncActor: SyncActor
217
+ mutationActor: MutationActor
218
+ } {
219
+ debug('Creating new Actors')
220
+
221
+ const mutationActor = createActor(mutationMachine, {
222
+ input: {
223
+ schema: config.editorActor.getSnapshot().context.schema,
224
+ slateEditor: config.slateEditor,
225
+ },
226
+ })
227
+
228
+ const syncActor = createActor(syncMachine, {
229
+ input: {
230
+ initialValue: config.editorActor.getSnapshot().context.initialValue,
231
+ keyGenerator: config.editorActor.getSnapshot().context.keyGenerator,
232
+ readOnly: config.editorActor
233
+ .getSnapshot()
234
+ .matches({'edit mode': 'read only'}),
235
+ schema: config.editorActor.getSnapshot().context.schema,
236
+ slateEditor: config.slateEditor,
237
+ },
238
+ })
239
+
240
+ config.subscriptions.push(() => {
241
+ const subscription = mutationActor.on('*', (event) => {
242
+ if (event.type === 'has pending patches') {
243
+ syncActor.send({type: 'has pending patches'})
244
+ }
245
+ if (event.type === 'mutation') {
246
+ syncActor.send({type: 'mutation'})
247
+ config.editorActor.send({
248
+ type: 'mutation',
249
+ patches: event.patches,
250
+ snapshot: event.snapshot,
251
+ value: event.snapshot,
252
+ })
253
+ }
254
+ })
255
+
256
+ return () => {
257
+ subscription.unsubscribe()
258
+ }
259
+ })
260
+
261
+ config.subscriptions.push(() => {
262
+ const subscription = syncActor.on('*', (event) => {
263
+ switch (event.type) {
264
+ case 'invalid value':
265
+ config.editorActor.send({
266
+ ...event,
267
+ type: 'notify.invalid value',
268
+ })
269
+ break
270
+ case 'value changed':
271
+ config.editorActor.send({
272
+ ...event,
273
+ type: 'notify.value changed',
274
+ })
275
+ break
276
+ case 'patch':
277
+ config.editorActor.send({
278
+ ...event,
279
+ type: 'internal.patch',
280
+ value: fromSlateValue(
281
+ config.slateEditor.children,
282
+ config.editorActor.getSnapshot().context.schema.block.name,
283
+ KEY_TO_VALUE_ELEMENT.get(config.slateEditor),
284
+ ),
285
+ })
286
+ break
287
+
288
+ default:
289
+ config.editorActor.send(event)
290
+ }
291
+ })
292
+
293
+ return () => {
294
+ subscription.unsubscribe()
295
+ }
296
+ })
297
+
298
+ config.subscriptions.push(() => {
299
+ const subscription = config.editorActor.on('*', (event) => {
300
+ if (
301
+ config.editorActor.getSnapshot().matches({'edit mode': 'read only'})
302
+ ) {
303
+ syncActor.send({type: 'update readOnly', readOnly: true})
304
+ } else {
305
+ syncActor.send({type: 'update readOnly', readOnly: false})
306
+ }
307
+
308
+ if (event.type === 'internal.patch') {
309
+ mutationActor.send({...event, type: 'patch'})
310
+ }
311
+ })
312
+
313
+ return () => {
314
+ subscription.unsubscribe()
315
+ }
316
+ })
317
+
318
+ return {
319
+ syncActor,
320
+ mutationActor,
167
321
  }
168
322
  }
@@ -9,10 +9,11 @@ import type {PortableTextSlateEditor} from '../types/editor'
9
9
  import type {EditorActor} from './editor-machine'
10
10
  import {withPlugins} from './plugins/with-plugins'
11
11
 
12
- const debug = debugWithName('component:PortableTextEditor:SlateContainer')
12
+ const debug = debugWithName('setup')
13
13
 
14
14
  type SlateEditorConfig = {
15
15
  editorActor: EditorActor
16
+ subscriptions: Array<() => () => void>
16
17
  }
17
18
 
18
19
  export type SlateEditor = {
@@ -20,33 +21,17 @@ export type SlateEditor = {
20
21
  initialValue: Array<Descendant>
21
22
  }
22
23
 
23
- const slateEditors = new WeakMap<EditorActor, SlateEditor>()
24
-
25
24
  export function createSlateEditor(config: SlateEditorConfig): SlateEditor {
26
- const existingSlateEditor = slateEditors.get(config.editorActor)
27
-
28
- if (existingSlateEditor) {
29
- debug('Reusing existing Slate editor instance', config.editorActor.id)
30
- return existingSlateEditor
31
- }
32
-
33
- debug('Creating new Slate editor instance', config.editorActor.id)
34
-
35
- const unsubscriptions: Array<() => void> = []
36
- const subscriptions: Array<() => () => void> = []
25
+ debug('Creating new Slate editor instance')
37
26
 
38
27
  const instance = withPlugins(withReact(createEditor()), {
39
28
  editorActor: config.editorActor,
40
- subscriptions,
29
+ subscriptions: config.subscriptions,
41
30
  })
42
31
 
43
32
  KEY_TO_VALUE_ELEMENT.set(instance, {})
44
33
  KEY_TO_SLATE_ELEMENT.set(instance, {})
45
34
 
46
- for (const subscription of subscriptions) {
47
- unsubscriptions.push(subscription())
48
- }
49
-
50
35
  const initialValue = [instance.pteCreateTextBlock({decorators: []})]
51
36
 
52
37
  const slateEditor: SlateEditor = {
@@ -54,7 +39,5 @@ export function createSlateEditor(config: SlateEditorConfig): SlateEditor {
54
39
  initialValue,
55
40
  }
56
41
 
57
- slateEditors.set(config.editorActor, slateEditor)
58
-
59
42
  return slateEditor
60
43
  }
@@ -71,10 +71,6 @@ export type ExternalEditorEvent =
71
71
  type: 'update key generator'
72
72
  keyGenerator: () => string
73
73
  }
74
- | {
75
- type: 'update value'
76
- value: Array<PortableTextBlock> | undefined
77
- }
78
74
  | {
79
75
  type: 'update maxBlocks'
80
76
  maxBlocks: number | undefined
@@ -227,7 +223,7 @@ export const editorMachine = setup({
227
223
  initialReadOnly: boolean
228
224
  maxBlocks: number | undefined
229
225
  selection: EditorSelection
230
- incomingValue: Array<PortableTextBlock> | undefined
226
+ initialValue: Array<PortableTextBlock> | undefined
231
227
  internalDrag?: {
232
228
  ghost?: HTMLElement
233
229
  origin: Pick<EventPosition, 'selection'>
@@ -402,7 +398,7 @@ export const editorMachine = setup({
402
398
  selection: null,
403
399
  initialReadOnly: input.readOnly ?? false,
404
400
  maxBlocks: input.maxBlocks,
405
- incomingValue: input.initialValue,
401
+ initialValue: input.initialValue,
406
402
  }),
407
403
  on: {
408
404
  'notify.blurred': {
@@ -434,9 +430,6 @@ export const editorMachine = setup({
434
430
  actions: assign({keyGenerator: ({event}) => event.keyGenerator}),
435
431
  },
436
432
  'update schema': {actions: 'assign schema'},
437
- 'update value': {
438
- actions: assign({incomingValue: ({event}) => event.value}),
439
- },
440
433
  'update maxBlocks': {
441
434
  actions: assign({maxBlocks: ({event}) => event.maxBlocks}),
442
435
  },
@@ -1,20 +1,19 @@
1
- import {useActorRef} from '@xstate/react'
2
1
  import type React from 'react'
3
- import {useMemo} from 'react'
2
+ import {useEffect} from 'react'
4
3
  import {Slate} from 'slate-react'
5
4
  import type {EditorConfig} from '../editor'
6
- import {Synchronizer} from './components/Synchronizer'
7
- import {createInternalEditor, editorConfigToMachineInput} from './create-editor'
5
+ import {stopActor} from '../internal-utils/stop-actor'
6
+ import useConstant from '../internal-utils/use-constant'
7
+ import {createInternalEditor} from './create-editor'
8
8
  import {EditorActorContext} from './editor-actor-context'
9
9
  import {EditorContext} from './editor-context'
10
- import {editorMachine} from './editor-machine'
11
10
  import {PortableTextEditorContext} from './hooks/usePortableTextEditor'
12
11
  import {PortableTextEditorSelectionProvider} from './hooks/usePortableTextEditorSelection'
13
12
  import {
14
13
  PortableTextEditor,
15
- RouteEventsToChanges,
16
14
  type PortableTextEditorProps,
17
15
  } from './PortableTextEditor'
16
+ import {RouteEventsToChanges} from './route-events-to-changes'
18
17
 
19
18
  /**
20
19
  * @public
@@ -43,40 +42,56 @@ export type EditorProviderProps = {
43
42
  * @group Components
44
43
  */
45
44
  export function EditorProvider(props: EditorProviderProps) {
46
- const editorActor = useActorRef(editorMachine, {
47
- input: editorConfigToMachineInput(props.initialConfig),
45
+ const {internalEditor, portableTextEditor} = useConstant(() => {
46
+ const internalEditor = createInternalEditor(props.initialConfig)
47
+ const portableTextEditor = new PortableTextEditor({
48
+ editor: internalEditor.editor,
49
+ } as unknown as PortableTextEditorProps)
50
+
51
+ return {internalEditor, portableTextEditor}
48
52
  })
49
- const internalEditor = useMemo(
50
- () => createInternalEditor(editorActor),
51
- [editorActor],
52
- )
53
- const portableTextEditor = useMemo(
54
- () =>
55
- new PortableTextEditor({
56
- editor: internalEditor,
57
- } as unknown as PortableTextEditorProps),
58
- [internalEditor],
59
- )
53
+
54
+ useEffect(() => {
55
+ const unsubscribers: Array<() => void> = []
56
+
57
+ for (const subscription of internalEditor.subscriptions) {
58
+ unsubscribers.push(subscription())
59
+ }
60
+
61
+ internalEditor.actors.editorActor.start()
62
+ internalEditor.actors.mutationActor.start()
63
+ internalEditor.actors.syncActor.start()
64
+
65
+ return () => {
66
+ for (const unsubscribe of unsubscribers) {
67
+ unsubscribe()
68
+ }
69
+
70
+ stopActor(internalEditor.actors.editorActor)
71
+ stopActor(internalEditor.actors.mutationActor)
72
+ stopActor(internalEditor.actors.syncActor)
73
+ }
74
+ }, [internalEditor])
60
75
 
61
76
  return (
62
- <EditorContext.Provider value={internalEditor}>
77
+ <EditorContext.Provider value={internalEditor.editor}>
63
78
  <RouteEventsToChanges
64
- editorActor={editorActor}
79
+ editorActor={internalEditor.actors.editorActor}
65
80
  onChange={(change) => {
66
81
  portableTextEditor.change$.next(change)
67
82
  }}
68
83
  />
69
- <Synchronizer
70
- editorActor={editorActor}
71
- slateEditor={internalEditor._internal.slateEditor.instance}
72
- />
73
- <EditorActorContext.Provider value={editorActor}>
84
+ <EditorActorContext.Provider value={internalEditor.actors.editorActor}>
74
85
  <Slate
75
- editor={internalEditor._internal.slateEditor.instance}
76
- initialValue={internalEditor._internal.slateEditor.initialValue}
86
+ editor={internalEditor.editor._internal.slateEditor.instance}
87
+ initialValue={
88
+ internalEditor.editor._internal.slateEditor.initialValue
89
+ }
77
90
  >
78
91
  <PortableTextEditorContext.Provider value={portableTextEditor}>
79
- <PortableTextEditorSelectionProvider editorActor={editorActor}>
92
+ <PortableTextEditorSelectionProvider
93
+ editorActor={internalEditor.actors.editorActor}
94
+ >
80
95
  {props.children}
81
96
  </PortableTextEditorSelectionProvider>
82
97
  </PortableTextEditorContext.Provider>
@@ -13,9 +13,12 @@ import {
13
13
  stateIn,
14
14
  type AnyEventObject,
15
15
  } from 'xstate'
16
+ import type {ActorRefFrom} from 'xstate'
16
17
  import type {PortableTextSlateEditor} from '../types/editor'
17
18
  import type {EditorSchema} from './editor-schema'
18
19
 
20
+ export type MutationActor = ActorRefFrom<typeof mutationMachine>
21
+
19
22
  /**
20
23
  * Makes sure editor mutation events are debounced
21
24
  */