@portabletext/editor 1.0.2 → 1.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -45,10 +45,6 @@
45
45
  "src"
46
46
  ],
47
47
  "dependencies": {
48
- "@sanity/block-tools": "^3.47.0",
49
- "@sanity/schema": "^3.47.0",
50
- "@sanity/types": "^3.47.0",
51
- "@sanity/util": "^3.47.0",
52
48
  "debug": "^3.2.7",
53
49
  "is-hotkey-esm": "^1.0.0",
54
50
  "lodash": "^4.17.21",
@@ -58,28 +54,46 @@
58
54
  "devDependencies": {
59
55
  "@babel/plugin-proposal-class-properties": "^7.18.6",
60
56
  "@jest/globals": "^29.7.0",
61
- "@playwright/test": "1.41.2",
57
+ "@playwright/test": "1.45.0",
62
58
  "@portabletext/toolkit": "^2.0.15",
59
+ "@sanity/block-tools": "^3.47.1",
63
60
  "@sanity/diff-match-patch": "^3.1.1",
61
+ "@sanity/eslint-config-i18n": "^1.1.0",
62
+ "@sanity/eslint-config-studio": "^4.0.0",
64
63
  "@sanity/pkg-utils": "^6.10.0",
64
+ "@sanity/schema": "^3.47.1",
65
65
  "@sanity/test": "0.0.1-alpha.1",
66
- "@sanity/ui": "^2.4.0",
66
+ "@sanity/types": "^3.47.1",
67
+ "@sanity/ui": "^2.5.0",
68
+ "@sanity/util": "^3.47.1",
67
69
  "@testing-library/react": "^13.4.0",
68
70
  "@types/debug": "^4.1.5",
69
71
  "@types/express": "^4.17.21",
70
- "@types/express-ws": "^3.0.1",
71
- "@types/lodash": "^4.14.149",
72
+ "@types/express-ws": "^3.0.4",
73
+ "@types/lodash": "^4.17.5",
72
74
  "@types/node": "^18.19.8",
73
- "@types/node-ipc": "^9.2.0",
75
+ "@types/node-ipc": "^9.2.3",
74
76
  "@types/react": "^18.3.3",
75
77
  "@types/react-dom": "^18.3.0",
76
- "@types/ws": "~8.5.3",
78
+ "@types/ws": "~8.5.10",
79
+ "@typescript-eslint/eslint-plugin": "^7.14.1",
80
+ "@typescript-eslint/parser": "^7.14.1",
77
81
  "@vitejs/plugin-react": "^4.3.1",
78
82
  "dotenv": "^16.4.5",
79
- "express": "^4.18.3",
83
+ "eslint": "^8.57.0",
84
+ "eslint-config-prettier": "^9.1.0",
85
+ "eslint-config-sanity": "^7.1.2",
86
+ "eslint-import-resolver-typescript": "^3.6.1",
87
+ "eslint-plugin-import": "^2.29.1",
88
+ "eslint-plugin-prettier": "^5.1.3",
89
+ "eslint-plugin-react-compiler": "0.0.0-experimental-51a85ea-20240601",
90
+ "eslint-plugin-tsdoc": "^0.3.0",
91
+ "eslint-plugin-unicorn": "^54.0.0",
92
+ "eslint-plugin-unused-imports": "^4.0.0",
93
+ "express": "^4.19.2",
80
94
  "express-ws": "^5.0.2",
81
95
  "jest": "^29.7.0",
82
- "jest-dev-server": "^9.0.1",
96
+ "jest-dev-server": "^9.0.2",
83
97
  "jest-environment-jsdom": "^29.7.0",
84
98
  "jest-environment-node": "^29.7.0",
85
99
  "node-ipc": "npm:@node-ipc/compat@9.2.5",
@@ -88,13 +102,16 @@
88
102
  "rimraf": "^3.0.2",
89
103
  "rxjs": "^7.8.1",
90
104
  "styled-components": "^6.1.11",
91
- "tsx": "^4.10.3",
105
+ "tsx": "^4.15.7",
92
106
  "typescript": "^5.4.5",
93
107
  "vite": "^4.5.3",
94
- "@repo/tsconfig": "^0.0.0",
95
- "@repo/package.config": "^0.0.0"
108
+ "@portabletext/patches": "^0.0.0"
96
109
  },
97
110
  "peerDependencies": {
111
+ "@sanity/block-tools": "^3.47.1",
112
+ "@sanity/schema": "^3.47.1",
113
+ "@sanity/types": "^3.47.1",
114
+ "@sanity/util": "^3.47.1",
98
115
  "react": "^16.9 || ^17 || ^18",
99
116
  "rxjs": "^7",
100
117
  "styled-components": "^6.1"
@@ -107,13 +124,14 @@
107
124
  },
108
125
  "scripts": {
109
126
  "build": "pkg-utils build --strict --check --clean",
127
+ "check:lint": "eslint .",
110
128
  "check:types": "tsc --project tsconfig.lib.json",
111
129
  "clean": "rimraf lib",
112
- "dev": "cd ./e2e-tests/ && tsx serve",
113
- "lint": "eslint .",
130
+ "dev": "pkg-utils watch",
131
+ "dev:e2e-server": "cd ./e2e-tests/ && tsx serve",
132
+ "lint:fix": "eslint . --fix",
114
133
  "test": "jest",
115
134
  "test:e2e": "jest --config=e2e-tests/e2e.config.cjs",
116
- "test:watch": "jest --watch",
117
- "watch": "pkg-utils watch"
135
+ "test:watch": "jest --watch"
118
136
  }
119
137
  }
