prosemirror-changeset 2.1.2 → 2.2.0-beta.1

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.
@@ -1,31 +1,34 @@
1
+ import {Node} from "prosemirror-model"
2
+ import {StepMap} from "prosemirror-transform"
1
3
  import {computeDiff} from "./diff"
2
4
  import {Change, Span} from "./change"
3
5
  export {Change, Span}
4
6
  export {simplifyChanges} from "./simplify"
5
7
 
6
- // ::- A change set tracks the changes to a document from a given
7
- // point in the past. It condenses a number of step maps down to a
8
- // flat sequence of replacements, and simplifies replacments that
9
- // partially undo themselves by comparing their content.
10
- export class ChangeSet {
11
- constructor(config, changes) {
12
- this.config = config
13
- // :: [Change] Replaced regions.
14
- this.changes = changes
15
- }
16
-
17
- // :: (Node, [StepMap], union<[any], any>) → ChangeSet
18
- // Computes a new changeset by adding the given step maps and
19
- // metadata (either as an array, per-map, or as a single value to be
20
- // associated with all maps) to the current set. Will not mutate the
21
- // old set.
22
- //
23
- // Note that due to simplification that happens after each add,
24
- // incrementally adding steps might create a different final set
25
- // than adding all those changes at once, since different document
26
- // tokens might be matched during simplification depending on the
27
- // boundaries of the current changed ranges.
28
- addSteps(newDoc, maps, data) {
8
+ /// A change set tracks the changes to a document from a given point
9
+ /// in the past. It condenses a number of step maps down to a flat
10
+ /// sequence of replacements, and simplifies replacments that
11
+ /// partially undo themselves by comparing their content.
12
+ export class ChangeSet<Data = any> {
13
+ /// @internal
14
+ constructor(
15
+ /// @internal
16
+ readonly config: {doc: Node, combine: (dataA: Data, dataB: Data) => Data},
17
+ /// Replaced regions.
18
+ readonly changes: readonly Change<Data>[]
19
+ ) {}
20
+
21
+ /// Computes a new changeset by adding the given step maps and
22
+ /// metadata (either as an array, per-map, or as a single value to be
23
+ /// associated with all maps) to the current set. Will not mutate the
24
+ /// old set.
25
+ ///
26
+ /// Note that due to simplification that happens after each add,
27
+ /// incrementally adding steps might create a different final set
28
+ /// than adding all those changes at once, since different document
29
+ /// tokens might be matched during simplification depending on the
30
+ /// boundaries of the current changed ranges.
31
+ addSteps(newDoc: Node, maps: readonly StepMap[], data: Data | readonly Data[]): ChangeSet<Data> {
29
32
  // This works by inspecting the position maps for the changes,
30
33
  // which indicate what parts of the document were replaced by new
31
34
  // content, and the size of that new content. It uses these to
@@ -40,7 +43,7 @@ export class ChangeSet {
40
43
  // a diff to try to minimize the change by dropping matching
41
44
  // pieces of the old and new document from the change.
42
45
 
43
- let stepChanges = []
46
+ let stepChanges: Change<Data>[] = []
44
47
  // Add spans for new steps.
45
48
  for (let i = 0; i < maps.length; i++) {
46
49
  let d = Array.isArray(data) ? data[i] : data
@@ -58,10 +61,11 @@ export class ChangeSet {
58
61
 
59
62
  let newChanges = mergeAll(stepChanges, this.config.combine)
60
63
  let changes = Change.merge(this.changes, newChanges, this.config.combine)
64
+ let updated: Change<Data>[] = changes as Change<Data>[]
61
65
 
62
66
  // Minimize changes when possible
63
- for (let i = 0; i < changes.length; i++) {
64
- let change = changes[i]
67
+ for (let i = 0; i < updated.length; i++) {
68
+ let change = updated[i]
65
69
  if (change.fromA == change.toA || change.fromB == change.toB ||
66
70
  // Only look at changes that touch newly added changed ranges
67
71
  !newChanges.some(r => r.toB > change.fromB && r.fromB < change.toB)) continue
@@ -71,48 +75,48 @@ export class ChangeSet {
71
75
  if (diff.length == 1 && diff[0].fromB == 0 && diff[0].toB == change.toB - change.fromB)
72
76
  continue
73
77
 
78
+ if (updated == changes) updated = changes.slice()
74
79
  if (diff.length == 1) {
75
- changes[i] = diff[0]
80
+ updated[i] = diff[0]
76
81
  } else {
77
- changes.splice(i, 1, ...diff)
82
+ updated.splice(i, 1, ...diff)
78
83
  i += diff.length - 1
79
84
  }
80
85
  }
81
86
 
82
- return new ChangeSet(this.config, changes)
87
+ return new ChangeSet(this.config, updated)
83
88
  }
84
89
 
85
- // :: Node
86
- // The starting document of the change set.
87
- get startDoc() { return this.config.doc }
88
-
89
- // :: (f: (range: Change) → any) → ChangeSet
90
- // Map the span's data values in the given set through a function
91
- // and construct a new set with the resulting data.
92
- map(f) {
93
- return new ChangeSet(this.config, this.changes.map(change => {
94
- let data = f(change)
95
- return data === change.data ? change :
96
- new Change(change.fromA, change.toA, change.fromB, change.toB, data)
90
+ /// The starting document of the change set.
91
+ get startDoc(): Node { return this.config.doc }
92
+
93
+ /// Map the span's data values in the given set through a function
94
+ /// and construct a new set with the resulting data.
95
+ map(f: (range: Span<Data>) => Data): ChangeSet<Data> {
96
+ let mapSpan = (span: Span<Data>) => {
97
+ let newData = f(span)
98
+ return newData === span.data ? span : new Span(span.length, newData)
99
+ }
100
+ return new ChangeSet(this.config, this.changes.map((ch: Change<Data>) => {
101
+ return new Change(ch.fromA, ch.toA, ch.fromB, ch.toB, ch.deleted.map(mapSpan), ch.inserted.map(mapSpan))
97
102
  }))
98
103
  }
99
104
 
100
- // :: (ChangeSet, ?[StepMap]) → ?{from: number, to: number}
101
- // Compare two changesets and return the range in which they are
102
- // changed, if any. If the document changed between the maps, pass
103
- // the maps for the steps that changed it as second argument, and
104
- // make sure the method is called on the old set and passed the new
105
- // set. The returned positions will be in new document coordinates.
106
- changedRange(b, maps) {
105
+ /// Compare two changesets and return the range in which they are
106
+ /// changed, if any. If the document changed between the maps, pass
107
+ /// the maps for the steps that changed it as second argument, and
108
+ /// make sure the method is called on the old set and passed the new
109
+ /// set. The returned positions will be in new document coordinates.
110
+ changedRange(b: ChangeSet, maps?: readonly StepMap[]): {from: number, to: number} | null {
107
111
  if (b == this) return null
108
112
  let touched = maps && touchedRange(maps)
109
113
  let moved = touched ? (touched.toB - touched.fromB) - (touched.toA - touched.fromA) : 0
110
- function map(p) {
114
+ function map(p: number) {
111
115
  return !touched || p <= touched.fromA ? p : p + moved
112
116
  }
113
117
 
114
118
  let from = touched ? touched.fromB : 2e8, to = touched ? touched.toB : -2e8
115
- function add(start, end = start) {
119
+ function add(start: number, end = start) {
116
120
  from = Math.min(start, from); to = Math.max(end, to)
117
121
  }
118
122
 
@@ -127,29 +131,31 @@ export class ChangeSet {
127
131
  return from <= to ? {from, to} : null
128
132
  }
129
133
 
130
- // :: (Node, ?(a: any, b: any) → any) → ChangeSet
131
- // Create a changeset with the given base object and configuration.
132
- // The `combine` function is used to compare and combine metadata—it
133
- // should return null when metadata isn't compatible, and a combined
134
- // version for a merged range when it is.
135
- static create(doc, combine = (a, b) => a === b ? a : null) {
136
- return new ChangeSet({combine, doc}, [], [])
134
+ /// Create a changeset with the given base object and configuration.
135
+ /// The `combine` function is used to compare and combine metadata—it
136
+ /// should return null when metadata isn't compatible, and a combined
137
+ /// version for a merged range when it is.
138
+ static create<Data = any>(doc: Node, combine: (dataA: Data, dataB: Data) => Data = (a, b) => a === b ? a : null as any) {
139
+ return new ChangeSet({combine, doc}, [])
137
140
  }
138
- }
139
141
 
140
- // Exported for testing
141
- ChangeSet.computeDiff = computeDiff
142
+ /// Exported for testing @internal
143
+ static computeDiff = computeDiff
144
+ }
142
145
 
143
- // : ([[Change]], (any, any) → any, number, number) → [Change]
144
146
  // Divide-and-conquer approach to merging a series of ranges.
145
- function mergeAll(ranges, combine, start = 0, end = ranges.length) {
147
+ function mergeAll<Data>(
148
+ ranges: readonly Change<Data>[],
149
+ combine: (dA: Data, dB: Data) => Data,
150
+ start = 0, end = ranges.length
151
+ ): readonly Change<Data>[] {
146
152
  if (end == start + 1) return [ranges[start]]
147
153
  let mid = (start + end) >> 1
148
154
  return Change.merge(mergeAll(ranges, combine, start, mid),
149
155
  mergeAll(ranges, combine, mid, end), combine)
150
156
  }
151
157
 
152
- function endRange(maps) {
158
+ function endRange(maps: readonly StepMap[]) {
153
159
  let from = 2e8, to = -2e8
154
160
  for (let i = 0; i < maps.length; i++) {
155
161
  let map = maps[i]
@@ -165,19 +171,19 @@ function endRange(maps) {
165
171
  return from == 2e8 ? null : {from, to}
166
172
  }
167
173
 
168
- function touchedRange(maps) {
174
+ function touchedRange(maps: readonly StepMap[]) {
169
175
  let b = endRange(maps)
170
176
  if (!b) return null
171
- let a = endRange(maps.map(m => m.invert()).reverse())
177
+ let a = endRange(maps.map(m => m.invert()).reverse())!
172
178
  return {fromA: a.from, toA: a.to, fromB: b.from, toB: b.to}
173
179
  }
174
180
 
175
- function sameRanges(a, b, map) {
181
+ function sameRanges<Data>(a: Change<Data>, b: Change<Data>, map: (pos: number) => number) {
176
182
  return map(a.fromB) == b.fromB && map(a.toB) == b.toB &&
177
183
  sameSpans(a.deleted, b.deleted) && sameSpans(a.inserted, b.inserted)
178
184
  }
179
185
 
180
- function sameSpans(a, b) {
186
+ function sameSpans<Data>(a: readonly Span<Data>[], b: readonly Span<Data>[]) {
181
187
  if (a.length != b.length) return false
182
188
  for (let i = 0; i < a.length; i++)
183
189
  if (a[i].length != b[i].length || a[i].data !== b[i].data) return false
@@ -1,13 +1,16 @@
1
+ import {Fragment} from "prosemirror-model"
2
+ import {Change} from "./change"
3
+
1
4
  // Convert the given range of a fragment to tokens, where node open
2
5
  // tokens are encoded as strings holding the node name, characters as
3
6
  // their character code, and node close tokens as -1.
4
- function tokens(frag, start, end, target) {
7
+ function tokens(frag: Fragment, start: number, end: number, target: (number | string)[]) {
5
8
  for (let i = 0, off = 0; i < frag.childCount; i++) {
6
9
  let child = frag.child(i), endOff = off + child.nodeSize
7
10
  let from = Math.max(off, start), to = Math.min(endOff, end)
8
11
  if (from < to) {
9
12
  if (child.isText) {
10
- for (let j = from; j < to; j++) target.push(child.text.charCodeAt(j - off))
13
+ for (let j = from; j < to; j++) target.push(child.text!.charCodeAt(j - off))
11
14
  } else if (child.isLeaf) {
12
15
  target.push(child.type.name)
13
16
  } else {
@@ -31,12 +34,11 @@ const MAX_DIFF_SIZE = 5000
31
34
  // idea is to make it higher in bigger replacements, so that you don't
32
35
  // get a diff soup of coincidentally identical letters when replacing
33
36
  // a paragraph.
34
- function minUnchanged(sizeA, sizeB) {
37
+ function minUnchanged(sizeA: number, sizeB: number) {
35
38
  return Math.min(15, Math.max(2, Math.floor(Math.max(sizeA, sizeB) / 10)))
36
39
  }
37
40
 
38
- // : (Fragment, Fragment, Change) → [Change]
39
- export function computeDiff(fragA, fragB, range) {
41
+ export function computeDiff(fragA: Fragment, fragB: Fragment, range: Change) {
40
42
  let tokA = tokens(fragA, range.fromA, range.toA, [])
41
43
  let tokB = tokens(fragB, range.fromB, range.toB, [])
42
44
 
@@ -56,8 +58,8 @@ export function computeDiff(fragA, fragB, range) {
56
58
 
57
59
  let lenA = endA - start, lenB = endB - start
58
60
  let max = Math.min(MAX_DIFF_SIZE, lenA + lenB), off = max + 1
59
- let history = []
60
- let frontier = []
61
+ let history: number[][] = []
62
+ let frontier: number[] = []
61
63
  for (let len = off * 2, i = 0; i < len; i++) frontier[i] = -1
62
64
 
63
65
  for (let size = 0; size <= max; size++) {
@@ -73,7 +75,7 @@ export function computeDiff(fragA, fragB, range) {
73
75
  // Used to add steps to a diff one at a time, back to front, merging
74
76
  // ones that are less than minSpan tokens apart
75
77
  let fromA = -1, toA = -1, fromB = -1, toB = -1
76
- let add = (fA, tA, fB, tB) => {
78
+ let add = (fA: number, tA: number, fB: number, tB: number) => {
77
79
  if (fromA > -1 && fromA < tA + minSpan) {
78
80
  fromA = fA; fromB = fB
79
81
  } else {
@@ -1,6 +1,7 @@
1
+ import {Fragment, Node} from "prosemirror-model"
1
2
  import {Span, Change} from "./change"
2
3
 
3
- let letter
4
+ let letter: RegExp | undefined
4
5
  // If the runtime support unicode properties in regexps, that's a good
5
6
  // source of info on whether something is a letter.
6
7
  try { letter = new RegExp("[\\p{Alphabetic}_]", "u") } catch(_) {}
@@ -9,7 +10,7 @@ try { letter = new RegExp("[\\p{Alphabetic}_]", "u") } catch(_) {}
9
10
  // or if it is part of these common single-case scripts.
10
11
  const nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/
11
12
 
12
- function isLetter(code) {
13
+ function isLetter(code: number) {
13
14
  if (code < 128)
14
15
  return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 79 && code <= 122
15
16
  let ch = String.fromCharCode(code)
@@ -20,15 +21,15 @@ function isLetter(code) {
20
21
  // Convert a range of document into a string, so that we can easily
21
22
  // access characters at a given position. Treat non-text tokens as
22
23
  // spaces so that they aren't considered part of a word.
23
- function getText(frag, start, end) {
24
+ function getText(frag: Fragment, start: number, end: number) {
24
25
  let out = ""
25
- function convert(frag, start, end) {
26
+ function convert(frag: Fragment, start: number, end: number) {
26
27
  for (let i = 0, off = 0; i < frag.childCount; i++) {
27
28
  let child = frag.child(i), endOff = off + child.nodeSize
28
29
  let from = Math.max(off, start), to = Math.min(endOff, end)
29
30
  if (from < to) {
30
31
  if (child.isText) {
31
- out += child.text.slice(Math.max(0, start - off), Math.min(child.text.length, end - off))
32
+ out += child.text!.slice(Math.max(0, start - off), Math.min(child.text!.length, end - off))
32
33
  } else if (child.isLeaf) {
33
34
  out += " "
34
35
  } else {
@@ -48,15 +49,14 @@ function getText(frag, start, end) {
48
49
  // candidates for merging.
49
50
  const MAX_SIMPLIFY_DISTANCE = 30
50
51
 
51
- // :: ([Change], Node) → [Change]
52
- // Simplifies a set of changes for presentation. This makes the
53
- // assumption that having both insertions and deletions within a word
54
- // is confusing, and, when such changes occur without a word boundary
55
- // between them, they should be expanded to cover the entire set of
56
- // words (in the new document) they touch. An exception is made for
57
- // single-character replacements.
58
- export function simplifyChanges(changes, doc) {
59
- let result = []
52
+ /// Simplifies a set of changes for presentation. This makes the
53
+ /// assumption that having both insertions and deletions within a word
54
+ /// is confusing, and, when such changes occur without a word boundary
55
+ /// between them, they should be expanded to cover the entire set of
56
+ /// words (in the new document) they touch. An exception is made for
57
+ /// single-character replacements.
58
+ export function simplifyChanges(changes: readonly Change[], doc: Node) {
59
+ let result: Change[] = []
60
60
  for (let i = 0; i < changes.length; i++) {
61
61
  let end = changes[i].toB, start = i
62
62
  while (i < changes.length - 1 && changes[i + 1].fromB <= end + MAX_SIMPLIFY_DISTANCE)
@@ -66,7 +66,7 @@ export function simplifyChanges(changes, doc) {
66
66
  return result
67
67
  }
68
68
 
69
- function simplifyAdjacentChanges(changes, from, to, doc, target) {
69
+ function simplifyAdjacentChanges(changes: readonly Change[], from: number, to: number, doc: Node, target: Change[]) {
70
70
  let start = Math.max(0, changes[from].fromB - MAX_SIMPLIFY_DISTANCE)
71
71
  let end = Math.min(doc.content.size, changes[to - 1].toB + MAX_SIMPLIFY_DISTANCE)
72
72
  let text = getText(doc.content, start, end)
@@ -107,9 +107,9 @@ function simplifyAdjacentChanges(changes, from, to, doc, target) {
107
107
  return changes
108
108
  }
109
109
 
110
- function combine(a, b) { return a === b ? a : null }
110
+ function combine<T>(a: T, b: T): T { return a === b ? a : null as any }
111
111
 
112
- function fillChange(changes, fromB, toB) {
112
+ function fillChange(changes: readonly Change[], fromB: number, toB: number) {
113
113
  let fromA = changes[0].fromA - (changes[0].fromB - fromB)
114
114
  let last = changes[changes.length - 1]
115
115
  let toA = last.toA + (toB - last.toB)
@@ -1,10 +1,11 @@
1
- const ist = require("ist")
2
- const {schema, doc, p} = require("prosemirror-test-builder")
3
- const {Transform} = require("prosemirror-transform")
1
+ import ist from "ist"
2
+ import {schema, doc, p} from "prosemirror-test-builder"
3
+ import {Transform} from "prosemirror-transform"
4
+ import {Node} from "prosemirror-model"
4
5
 
5
- const {ChangeSet} = require("..")
6
+ import {ChangeSet} from "prosemirror-changeset"
6
7
 
7
- function mk(doc, change) {
8
+ function mk(doc: Node, change: (tr: Transform) => Transform): {doc0: Node, tr: Transform, data: any[], set0: ChangeSet, set: ChangeSet} {
8
9
  let tr = change(new Transform(doc))
9
10
  let data = new Array(tr.steps.length).fill("a")
10
11
  let set0 = ChangeSet.create(doc)
@@ -12,7 +13,7 @@ function mk(doc, change) {
12
13
  set: set0.addSteps(tr.doc, tr.mapping.maps, data)}
13
14
  }
14
15
 
15
- function same(a, b) {
16
+ function same(a: any, b: any) {
16
17
  ist(JSON.stringify(a), JSON.stringify(b))
17
18
  }
18
19
 
@@ -42,6 +43,6 @@ describe("ChangeSet.changedRange", () => {
42
43
 
43
44
  it("detects changes in deletions", () => {
44
45
  let {set} = mk(doc(p("abc")), tr => tr.delete(2, 3))
45
- same(set.changedRange(set.map(() => "b", () => "b")), {from: 2, to: 2})
46
+ same(set.changedRange(set.map(() => "b")), {from: 2, to: 2})
46
47
  })
47
48
  })
@@ -1,8 +1,9 @@
1
- const ist = require("ist")
2
- const {schema, doc, p, blockquote, h1} = require("prosemirror-test-builder")
3
- const {Transform} = require("prosemirror-transform")
1
+ import ist from "ist"
2
+ import {schema, doc, p, blockquote, h1} from "prosemirror-test-builder"
3
+ import {Transform} from "prosemirror-transform"
4
+ import {Node} from "prosemirror-model"
4
5
 
5
- const {ChangeSet} = require("..")
6
+ import {ChangeSet} from "prosemirror-changeset"
6
7
 
7
8
  describe("ChangeSet", () => {
8
9
  it("finds a single insertion",
@@ -181,11 +182,12 @@ describe("ChangeSet", () => {
181
182
 
182
183
  it("correctly handles steps with multiple map entries", find(doc(p()), [
183
184
  tr => tr.replaceWith(1, 1, t("ab")),
184
- tr => tr.wrap(tr.doc.resolve(1).blockRange(), [{type: schema.nodes.blockquote}])
185
+ tr => tr.wrap(tr.doc.resolve(1).blockRange()!, [{type: schema.nodes.blockquote}])
185
186
  ], [[0, 0, 0, 1], [1, 1, 2, 4], [2, 2, 5, 6]]))
186
187
  })
187
188
 
188
- function find(doc, build, changes, sep) {
189
+ function find(doc: Node, build: ((tr: Transform) => void) | ((tr: Transform) => void)[],
190
+ changes: any[], sep?: number[] | boolean) {
189
191
  return () => {
190
192
  let set = ChangeSet.create(doc), curDoc = doc
191
193
  if (!Array.isArray(build)) build = [build]
@@ -198,7 +200,7 @@ function find(doc, build, changes, sep) {
198
200
 
199
201
  let owner = sep && changes.length && changes[0].length > 4
200
202
  ist(JSON.stringify(set.changes.map(ch => {
201
- let range = [ch.fromA, ch.toA, ch.fromB, ch.toB]
203
+ let range: any[] = [ch.fromA, ch.toA, ch.fromB, ch.toB]
202
204
  if (owner) range.push(ch.deleted.map(d => [d.length, d.data]),
203
205
  ch.inserted.map(d => [d.length, d.data]))
204
206
  return range
@@ -206,4 +208,4 @@ function find(doc, build, changes, sep) {
206
208
  }
207
209
  }
208
210
 
209
- function t(str) { return schema.text(str) }
211
+ function t(str: string) { return schema.text(str) }
@@ -1,10 +1,11 @@
1
- const ist = require("ist")
2
- const {doc, p, em, strong, h1, h2} = require("prosemirror-test-builder")
3
-
4
- const {Span, Change, ChangeSet: {computeDiff}} = require("..")
1
+ import ist from "ist"
2
+ import {doc, p, em, strong, h1, h2} from "prosemirror-test-builder"
3
+ import {Node} from "prosemirror-model"
4
+ import {Span, Change, ChangeSet} from "prosemirror-changeset"
5
+ const {computeDiff} = ChangeSet
5
6
 
6
7
  describe("computeDiff", () => {
7
- function test(doc1, doc2, ...ranges) {
8
+ function test(doc1: Node, doc2: Node, ...ranges: number[][]) {
8
9
  let diff = computeDiff(doc1.content, doc2.content,
9
10
  new Change(0, doc1.content.size, 0, doc2.content.size,
10
11
  [new Span(doc1.content.size, 0)],
@@ -1,5 +1,5 @@
1
- const ist = require("ist")
2
- const {Change, Span} = require("..")
1
+ import ist from "ist"
2
+ import {Change, Span} from "prosemirror-changeset"
3
3
 
4
4
  describe("mergeChanges", () => {
5
5
  it("can merge simple insertions", () => test(
@@ -43,13 +43,13 @@ describe("mergeChanges", () => {
43
43
  ))
44
44
  })
45
45
 
46
- function range(array, author = 0) {
46
+ function range(array: number[], author = 0) {
47
47
  let [fromA, toA] = array
48
48
  let [fromB, toB] = array.length > 2 ? array.slice(2) : array
49
49
  return new Change(fromA, toA, fromB, toB, [new Span(toA - fromA, author)], [new Span(toB - fromB, author)])
50
50
  }
51
51
 
52
- function test(changeA, changeB, expected) {
52
+ function test(changeA: number[][], changeB: number[][], expected: number[][]) {
53
53
  const result = Change.merge(changeA.map(range), changeB.map(range), a => a)
54
54
  .map(r => [r.fromA, r.toA, r.fromB, r.toB])
55
55
  ist(JSON.stringify(result), JSON.stringify(expected))
@@ -1,6 +1,7 @@
1
- const ist = require("ist")
2
- const {doc, p, img} = require("prosemirror-test-builder")
3
- const {simplifyChanges, Change, Span} = require("..")
1
+ import ist from "ist"
2
+ import {doc, p, img} from "prosemirror-test-builder"
3
+ import {Node} from "prosemirror-model"
4
+ import {simplifyChanges, Change, Span} from "prosemirror-changeset"
4
5
 
5
6
  describe("simplifyChanges", () => {
6
7
  it("doesn't change insertion-only changes", () => test(
@@ -25,7 +26,7 @@ describe("simplifyChanges", () => {
25
26
  [[7, 10]], doc(p("one two ----- four")), [[5, 10]]))
26
27
 
27
28
  it("treats leaf nodes as non-words", () => test(
28
- [[2, 3], [6, 7]], doc(p("one", img, "two")), [[2, 3], [6, 7]]))
29
+ [[2, 3], [6, 7]], doc(p("one", img(), "two")), [[2, 3], [6, 7]]))
29
30
 
30
31
  it("treats node boundaries as non-words", () => test(
31
32
  [[2, 3], [7, 8]], doc(p("one"), p("two")), [[2, 3], [7, 8]]))
@@ -55,13 +56,13 @@ describe("simplifyChanges", () => {
55
56
  })
56
57
  })
57
58
 
58
- function range(array, author = 0) {
59
+ function range(array: number[], author = 0) {
59
60
  let [fromA, toA] = array
60
61
  let [fromB, toB] = array.length > 2 ? array.slice(2) : array
61
62
  return new Change(fromA, toA, fromB, toB, [new Span(toA - fromA, author)], [new Span(toB - fromB, author)])
62
63
  }
63
64
 
64
- function test(changes, doc, result) {
65
+ function test(changes: number[][], doc: Node, result: number[][]) {
65
66
  let ranges = changes.map(range)
66
67
  ist(JSON.stringify(simplifyChanges(ranges, doc).map((r, i) => {
67
68
  if (result[i] && result[i].length > 2) return [r.fromA, r.toA, r.fromB, r.toB]
package/rollup.config.js DELETED
@@ -1,14 +0,0 @@
1
- module.exports = {
2
- input: './src/changeset.js',
3
- output: [{
4
- file: 'dist/index.js',
5
- format: 'cjs',
6
- sourcemap: true
7
- }, {
8
- file: 'dist/index.es.js',
9
- format: 'es',
10
- sourcemap: true
11
- }],
12
- plugins: [require('@rollup/plugin-buble')()],
13
- external(id) { return !/^[\.\/]/.test(id) }
14
- }
package/test/mocha.opts DELETED
@@ -1 +0,0 @@
1
- --require reify