@y/y 14.0.0-18 → 14.0.0-20

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 (129) hide show
  1. package/README.md +7 -5
  2. package/dist/src/index.d.ts +2 -1
  3. package/dist/src/internals.d.ts +2 -9
  4. package/dist/src/structs/ContentType.d.ts +6 -12
  5. package/dist/src/structs/ContentType.d.ts.map +1 -1
  6. package/dist/src/structs/Item.d.ts +5 -6
  7. package/dist/src/structs/Item.d.ts.map +1 -1
  8. package/dist/src/utils/AttributionManager.d.ts +20 -6
  9. package/dist/src/utils/AttributionManager.d.ts.map +1 -1
  10. package/dist/src/utils/Doc.d.ts +7 -70
  11. package/dist/src/utils/Doc.d.ts.map +1 -1
  12. package/dist/src/utils/ID.d.ts +2 -2
  13. package/dist/src/utils/ID.d.ts.map +1 -1
  14. package/dist/src/utils/IdMap.d.ts +19 -16
  15. package/dist/src/utils/IdMap.d.ts.map +1 -1
  16. package/dist/src/utils/IdSet.d.ts +2 -2
  17. package/dist/src/utils/IdSet.d.ts.map +1 -1
  18. package/dist/src/utils/RelativePosition.d.ts +8 -8
  19. package/dist/src/utils/RelativePosition.d.ts.map +1 -1
  20. package/dist/src/utils/Transaction.d.ts +9 -5
  21. package/dist/src/utils/Transaction.d.ts.map +1 -1
  22. package/dist/src/utils/UndoManager.d.ts +14 -12
  23. package/dist/src/utils/UndoManager.d.ts.map +1 -1
  24. package/dist/src/utils/UpdateEncoder.d.ts +2 -0
  25. package/dist/src/utils/UpdateEncoder.d.ts.map +1 -1
  26. package/dist/src/utils/YEvent.d.ts +21 -42
  27. package/dist/src/utils/YEvent.d.ts.map +1 -1
  28. package/dist/src/utils/isParentOf.d.ts +1 -1
  29. package/dist/src/utils/isParentOf.d.ts.map +1 -1
  30. package/dist/src/utils/logging.d.ts +2 -2
  31. package/dist/src/utils/logging.d.ts.map +1 -1
  32. package/dist/src/utils/meta.d.ts +43 -0
  33. package/dist/src/utils/meta.d.ts.map +1 -0
  34. package/dist/src/utils/ts.d.ts +4 -0
  35. package/dist/src/utils/ts.d.ts.map +1 -0
  36. package/dist/src/utils/updates.d.ts +3 -9
  37. package/dist/src/utils/updates.d.ts.map +1 -1
  38. package/dist/src/ytype.d.ts +498 -0
  39. package/dist/src/ytype.d.ts.map +1 -0
  40. package/dist/tests/IdMap.tests.d.ts.map +1 -1
  41. package/dist/tests/attribution.tests.d.ts +1 -0
  42. package/dist/tests/attribution.tests.d.ts.map +1 -1
  43. package/dist/tests/compatibility.tests.d.ts.map +1 -1
  44. package/dist/tests/doc.tests.d.ts.map +1 -1
  45. package/dist/tests/relativePositions.tests.d.ts +9 -9
  46. package/dist/tests/relativePositions.tests.d.ts.map +1 -1
  47. package/dist/tests/snapshot.tests.d.ts.map +1 -1
  48. package/dist/tests/testHelper.d.ts +28 -27
  49. package/dist/tests/testHelper.d.ts.map +1 -1
  50. package/dist/tests/undo-redo.tests.d.ts.map +1 -1
  51. package/dist/tests/updates.tests.d.ts +1 -1
  52. package/dist/tests/updates.tests.d.ts.map +1 -1
  53. package/dist/tests/y-array.tests.d.ts +0 -2
  54. package/dist/tests/y-array.tests.d.ts.map +1 -1
  55. package/dist/tests/y-map.tests.d.ts +0 -3
  56. package/dist/tests/y-map.tests.d.ts.map +1 -1
  57. package/dist/tests/y-text.tests.d.ts +1 -1
  58. package/dist/tests/y-text.tests.d.ts.map +1 -1
  59. package/dist/tests/y-xml.tests.d.ts +0 -1
  60. package/dist/tests/y-xml.tests.d.ts.map +1 -1
  61. package/package.json +16 -16
  62. package/src/index.js +152 -0
  63. package/src/internals.js +35 -0
  64. package/src/structs/AbstractStruct.js +59 -0
  65. package/src/structs/ContentAny.js +115 -0
  66. package/src/structs/ContentBinary.js +93 -0
  67. package/src/structs/ContentDeleted.js +101 -0
  68. package/src/structs/ContentDoc.js +141 -0
  69. package/src/structs/ContentEmbed.js +98 -0
  70. package/src/structs/ContentFormat.js +105 -0
  71. package/src/structs/ContentJSON.js +119 -0
  72. package/src/structs/ContentString.js +113 -0
  73. package/src/structs/ContentType.js +152 -0
  74. package/src/structs/GC.js +80 -0
  75. package/src/structs/Item.js +841 -0
  76. package/src/structs/Skip.js +75 -0
  77. package/src/utils/AttributionManager.js +653 -0
  78. package/src/utils/Doc.js +266 -0
  79. package/src/utils/EventHandler.js +87 -0
  80. package/src/utils/ID.js +89 -0
  81. package/src/utils/IdMap.js +673 -0
  82. package/src/utils/IdSet.js +825 -0
  83. package/src/utils/RelativePosition.js +352 -0
  84. package/src/utils/Snapshot.js +220 -0
  85. package/src/utils/StructSet.js +137 -0
  86. package/src/utils/StructStore.js +289 -0
  87. package/src/utils/Transaction.js +671 -0
  88. package/src/utils/UndoManager.js +406 -0
  89. package/src/utils/UpdateDecoder.js +281 -0
  90. package/src/utils/UpdateEncoder.js +327 -0
  91. package/src/utils/YEvent.js +189 -0
  92. package/src/utils/delta-helpers.js +54 -0
  93. package/src/utils/encoding.js +623 -0
  94. package/src/utils/isParentOf.js +21 -0
  95. package/src/utils/logging.js +21 -0
  96. package/src/utils/meta.js +97 -0
  97. package/src/utils/ts.js +3 -0
  98. package/src/utils/updates.js +711 -0
  99. package/src/ytype.js +1962 -0
  100. package/dist/Skip-wRT7BKFP.js +0 -11877
  101. package/dist/Skip-wRT7BKFP.js.map +0 -1
  102. package/dist/index-BV-j5wdP.js +0 -163
  103. package/dist/index-BV-j5wdP.js.map +0 -1
  104. package/dist/internals.js +0 -25
  105. package/dist/internals.js.map +0 -1
  106. package/dist/src/types/AbstractType.d.ts +0 -239
  107. package/dist/src/types/AbstractType.d.ts.map +0 -1
  108. package/dist/src/types/YArray.d.ts +0 -128
  109. package/dist/src/types/YArray.d.ts.map +0 -1
  110. package/dist/src/types/YMap.d.ts +0 -112
  111. package/dist/src/types/YMap.d.ts.map +0 -1
  112. package/dist/src/types/YText.d.ts +0 -216
  113. package/dist/src/types/YText.d.ts.map +0 -1
  114. package/dist/src/types/YXmlElement.d.ts +0 -106
  115. package/dist/src/types/YXmlElement.d.ts.map +0 -1
  116. package/dist/src/types/YXmlFragment.d.ts +0 -143
  117. package/dist/src/types/YXmlFragment.d.ts.map +0 -1
  118. package/dist/src/types/YXmlHook.d.ts +0 -32
  119. package/dist/src/types/YXmlHook.d.ts.map +0 -1
  120. package/dist/src/types/YXmlText.d.ts +0 -34
  121. package/dist/src/types/YXmlText.d.ts.map +0 -1
  122. package/dist/src/utils/AbstractConnector.d.ts +0 -20
  123. package/dist/src/utils/AbstractConnector.d.ts.map +0 -1
  124. package/dist/src/utils/types.d.ts +0 -7
  125. package/dist/src/utils/types.d.ts.map +0 -1
  126. package/dist/testHelper.js +0 -617
  127. package/dist/testHelper.js.map +0 -1
  128. package/dist/yjs.js +0 -26
  129. package/dist/yjs.js.map +0 -1