@@ -9,7 +9,6 @@ import {
9
9
  type HTMLProps,
10
10
  type KeyboardEvent,
11
11
  type MutableRefObject,
12
- type ReactNode,
13
12
  type TextareaHTMLAttributes,
14
13
  useCallback,
15
14
  useEffect,
@@ -42,13 +41,13 @@ import {
42
41
  type EditorSelection,
43
42
  type OnCopyFn,
44
43
  type OnPasteFn,
45
- type OnPasteResult,
46
44
  type RangeDecoration,
47
45
  type RenderAnnotationFunction,
48
46
  type RenderBlockFunction,
49
47
  type RenderChildFunction,
50
48
  type RenderDecoratorFunction,
51
49
  type RenderListItemFunction,
50
+ type RenderPlaceholderFunction,
52
51
  type RenderStyleFunction,
53
52
  type ScrollSelectionIntoViewFunction,
54
53
  } from '../types/editor'
@@ -100,7 +99,7 @@ export type PortableTextEditableProps = Omit<
100
99
  renderChild?: RenderChildFunction
101
100
  renderDecorator?: RenderDecoratorFunction
102
101
  renderListItem?: RenderListItemFunction
103
- renderPlaceholder?: () => ReactNode
102
+ renderPlaceholder?: RenderPlaceholderFunction
104
103
  renderStyle?: RenderStyleFunction
105
104
  scrollSelectionIntoView?: ScrollSelectionIntoViewFunction
106
105
  selection?: EditorSelection
@@ -390,42 +389,37 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
390
389
  slateEditor.insertData(event.clipboardData)
391
390
  return
392
391
  }
393
- // Resolve it as promise (can be either async promise or sync return value)
394
- new Promise<OnPasteResult>((resolve) => {
395
- const value = PortableTextEditor.getValue(portableTextEditor)
396
- const ptRange = toPortableTextRange(value, slateEditor.selection, schemaTypes)
397
- const path = ptRange?.focus.path || []
398
- resolve(
399
- onPaste({
400
- event,
401
- value,
402
- path,
403
- schemaTypes,
404
- }),
405
- )
406
- })
407
- .then((result) => {
408
- debug('Custom paste function from client resolved', result)
409
- change$.next({type: 'loading', isLoading: true})
410
- if (!result || !result.insert) {
411
- debug('No result from custom paste handler, pasting normally')
412
- slateEditor.insertData(event.clipboardData)
413
- return
414
- }
415
- if (result && result.insert) {
416
- slateEditor.insertFragment(
417
- toSlateValue(result.insert as PortableTextBlock[], {schemaTypes}),
418
- )
392
+
393
+ const value = PortableTextEditor.getValue(portableTextEditor)
394
+ const ptRange = toPortableTextRange(value, slateEditor.selection, schemaTypes)
395
+ const path = ptRange?.focus.path || []
396
+ const onPasteResult = onPaste({event, value, path, schemaTypes})
397
+
398
+ if (onPasteResult === undefined) {
399
+ debug('No result from custom paste handler, pasting normally')
400
+ slateEditor.insertData(event.clipboardData)
401
+ } else {
402
+ // Resolve it as promise (can be either async promise or sync return value)
403
+ change$.next({type: 'loading', isLoading: true})
404
+ Promise.resolve(onPasteResult)
405
+ .then((result) => {
406
+ debug('Custom paste function from client resolved', result)
407
+ if (result && result.insert) {
408
+ slateEditor.insertFragment(
409
+ toSlateValue(result.insert as PortableTextBlock[], {schemaTypes}),
410
+ )
411
+ } else {
412
+ console.warn('Your onPaste function returned something unexpected:', result)
413
+ }
414
+ })
415
+ .catch((error) => {
416
+ console.error(error) // eslint-disable-line no-console
417
+ return error
418
+ })
419
+ .finally(() => {
419
420
  change$.next({type: 'loading', isLoading: false})
420
- return
421
- }
422
- console.warn('Your onPaste function returned something unexpected:', result)
423
- })
424
- .catch((error) => {
425
- change$.next({type: 'loading', isLoading: false})
426
- console.error(error) // eslint-disable-line no-console
427
- return error
428
- })
421
+ })
422
+ }
429
423
  },
430
424
  [change$, onPaste, portableTextEditor, schemaTypes, slateEditor],
431
425
  )
@@ -1,3 +1,4 @@
1
+ import {type Patch} from '@portabletext/patches/types'
1
2
  import {type PortableTextBlock} from '@sanity/types'
2
3
  import {throttle} from 'lodash'