@@ -0,0 +1,101 @@
1
+ import {
2
+ addToIdSet,
3
+ UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, StructStore, Item, Transaction // eslint-disable-line
4
+ } from '../internals.js'
5
+
6
+ export class ContentDeleted {
7
+ /**
8
+ * @param {number} len
9
+ */
10
+ constructor (len) {
11
+ this.len = len
12
+ }
13
+
14
+ /**
15
+ * @return {number}
16
+ */
17
+ getLength () {
18
+ return this.len
19
+ }
20
+
21
+ /**
22
+ * @return {Array<any>}
23
+ */
24
+ getContent () {
25
+ return []
26
+ }
27
+
28
+ /**
29
+ * @return {boolean}
30
+ */
31
+ isCountable () {
32
+ return false
33
+ }
34
+
35
+ /**
36
+ * @return {ContentDeleted}
37
+ */
38
+ copy () {
39
+ return new ContentDeleted(this.len)
40
+ }
41
+
42
+ /**
43
+ * @param {number} offset
44
+ * @return {ContentDeleted}
45
+ */
46
+ splice (offset) {
47
+ const right = new ContentDeleted(this.len - offset)
48
+ this.len = offset
49
+ return right
50
+ }
51
+
52
+ /**
53
+ * @param {ContentDeleted} right
54
+ * @return {boolean}
55
+ */
56
+ mergeWith (right) {
57
+ this.len += right.len
58
+ return true
59
+ }
60
+
61
+ /**
62
+ * @param {Transaction} transaction
63
+ * @param {Item} item
64
+ */
65
+ integrate (transaction, item) {
66
+ addToIdSet(transaction.deleteSet, item.id.client, item.id.clock, this.len)
67
+ item.markDeleted()
68
+ }
69
+
70
+ /**
71
+ * @param {Transaction} _transaction
72
+ */
73
+ delete (_transaction) {}
74
+ /**
75
+ * @param {Transaction} _tr
76
+ */
77
+ gc (_tr) {}
78
+ /**
79
+ * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
80
+ * @param {number} offset
81
+ * @param {number} offsetEnd
82
+ */
83
+ write (encoder, offset, offsetEnd) {
84
+ encoder.writeLen(this.len - offset - offsetEnd)
85
+ }
86
+
87
+ /**
88
+ * @return {number}
89
+ */
90
+ getRef () {
91
+ return 1
92
+ }
93
+ }
94
+
95
+ /**
96
+ * @private
97
+ *
98
+ * @param {UpdateDecoderV1 | UpdateDecoderV2 } decoder
99
+ * @return {ContentDeleted}
100
+ */
101
+ export const readContentDeleted = decoder => new ContentDeleted(decoder.readLen())
@@ -0,0 +1,141 @@
1
+ import {
2
+ Doc, UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, StructStore, Transaction, Item // eslint-disable-line
3
+ } from '../internals.js'
4
+
5
+ import * as error from 'lib0/error'
6
+
7
+ /**
8
+ * @param {string} guid
9
+ * @param {Object<string, any>} opts
10
+ */
11
+ const createDocFromOpts = (guid, opts) => new Doc({ guid, ...opts, shouldLoad: opts.shouldLoad || opts.autoLoad || false })
12
+
13
+ /**
14
+ * @private
15
+ */
16
+ export class ContentDoc {
17
+ /**
18
+ * @param {Doc} doc
19
+ */
20
+ constructor (doc) {
21
+ if (doc._item) {
22
+ console.error('This document was already integrated as a sub-document. You should create a second instance instead with the same guid.')
23
+ }
24
+ /**
25
+ * @type {Doc}
26
+ */
27
+ this.doc = doc
28
+ /**
29
+ * @type {any}
30
+ */
31
+ const opts = {}
32
+ this.opts = opts
33
+ if (!doc.gc) {
34
+ opts.gc = false
35
+ }
36
+ if (doc.autoLoad) {
37
+ opts.autoLoad = true
38
+ }
39
+ if (doc.meta !== null) {
40
+ opts.meta = doc.meta
41
+ }
42
+ }
43
+
44
+ /**
45
+ * @return {number}
46
+ */
47
+ getLength () {
48
+ return 1
49
+ }
50
+
51
+ /**
52
+ * @return {Array<any>}
53
+ */
54
+ getContent () {
55
+ return [this.doc]
56
+ }
57
+
58
+ /**
59
+ * @return {boolean}
60
+ */
61
+ isCountable () {
62
+ return true
63
+ }
64
+
65
+ /**
66
+ * @return {ContentDoc}
67
+ */
68
+ copy () {
69
+ return new ContentDoc(createDocFromOpts(this.doc.guid, this.opts))
70
+ }
71
+
72
+ /**
73
+ * @param {number} offset
74
+ * @return {ContentDoc}
75
+ */
76
+ splice (offset) {
77
+ throw error.methodUnimplemented()
78
+ }
79
+
80
+ /**
81
+ * @param {ContentDoc} right
82
+ * @return {boolean}
83
+ */
84
+ mergeWith (right) {
85
+ return false
86
+ }
87
+
88
+ /**
89
+ * @param {Transaction} transaction
90
+ * @param {Item} item
91
+ */
92
+ integrate (transaction, item) {
93
+ // this needs to be reflected in doc.destroy as well
94
+ this.doc._item = item
95
+ transaction.subdocsAdded.add(this.doc)
96
+ if (this.doc.shouldLoad) {
97
+ transaction.subdocsLoaded.add(this.doc)
98
+ }
99
+ }
100
+
101
+ /**
102
+ * @param {Transaction} transaction
103
+ */
104
+ delete (transaction) {
105
+ if (transaction.subdocsAdded.has(this.doc)) {
106
+ transaction.subdocsAdded.delete(this.doc)
107
+ } else {
108
+ transaction.subdocsRemoved.add(this.doc)
109
+ }
110
+ }
111
+
112
+ /**
113
+ * @param {Transaction} _tr
114
+ */
115
+ gc (_tr) {}
116
+
117
+ /**
118
+ * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
119
+ * @param {number} _offset
120
+ * @param {number} _offsetEnd
121
+ */
122
+ write (encoder, _offset, _offsetEnd) {
123
+ encoder.writeString(this.doc.guid)
124
+ encoder.writeAny(this.opts)
125
+ }
126
+
127
+ /**
128
+ * @return {number}
129
+ */
130
+ getRef () {
131
+ return 9
132
+ }
133
+ }
134
+
135
+ /**
136
+ * @private
137
+ *
138
+ * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
139
+ * @return {ContentDoc}
140
+ */
141
+ export const readContentDoc = decoder => new ContentDoc(createDocFromOpts(decoder.readString(), decoder.readAny()))
@@ -0,0 +1,98 @@
1
+ import {
2
+ UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, StructStore, Item, Transaction // eslint-disable-line
3
+ } from '../internals.js'
4
+
5
+ import * as error from 'lib0/error'
6
+
7
+ /**
8
+ * @private
9
+ */
10
+ export class ContentEmbed {
11
+ /**
12
+ * @param {Object} embed
13
+ */
14
+ constructor (embed) {
15
+ this.embed = embed
16
+ }
17
+
18
+ /**
19
+ * @return {number}
20
+ */
21
+ getLength () {
22
+ return 1
23
+ }
24
+
25
+ /**
26
+ * @return {Array<any>}
27
+ */
28
+ getContent () {
29
+ return [this.embed]
30
+ }
31
+
32
+ /**
33
+ * @return {boolean}
34
+ */
35
+ isCountable () {
36
+ return true
37
+ }
38
+
39
+ /**
40
+ * @return {ContentEmbed}
41
+ */
42
+ copy () {
43
+ return new ContentEmbed(this.embed)
44
+ }
45
+
46
+ /**
47
+ * @param {number} offset
48
+ * @return {ContentEmbed}
49
+ */
50
+ splice (offset) {
51
+ throw error.methodUnimplemented()
52
+ }
53
+
54
+ /**
55
+ * @param {ContentEmbed} right
56
+ * @return {boolean}
57
+ */
58
+ mergeWith (right) {
59
+ return false
60
+ }
61
+
62
+ /**
63
+ * @param {Transaction} transaction
64
+ * @param {Item} item
65
+ */
66
+ integrate (transaction, item) {}
67
+ /**
68
+ * @param {Transaction} transaction
69
+ */
70
+ delete (transaction) {}
71
+ /**
72
+ * @param {Transaction} _tr
73
+ */
74
+ gc (_tr) {}
75
+ /**
76
+ * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
77
+ * @param {number} _offset
78
+ * @param {number} _offsetEnd
79
+ */
80
+ write (encoder, _offset, _offsetEnd) {
81
+ encoder.writeJSON(this.embed)
82
+ }
83
+
84
+ /**
85
+ * @return {number}
86
+ */
87
+ getRef () {
88
+ return 5
89
+ }
90
+ }
91
+
92
+ /**
93
+ * @private
94
+ *
95
+ * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
96
+ * @return {ContentEmbed}
97
+ */
98
+ export const readContentEmbed = decoder => new ContentEmbed(decoder.readJSON())
@@ -0,0 +1,105 @@
1
+ import {
2
+ UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, Item, Transaction // eslint-disable-line
3
+ } from '../internals.js'
4
+
5
+ import * as error from 'lib0/error'
6
+
7
+ /**
8
+ * @private
9
+ */
10
+ export class ContentFormat {
11
+ /**
12
+ * @param {string} key
13
+ * @param {Object} value
14
+ */
15
+ constructor (key, value) {
16
+ this.key = key
17
+ this.value = value
18
+ }
19
+
20
+ /**
21
+ * @return {number}
22
+ */
23
+ getLength () {
24
+ return 1
25
+ }
26
+
27
+ /**
28
+ * @return {Array<any>}
29
+ */
30
+ getContent () {
31
+ return []
32
+ }
33
+
34
+ /**
35
+ * @return {boolean}
36
+ */
37
+ isCountable () {
38
+ return false
39
+ }
40
+
41
+ /**
42
+ * @return {ContentFormat}
43
+ */
44
+ copy () {
45
+ return new ContentFormat(this.key, this.value)
46
+ }
47
+
48
+ /**
49
+ * @param {number} _offset
50
+ * @return {ContentFormat}
51
+ */
52
+ splice (_offset) {
53
+ throw error.methodUnimplemented()
54
+ }
55
+
56
+ /**
57
+ * @param {ContentFormat} _right
58
+ * @return {boolean}
59
+ */
60
+ mergeWith (_right) {
61
+ return false
62
+ }
63
+
64
+ /**
65
+ * @param {Transaction} _transaction
66
+ * @param {Item} item
67
+ */
68
+ integrate (_transaction, item) {
69
+ // @todo searchmarker are currently unsupported for rich text documents
70
+ const p = /** @type {import('../ytype.js').YType<any>} */ (item.parent)
71
+ p._searchMarker = null
72
+ p._hasFormatting = true
73
+ }
74
+
75
+ /**
76
+ * @param {Transaction} _transaction
77
+ */
78
+ delete (_transaction) {}
79
+ /**
80
+ * @param {Transaction} _tr
81
+ */
82
+ gc (_tr) {}
83
+ /**
84
+ * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
85
+ * @param {number} _offset
86
+ * @param {number} _offsetEnd
87
+ */
88
+ write (encoder, _offset, _offsetEnd) {
89
+ encoder.writeKey(this.key)
90
+ encoder.writeJSON(this.value)
91
+ }
92
+
93
+ /**
94
+ * @return {number}
95
+ */
96
+ getRef () {
97
+ return 6
98
+ }
99
+ }
100
+
101
+ /**
102
+ * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
103
+ * @return {ContentFormat}
104
+ */
105
+ export const readContentFormat = decoder => new ContentFormat(decoder.readKey(), decoder.readJSON())
@@ -0,0 +1,119 @@
1
+ import {
2
+ UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, Transaction, Item, StructStore // eslint-disable-line
3
+ } from '../internals.js'
4
+
5
+ /**
6
+ * @private
7
+ */
8
+ export class ContentJSON {
9
+ /**
10
+ * @param {Array<any>} arr
11
+ */
12
+ constructor (arr) {
13
+ /**
14
+ * @type {Array<any>}
15
+ */
16
+ this.arr = arr
17
+ }
18
+
19
+ /**
20
+ * @return {number}
21
+ */
22
+ getLength () {
23
+ return this.arr.length
24
+ }
25
+
26
+ /**
27
+ * @return {Array<any>}
28
+ */
29
+ getContent () {
30
+ return this.arr
31
+ }
32
+
33
+ /**
34
+ * @return {boolean}
35
+ */
36
+ isCountable () {
37
+ return true
38
+ }
39
+
40
+ /**
41
+ * @return {ContentJSON}
42
+ */
43
+ copy () {
44
+ return new ContentJSON(this.arr)
45
+ }
46
+
47
+ /**
48
+ * @param {number} offset
49
+ * @return {ContentJSON}
50
+ */
51
+ splice (offset) {
52
+ const right = new ContentJSON(this.arr.slice(offset))
53
+ this.arr = this.arr.slice(0, offset)
54
+ return right
55
+ }
56
+
57
+ /**
58
+ * @param {ContentJSON} right
59
+ * @return {boolean}
60
+ */
61
+ mergeWith (right) {
62
+ this.arr = this.arr.concat(right.arr)
63
+ return true
64
+ }
65
+
66
+ /**
67
+ * @param {Transaction} transaction
68
+ * @param {Item} item
69
+ */
70
+ integrate (transaction, item) {}
71
+ /**
72
+ * @param {Transaction} transaction
73
+ */
74
+ delete (transaction) {}
75
+ /**
76
+ * @param {Transaction} _tr
77
+ */
78
+ gc (_tr) {}
79
+ /**
80
+ * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
81
+ * @param {number} offset
82
+ * @param {number} offsetEnd
83
+ */
84
+ write (encoder, offset, offsetEnd) {
85
+ const end = this.arr.length - offsetEnd
86
+ encoder.writeLen(end - offset)
87
+ for (let i = offset; i < end; i++) {
88
+ const c = this.arr[i]
89
+ encoder.writeString(c === undefined ? 'undefined' : JSON.stringify(c))
90
+ }
91
+ }
92
+
93
+ /**
94
+ * @return {number}
95
+ */
96
+ getRef () {
97
+ return 2
98
+ }
99
+ }
100
+
101
+ /**
102
+ * @private
103
+ *
104
+ * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
105
+ * @return {ContentJSON}
106
+ */
107
+ export const readContentJSON = decoder => {
108
+ const len = decoder.readLen()
109
+ const cs = []
110
+ for (let i = 0; i < len; i++) {
111
+ const c = decoder.readString()
112
+ if (c === 'undefined') {
113
+ cs.push(undefined)
114
+ } else {
115
+ cs.push(JSON.parse(c))
116
+ }
117
+ }
118
+ return new ContentJSON(cs)
119
+ }
@@ -0,0 +1,113 @@
1
+ import {
2
+ UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, Transaction, Item, StructStore // eslint-disable-line
3
+ } from '../internals.js'
4
+
5
+ /**
6
+ * @private
7
+ */
8
+ export class ContentString {
9
+ /**
10
+ * @param {string} str
11
+ */
12
+ constructor (str) {
13
+ /**
14
+ * @type {string}
15
+ */
16
+ this.str = str
17
+ }
18
+
19
+ /**
20
+ * @return {number}
21
+ */
22
+ getLength () {
23
+ return this.str.length
24
+ }
25
+
26
+ /**
27
+ * @return {Array<any>}
28
+ */
29
+ getContent () {
30
+ return this.str.split('')
31
+ }
32
+
33
+ /**
34
+ * @return {boolean}
35
+ */
36
+ isCountable () {
37
+ return true
38
+ }
39
+
40
+ /**
41
+ * @return {ContentString}
42
+ */
43
+ copy () {
44
+ return new ContentString(this.str)
45
+ }
46
+
47
+ /**
48
+ * @param {number} offset
49
+ * @return {ContentString}
50
+ */
51
+ splice (offset) {
52
+ const right = new ContentString(this.str.slice(offset))
53
+ this.str = this.str.slice(0, offset)
54
+
55
+ // Prevent encoding invalid documents because of splitting of surrogate pairs: https://github.com/yjs/yjs/issues/248
56
+ const firstCharCode = this.str.charCodeAt(offset - 1)
57
+ if (firstCharCode >= 0xD800 && firstCharCode <= 0xDBFF) {
58
+ // Last character of the left split is the start of a surrogate utf16/ucs2 pair.
59
+ // We don't support splitting of surrogate pairs because this may lead to invalid documents.
60
+ // Replace the invalid character with a unicode replacement character (� / U+FFFD)
61
+ this.str = this.str.slice(0, offset - 1) + '�'
62
+ // replace right as well
63
+ right.str = '�' + right.str.slice(1)
64
+ }
65
+ return right
66
+ }
67
+
68
+ /**
69
+ * @param {ContentString} right
70
+ * @return {boolean}
71
+ */
72
+ mergeWith (right) {
73
+ this.str += right.str
74
+ return true
75
+ }
76
+
77
+ /**
78
+ * @param {Transaction} transaction
79
+ * @param {Item} item
80
+ */
81
+ integrate (transaction, item) {}
82
+ /**
83
+ * @param {Transaction} transaction
84
+ */
85
+ delete (transaction) {}
86
+ /**
87
+ * @param {Transaction} _tr
88
+ */
89
+ gc (_tr) {}
90
+ /**
91
+ * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
92
+ * @param {number} offset
93
+ * @param {number} offsetEnd
94
+ */
95
+ write (encoder, offset, offsetEnd) {
96
+ encoder.writeString((offset === 0 && offsetEnd === 0) ? this.str : this.str.slice(offset, this.str.length - offsetEnd))
97
+ }
98
+
99
+ /**
100
+ * @return {number}
101
+ */
102
+ getRef () {
103
+ return 4
104
+ }
105
+ }
106
+
107
+ /**
108
+ * @private
109
+ *
110
+ * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder
111
+ * @return {ContentString}
112
+ */
113
+ export const readContentString = decoder => new ContentString(decoder.readString())