3
4
  import {
@@ -13,7 +14,6 @@ import {Editor} from 'slate'
13
14
  import {useSlate} from 'slate-react'
14
15
 
15
16
  import {type EditorChange, type EditorChanges, type EditorSelection} from '../../types/editor'
16
- import {type Patch} from '../../types/patch'
17
17
  import {debugWithName} from '../../utils/debug'
18
18
  import {IS_PROCESSING_LOCAL_CHANGES} from '../../utils/weakMaps'
19
19
  import {PortableTextEditorContext} from '../hooks/usePortableTextEditor'
@@ -0,0 +1,166 @@
1
+ import {describe, expect, it} from '@jest/globals'
2
+ import {isPortableTextSpan, isPortableTextTextBlock} from '@sanity/types'
3
+ import {type Descendant} from 'slate'
4
+
5
+ import {exportedForTesting} from '../createWithInsertData'
6
+
7
+ const initialValue = [
8
+ {
9
+ _key: 'a',
10
+ _type: 'myTestBlockType',
11
+ children: [
12
+ {
13
+ _key: 'a1',
14
+ _type: 'span',
15
+ marks: ['link1'],
16
+ text: 'Block A',
17
+ },
18
+ {
19
+ _key: 'a2',
20
+ _type: 'span',
21
+ marks: ['colour1'],
22
+ text: 'Block B',
23
+ },
24
+ ],
25
+ markDefs: [
26
+ {
27
+ _key: 'link1',
28
+ _type: 'link',
29
+ href: 'google.com',
30
+ newTab: false,
31
+ },
32
+ {
33
+ _key: 'colour1',
34
+ _type: 'color',
35
+ color: 'red',
36
+ },
37
+ ],
38
+ style: 'normal',
39
+ },
40
+ ] satisfies Array<Descendant>
41
+
42
+ describe('plugin: createWithInsertData _regenerateKeys', () => {
43
+ it('has MarkDefs that are allowed annotations', async () => {
44
+ const {_regenerateKeys} = exportedForTesting
45
+ let keyCursor = 0
46
+
47
+ const generatedValue = _regenerateKeys(
48
+ {
49
+ isTextBlock: isPortableTextTextBlock,
50
+ isTextSpan: isPortableTextSpan,
51
+ },
52
+ initialValue,
53
+ () => {
54
+ keyCursor++
55
+ return `k${keyCursor}`
56
+ },
57
+ 'span',
58
+ {
59
+ annotations: [
60
+ // eslint-disable-next-line camelcase
61
+ {name: 'color', jsonType: 'object', fields: [], __experimental_search: []},
62
+ // eslint-disable-next-line camelcase
63
+ {name: 'link', jsonType: 'object', fields: [], __experimental_search: []},
64
+ ],
65
+ },
66
+ )
67
+
68
+ // the keys are not important here as it's not what we are testing here
69
+ expect(generatedValue).toStrictEqual([
70
+ {
71
+ _key: 'k3',
72
+ _type: 'myTestBlockType',
73
+ children: [
74
+ {_key: 'k4', _type: 'span', marks: ['k1'], text: 'Block A'},
75
+ {
76
+ _key: 'k5',
77
+ _type: 'span',
78
+ marks: ['k2'],
79
+ text: 'Block B',
80
+ },
81
+ ],
82
+ markDefs: [
83
+ {_key: 'k1', _type: 'link', href: 'google.com', newTab: false},
84
+ {_key: 'k2', _type: 'color', color: 'red'},
85
+ ],
86
+ style: 'normal',
87
+ },
88
+ ])
89
+ })
90
+
91
+ it('removes MarkDefs when no annotations are allowed', async () => {
92
+ const {_regenerateKeys} = exportedForTesting
93
+ let keyCursor = 0
94
+
95
+ const generatedValue = _regenerateKeys(
96
+ {
97
+ isTextBlock: isPortableTextTextBlock,
98
+ isTextSpan: isPortableTextSpan,
99
+ },
100
+ initialValue,
101
+ () => {
102
+ keyCursor++
103
+ return `k${keyCursor}`
104
+ },
105
+ 'span',
106
+ {annotations: []},
107
+ )
108
+
109
+ // orphaned children marks are removed later in the normalize function
110
+ expect(generatedValue).toStrictEqual([
111
+ {
112
+ _key: 'k1',
113
+ _type: 'myTestBlockType',
114
+ children: [
115
+ {_key: 'a1', _type: 'span', marks: ['link1'], text: 'Block A'},
116
+ {
117
+ _key: 'a2',
118
+ _type: 'span',
119
+ marks: ['colour1'],
120
+ text: 'Block B',
121
+ },
122
+ ],
123
+ style: 'normal',
124
+ },
125
+ ])
126
+ })
127
+
128
+ it('updates MarkDefs when one annotations is allowed but one is not allowed', async () => {
129
+ const {_regenerateKeys} = exportedForTesting
130
+ let keyCursor = 0
131
+
132
+ const generatedValue = _regenerateKeys(
133
+ {
134
+ isTextBlock: isPortableTextTextBlock,
135
+ isTextSpan: isPortableTextSpan,
136
+ },
137
+ initialValue,
138
+ () => {
139
+ keyCursor++
140
+ return `k${keyCursor}`
141
+ },
142
+ 'span',
143
+ // eslint-disable-next-line camelcase
144
+ {annotations: [{name: 'color', jsonType: 'object', fields: [], __experimental_search: []}]},
145
+ )
146
+
147
+ // orphaned children marks are removed later in the normalize function
148
+ expect(generatedValue).toStrictEqual([
149
+ {
150
+ _key: 'k1',
151
+ _type: 'myTestBlockType',
152
+ children: [
153
+ {_key: 'a1', _type: 'span', marks: ['link1'], text: 'Block A'},
154
+ {
155
+ _key: 'a2',
156
+ _type: 'span',
157
+ marks: ['colour1'],
158
+ text: 'Block B',
159
+ },
160
+ ],
161
+ markDefs: [{_key: 'colour1', _type: 'color', color: 'red'}],
162
+ style: 'normal',
163
+ },
164
+ ])
165
+ })
166
+ })
@@ -138,6 +138,7 @@ export function createWithInsertData(
138
138
  toSlateValue(parsed, {schemaTypes}),
139
139
  keyGenerator,
140
140
  spanTypeName,
141
+ schemaTypes,
141
142
  )
142
143
  // Validate the result
143
144
  const validation = validateValue(parsed, schemaTypes, keyGenerator)
@@ -269,15 +270,39 @@ function escapeHtml(str: string) {
269
270
  * @internal
270
271
  */
271
272
  function _regenerateKeys(
272
- editor: PortableTextSlateEditor,
273
+ editor: Pick<PortableTextSlateEditor, 'isTextBlock' | 'isTextSpan'>,
273
274
  fragment: Descendant[],
274
275
  keyGenerator: () => string,
275
276
  spanTypeName: string,
277
+ editorTypes: Pick<PortableTextMemberSchemaTypes, 'annotations'>,
276
278
  ): Descendant[] {
277
279
  return fragment.map((node) => {
278
280
  const newNode: Descendant = {...node}
279
281
  // Ensure the copy has new keys
280
282
  if (editor.isTextBlock(newNode)) {
283
+ const annotations = editorTypes.annotations.map((t) => t.name)
284
+
285
+ // Ensure that if there are no annotations, we remove the markDefs
286
+ if (annotations.length === 0) {
287
+ const {markDefs, ...NewNodeNoDefs} = newNode
288
+
289
+ return {...NewNodeNoDefs, _key: keyGenerator()}
290
+ }
291
+
292
+ // Ensure that all annotations are allowed
293
+ const hasForbiddenAnnotations = (newNode.markDefs || []).some((def) => {
294
+ return !annotations.includes(def._type)
295
+ })
296
+
297
+ // if they have forbidden annotations, we remove them and keep the rest
298
+ if (hasForbiddenAnnotations) {
299
+ const allowedAnnotations = (newNode.markDefs || []).filter((def) => {
300
+ return annotations.includes(def._type)
301
+ })
302
+
303
+ return {...newNode, markDefs: allowedAnnotations, _key: keyGenerator()}
304
+ }
305
+
281
306
  newNode.markDefs = (newNode.markDefs || []).map((def) => {
282
307
  const oldKey = def._key
283
308
  const newKey = keyGenerator()
@@ -357,3 +382,11 @@ function _insertFragment(
357
382
 
358
383
  editor.onChange()
359
384
  }
385
+
386
+ /**
387
+ * functions we don't want to export but want to test
388
+ * @internal
389
+ */
390
+ export const exportedForTesting = {
391
+ _regenerateKeys,
392
+ }
@@ -1,4 +1,6 @@
1
1
  /* eslint-disable max-nested-callbacks */
2
+ import {insert, setIfMissing, unset} from '@portabletext/patches/patch-event'
3
+ import {type Patch} from '@portabletext/patches/types'
2
4
  import {type Subject} from 'rxjs'
3
5
  import {
4
6
  type Descendant,
@@ -14,14 +16,12 @@ import {
14
16
  type SplitNodeOperation,
15
17
  } from 'slate'
16
18
 
17
- import {insert, setIfMissing, unset} from '../../patch/PatchEvent'
18
19
  import {
19
20
  type EditorChange,
20
21
  type PatchObservable,
21
22
  type PortableTextMemberSchemaTypes,
22
23
  type PortableTextSlateEditor,
23
24
  } from '../../types/editor'
24
- import {type Patch} from '../../types/patch'
25
25
  import {createApplyPatch} from '../../utils/applyPatch'
26
26
  import {debugWithName} from '../../utils/debug'
27
27
  import {fromSlateValue, isEqualToEmptyEditor} from '../../utils/values'
@@ -3,13 +3,13 @@
3
3
  * The undo/redo steps are rebased against incoming patches since the step occurred.
4
4
  */
5
5
 
6
+ import {type Patch} from '@portabletext/patches/types'
6
7
  import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, parsePatch} from '@sanity/diff-match-patch'
7
8
  import {type ObjectSchemaType, type PortableTextBlock} from '@sanity/types'
8
9
  import {flatten, isEqual} from 'lodash'
9
10
  import {type Descendant, Editor, Operation, Path, type SelectionOperation, Transforms} from 'slate'
10
11
 
11
12
  import {type PatchObservable, type PortableTextSlateEditor} from '../../types/editor'
12
- import {type Patch} from '../../types/patch'
13
13
  import {debugWithName} from '../../utils/debug'
14
14
  import {fromSlateValue} from '../../utils/values'
15
15
  import {withPreserveKeys} from '../../utils/withPreserveKeys'
package/src/index.ts CHANGED
@@ -7,5 +7,4 @@ export type {PortableTextEditorProps} from './editor/PortableTextEditor'
7
7
  export {PortableTextEditor} from './editor/PortableTextEditor'
8
8
  export * from './types/editor'
9
9
  export * from './types/options'
10
- export * from './types/patch'
11
- export {compactPatches} from './utils/patches'
10
+ export * from '@portabletext/patches/types'
@@ -1,3 +1,4 @@
1
+ import {type Patch} from '@portabletext/patches/types'
1
2
  import {
2
3
  type ArraySchemaType,
3
4
  type BlockDecoratorDefinition,
@@ -30,7 +31,6 @@ import {type DOMNode} from 'slate-react/dist/utils/dom'
30
31
 
31
32
  import {type PortableTextEditableProps} from '../editor/Editable'
32
33
  import {type PortableTextEditor} from '../editor/PortableTextEditor'
33
- import {type Patch} from '../types/patch'
34
34
 
35
35
  /** @beta */
36
36
  export interface EditableAPIDeleteOptions {
@@ -467,7 +467,6 @@ export interface BlockDecoratorRenderProps {
467
467
  value: string
468
468
  }
469
469
  /** @beta */
470
-
471
470
  export interface BlockListItemRenderProps {
472
471
  block: PortableTextTextBlock
473
472
  children: ReactElement
@@ -493,10 +492,12 @@ export type RenderEditableFunction = (props: PortableTextEditableProps) => JSX.E
493
492
  export type RenderAnnotationFunction = (props: BlockAnnotationRenderProps) => JSX.Element
494
493
 
495
494
  /** @beta */
496
- export type RenderStyleFunction = (props: BlockStyleRenderProps) => JSX.Element
495
+ export type RenderPlaceholderFunction = () => React.ReactNode
497
496
 
498
497
  /** @beta */
498
+ export type RenderStyleFunction = (props: BlockStyleRenderProps) => JSX.Element
499
499
 
500
+ /** @beta */
500
501
  export interface BlockStyleRenderProps {
501
502
  block: PortableTextTextBlock
502
503
  children: ReactElement
@@ -1,4 +1,5 @@
1
1
  import {describe, expect, test} from '@jest/globals'
2
+ import {type DiffMatchPatch} from '@portabletext/patches/types'
2
3
  import {makeDiff, makePatches, stringifyPatches} from '@sanity/diff-match-patch'
3
4
  import {
4
5
  isPortableTextSpan,
@@ -11,7 +12,6 @@ import {
11
12
  import {type Descendant, type Operation} from 'slate'
12
13
 
13
14
  import {type PortableTextSlateEditor} from '../../types/editor'
14
- import {type DiffMatchPatch} from '../../types/patch'
15
15
  import {diffMatchPatch} from '../applyPatch'
16
16
 
17
17
  describe('operationToPatches: diffMatchPatch', () => {
@@ -1,4 +1,12 @@
1
1
  /* eslint-disable max-statements */
2
+ import {applyAll} from '@portabletext/patches/apply'
3
+ import {
4
+ type DiffMatchPatch,
5
+ type InsertPatch,
6
+ type Patch,
7
+ type SetPatch,
8
+ type UnsetPatch,
9
+ } from '@portabletext/patches/types'
2
10
  import {
3
11
  applyPatches as diffMatchPatchApplyPatches,
4
12
  cleanupEfficiency,
@@ -17,15 +25,7 @@ import {
17
25
  } from '@sanity/types'
18
26
  import {type Descendant, Element, type Node, type Path as SlatePath, Text, Transforms} from 'slate'
19
27
 
20
- import {applyAll} from '../patch/applyPatch'
21
28
  import {type PortableTextMemberSchemaTypes, type PortableTextSlateEditor} from '../types/editor'
22
- import {
23
- type DiffMatchPatch,
24
- type InsertPatch,
25
- type Patch,
26
- type SetPatch,
27
- type UnsetPatch,
28
- } from '../types/patch'
29
29
  import {debugWithName} from './debug'
30
30
  import {toSlateValue} from './values'
31
31
  import {KEY_TO_SLATE_ELEMENT} from './weakMaps'
@@ -1,3 +1,5 @@
1
+ import {diffMatchPatch, insert, set, setIfMissing, unset} from '@portabletext/patches/patch-event'
2
+ import {type InsertPosition, type Patch} from '@portabletext/patches/types'
1
3
  import {type Path, type PortableTextSpan, type PortableTextTextBlock} from '@sanity/types'
2
4
  import {get, isUndefined, omitBy} from 'lodash'
3
5
  import {
@@ -14,9 +16,7 @@ import {
14
16
  } from 'slate'
15
17
 
16
18
  import {type PatchFunctions} from '../editor/plugins/createWithPatches'
17
- import {diffMatchPatch, insert, set, setIfMissing, unset} from '../patch/PatchEvent'
18
19
  import {type PortableTextMemberSchemaTypes, type PortableTextSlateEditor} from '../types/editor'
19
- import {type InsertPosition, type Patch} from '../types/patch'
20
20
  import {debugWithName} from './debug'
21
21
  import {fromSlateValue} from './values'
22
22
 
@@ -1,3 +1,4 @@
1
+ import {insert, set, setIfMissing, unset} from '@portabletext/patches/patch-event'
1
2
  import {
2
3
  isPortableTextTextBlock,
3
4
  type PortableTextBlock,
@@ -6,7 +7,6 @@ import {
6
7
  } from '@sanity/types'
7
8
  import {flatten, isPlainObject, uniq} from 'lodash'
8
9
 
9
- import {insert, set, setIfMissing, unset} from '../patch/PatchEvent'
10
10
  import {type InvalidValueResolution, type PortableTextMemberSchemaTypes} from '../types/editor'
11
11
  import {EMPTY_MARKDEFS} from './values'
12
12
 
@@ -1,33 +0,0 @@
1
- import {type PathSegment} from '@sanity/types'
2
- import {flatten} from 'lodash'
3
-
4
- import {type Patch} from '../types/patch'
5
- import {diffMatchPatch, insert, prefixPath, set, setIfMissing, unset} from './patches'
6
-
7
- type PatchArg = Patch | Array<Patch>
8
-
9
- export default class PatchEvent {
10
- static from(...patches: Array<PatchArg>) {
11
- return new PatchEvent(flatten(patches))
12
- }
13
-
14
- patches: Array<Patch>
15
-
16
- constructor(patches: Array<Patch>) {
17
- this.patches = patches
18
- }
19
-
20
- prepend(...patches: Array<PatchArg>): PatchEvent {
21
- return PatchEvent.from([...flatten(patches), ...this.patches])
22
- }
23
-
24
- append(...patches: Array<PatchArg>): PatchEvent {
25
- return PatchEvent.from([...this.patches, ...flatten(patches)])
26
- }
27
-
28
- prefixAll(segment: PathSegment): PatchEvent {
29
- return PatchEvent.from(this.patches.map((patch) => prefixPath(patch, segment)))
30
- }
31
- }
32
-
33
- export {diffMatchPatch, insert, PatchEvent, set, setIfMissing, unset}
@@ -1,29 +0,0 @@
1
- import {isObject, isString} from 'lodash'
2
-
3
- import applyArrayPatch from './array'
4
- import applyObjectPatch from './object'
5
- import applyPrimitivePatch from './primitive'
6
- import applyStringPatch from './string'
7
-
8
- export function applyAll(value: any, patches: any[]) {
9
- return patches.reduce(_apply, value)
10
- }
11
-
12
- function applyPatch(value: string, patch: {type: string; path: any[]; value: any}) {
13
- if (Array.isArray(value)) {
14
- return applyArrayPatch(value, patch as any)
15
- }
16
- if (isString(value)) {
17
- return applyStringPatch(value, patch)
18
- }
19
- if (isObject(value)) {
20
- return applyObjectPatch(value, patch)
21
- }
22
- return applyPrimitivePatch(value, patch)
23
- }
24
-
25
- export default function _apply(value: string, patch: {type: string; path: any[]; value: any}) {
26
- const res = applyPatch(value, patch)
27
- // console.log('applyPatch(%o, %o) : %o (noop? %o)', value, patch, res, value === res)
28
- return res
29
- }