@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.
- package/README.md +7 -5
- package/dist/src/index.d.ts +2 -1
- package/dist/src/internals.d.ts +2 -9
- package/dist/src/structs/ContentType.d.ts +6 -12
- package/dist/src/structs/ContentType.d.ts.map +1 -1
- package/dist/src/structs/Item.d.ts +5 -6
- package/dist/src/structs/Item.d.ts.map +1 -1
- package/dist/src/utils/AttributionManager.d.ts +20 -6
- package/dist/src/utils/AttributionManager.d.ts.map +1 -1
- package/dist/src/utils/Doc.d.ts +7 -70
- package/dist/src/utils/Doc.d.ts.map +1 -1
- package/dist/src/utils/ID.d.ts +2 -2
- package/dist/src/utils/ID.d.ts.map +1 -1
- package/dist/src/utils/IdMap.d.ts +19 -16
- package/dist/src/utils/IdMap.d.ts.map +1 -1
- package/dist/src/utils/IdSet.d.ts +2 -2
- package/dist/src/utils/IdSet.d.ts.map +1 -1
- package/dist/src/utils/RelativePosition.d.ts +8 -8
- package/dist/src/utils/RelativePosition.d.ts.map +1 -1
- package/dist/src/utils/Transaction.d.ts +9 -5
- package/dist/src/utils/Transaction.d.ts.map +1 -1
- package/dist/src/utils/UndoManager.d.ts +14 -12
- package/dist/src/utils/UndoManager.d.ts.map +1 -1
- package/dist/src/utils/UpdateEncoder.d.ts +2 -0
- package/dist/src/utils/UpdateEncoder.d.ts.map +1 -1
- package/dist/src/utils/YEvent.d.ts +21 -42
- package/dist/src/utils/YEvent.d.ts.map +1 -1
- package/dist/src/utils/isParentOf.d.ts +1 -1
- package/dist/src/utils/isParentOf.d.ts.map +1 -1
- package/dist/src/utils/logging.d.ts +2 -2
- package/dist/src/utils/logging.d.ts.map +1 -1
- package/dist/src/utils/meta.d.ts +43 -0
- package/dist/src/utils/meta.d.ts.map +1 -0
- package/dist/src/utils/ts.d.ts +4 -0
- package/dist/src/utils/ts.d.ts.map +1 -0
- package/dist/src/utils/updates.d.ts +3 -9
- package/dist/src/utils/updates.d.ts.map +1 -1
- package/dist/src/ytype.d.ts +498 -0
- package/dist/src/ytype.d.ts.map +1 -0
- package/dist/tests/IdMap.tests.d.ts.map +1 -1
- package/dist/tests/attribution.tests.d.ts +1 -0
- package/dist/tests/attribution.tests.d.ts.map +1 -1
- package/dist/tests/compatibility.tests.d.ts.map +1 -1
- package/dist/tests/doc.tests.d.ts.map +1 -1
- package/dist/tests/relativePositions.tests.d.ts +9 -9
- package/dist/tests/relativePositions.tests.d.ts.map +1 -1
- package/dist/tests/snapshot.tests.d.ts.map +1 -1
- package/dist/tests/testHelper.d.ts +28 -27
- package/dist/tests/testHelper.d.ts.map +1 -1
- package/dist/tests/undo-redo.tests.d.ts.map +1 -1
- package/dist/tests/updates.tests.d.ts +1 -1
- package/dist/tests/updates.tests.d.ts.map +1 -1
- package/dist/tests/y-array.tests.d.ts +0 -2
- package/dist/tests/y-array.tests.d.ts.map +1 -1
- package/dist/tests/y-map.tests.d.ts +0 -3
- package/dist/tests/y-map.tests.d.ts.map +1 -1
- package/dist/tests/y-text.tests.d.ts +1 -1
- package/dist/tests/y-text.tests.d.ts.map +1 -1
- package/dist/tests/y-xml.tests.d.ts +0 -1
- package/dist/tests/y-xml.tests.d.ts.map +1 -1
- package/package.json +16 -16
- package/src/index.js +152 -0
- package/src/internals.js +35 -0
- package/src/structs/AbstractStruct.js +59 -0
- package/src/structs/ContentAny.js +115 -0
- package/src/structs/ContentBinary.js +93 -0
- package/src/structs/ContentDeleted.js +101 -0
- package/src/structs/ContentDoc.js +141 -0
- package/src/structs/ContentEmbed.js +98 -0
- package/src/structs/ContentFormat.js +105 -0
- package/src/structs/ContentJSON.js +119 -0
- package/src/structs/ContentString.js +113 -0
- package/src/structs/ContentType.js +152 -0
- package/src/structs/GC.js +80 -0
- package/src/structs/Item.js +841 -0
- package/src/structs/Skip.js +75 -0
- package/src/utils/AttributionManager.js +653 -0
- package/src/utils/Doc.js +266 -0
- package/src/utils/EventHandler.js +87 -0
- package/src/utils/ID.js +89 -0
- package/src/utils/IdMap.js +673 -0
- package/src/utils/IdSet.js +825 -0
- package/src/utils/RelativePosition.js +352 -0
- package/src/utils/Snapshot.js +220 -0
- package/src/utils/StructSet.js +137 -0
- package/src/utils/StructStore.js +289 -0
- package/src/utils/Transaction.js +671 -0
- package/src/utils/UndoManager.js +406 -0
- package/src/utils/UpdateDecoder.js +281 -0
- package/src/utils/UpdateEncoder.js +327 -0
- package/src/utils/YEvent.js +189 -0
- package/src/utils/delta-helpers.js +54 -0
- package/src/utils/encoding.js +623 -0
- package/src/utils/isParentOf.js +21 -0
- package/src/utils/logging.js +21 -0
- package/src/utils/meta.js +97 -0
- package/src/utils/ts.js +3 -0
- package/src/utils/updates.js +711 -0
- package/src/ytype.js +1962 -0
- package/dist/Skip-wRT7BKFP.js +0 -11877
- package/dist/Skip-wRT7BKFP.js.map +0 -1
- package/dist/index-BV-j5wdP.js +0 -163
- package/dist/index-BV-j5wdP.js.map +0 -1
- package/dist/internals.js +0 -25
- package/dist/internals.js.map +0 -1
- package/dist/src/types/AbstractType.d.ts +0 -239
- package/dist/src/types/AbstractType.d.ts.map +0 -1
- package/dist/src/types/YArray.d.ts +0 -128
- package/dist/src/types/YArray.d.ts.map +0 -1
- package/dist/src/types/YMap.d.ts +0 -112
- package/dist/src/types/YMap.d.ts.map +0 -1
- package/dist/src/types/YText.d.ts +0 -216
- package/dist/src/types/YText.d.ts.map +0 -1
- package/dist/src/types/YXmlElement.d.ts +0 -106
- package/dist/src/types/YXmlElement.d.ts.map +0 -1
- package/dist/src/types/YXmlFragment.d.ts +0 -143
- package/dist/src/types/YXmlFragment.d.ts.map +0 -1
- package/dist/src/types/YXmlHook.d.ts +0 -32
- package/dist/src/types/YXmlHook.d.ts.map +0 -1
- package/dist/src/types/YXmlText.d.ts +0 -34
- package/dist/src/types/YXmlText.d.ts.map +0 -1
- package/dist/src/utils/AbstractConnector.d.ts +0 -20
- package/dist/src/utils/AbstractConnector.d.ts.map +0 -1
- package/dist/src/utils/types.d.ts +0 -7
- package/dist/src/utils/types.d.ts.map +0 -1
- package/dist/testHelper.js +0 -617
- package/dist/testHelper.js.map +0 -1
- package/dist/yjs.js +0 -26
- package/dist/yjs.js.map +0 -1
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import * as error from 'lib0/error'
|
|
2
|
+
import * as encoding from 'lib0/encoding'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
ID // eslint-disable-line
|
|
6
|
+
} from '../internals.js'
|
|
7
|
+
|
|
8
|
+
export class IdSetEncoderV1 {
|
|
9
|
+
constructor () {
|
|
10
|
+
this.restEncoder = encoding.createEncoder()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
toUint8Array () {
|
|
14
|
+
return encoding.toUint8Array(this.restEncoder)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
resetIdSetCurVal () {
|
|
18
|
+
// nop
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {number} clock
|
|
23
|
+
*/
|
|
24
|
+
writeIdSetClock (clock) {
|
|
25
|
+
encoding.writeVarUint(this.restEncoder, clock)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {number} len
|
|
30
|
+
*/
|
|
31
|
+
writeIdSetLen (len) {
|
|
32
|
+
encoding.writeVarUint(this.restEncoder, len)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class UpdateEncoderV1 extends IdSetEncoderV1 {
|
|
37
|
+
/**
|
|
38
|
+
* @param {ID} id
|
|
39
|
+
*/
|
|
40
|
+
writeLeftID (id) {
|
|
41
|
+
encoding.writeVarUint(this.restEncoder, id.client)
|
|
42
|
+
encoding.writeVarUint(this.restEncoder, id.clock)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {ID} id
|
|
47
|
+
*/
|
|
48
|
+
writeRightID (id) {
|
|
49
|
+
encoding.writeVarUint(this.restEncoder, id.client)
|
|
50
|
+
encoding.writeVarUint(this.restEncoder, id.clock)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Use writeClient and writeClock instead of writeID if possible.
|
|
55
|
+
* @param {number} client
|
|
56
|
+
*/
|
|
57
|
+
writeClient (client) {
|
|
58
|
+
encoding.writeVarUint(this.restEncoder, client)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {number} info An unsigned 8-bit integer
|
|
63
|
+
*/
|
|
64
|
+
writeInfo (info) {
|
|
65
|
+
encoding.writeUint8(this.restEncoder, info)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @param {string} s
|
|
70
|
+
*/
|
|
71
|
+
writeString (s) {
|
|
72
|
+
encoding.writeVarString(this.restEncoder, s)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {boolean} isYKey
|
|
77
|
+
*/
|
|
78
|
+
writeParentInfo (isYKey) {
|
|
79
|
+
encoding.writeVarUint(this.restEncoder, isYKey ? 1 : 0)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @param {number} info An unsigned 8-bit integer
|
|
84
|
+
*/
|
|
85
|
+
writeTypeRef (info) {
|
|
86
|
+
encoding.writeVarUint(this.restEncoder, info)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Write len of a struct - well suited for Opt RLE encoder.
|
|
91
|
+
*
|
|
92
|
+
* @param {number} len
|
|
93
|
+
*/
|
|
94
|
+
writeLen (len) {
|
|
95
|
+
encoding.writeVarUint(this.restEncoder, len)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @param {any} any
|
|
100
|
+
*/
|
|
101
|
+
writeAny (any) {
|
|
102
|
+
encoding.writeAny(this.restEncoder, any)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @param {Uint8Array} buf
|
|
107
|
+
*/
|
|
108
|
+
writeBuf (buf) {
|
|
109
|
+
encoding.writeVarUint8Array(this.restEncoder, buf)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @param {any} embed
|
|
114
|
+
*/
|
|
115
|
+
writeJSON (embed) {
|
|
116
|
+
encoding.writeVarString(this.restEncoder, JSON.stringify(embed))
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @param {string} key
|
|
121
|
+
*/
|
|
122
|
+
writeKey (key) {
|
|
123
|
+
encoding.writeVarString(this.restEncoder, key)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export class IdSetEncoderV2 {
|
|
128
|
+
constructor () {
|
|
129
|
+
this.restEncoder = encoding.createEncoder() // encodes all the rest / non-optimized
|
|
130
|
+
this.dsCurrVal = 0
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
toUint8Array () {
|
|
134
|
+
return encoding.toUint8Array(this.restEncoder)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
resetIdSetCurVal () {
|
|
138
|
+
this.dsCurrVal = 0
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @param {number} clock
|
|
143
|
+
*/
|
|
144
|
+
writeIdSetClock (clock) {
|
|
145
|
+
const diff = clock - this.dsCurrVal
|
|
146
|
+
this.dsCurrVal = clock
|
|
147
|
+
encoding.writeVarUint(this.restEncoder, diff)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @param {number} len
|
|
152
|
+
*/
|
|
153
|
+
writeIdSetLen (len) {
|
|
154
|
+
if (len === 0) {
|
|
155
|
+
error.unexpectedCase()
|
|
156
|
+
}
|
|
157
|
+
encoding.writeVarUint(this.restEncoder, len - 1)
|
|
158
|
+
this.dsCurrVal += len
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export class UpdateEncoderV2 extends IdSetEncoderV2 {
|
|
163
|
+
constructor () {
|
|
164
|
+
super()
|
|
165
|
+
/**
|
|
166
|
+
* @type {Map<string,number>}
|
|
167
|
+
*/
|
|
168
|
+
this.keyMap = new Map()
|
|
169
|
+
/**
|
|
170
|
+
* Refers to the next unique key-identifier to me used.
|
|
171
|
+
* See writeKey method for more information.
|
|
172
|
+
*
|
|
173
|
+
* @type {number}
|
|
174
|
+
*/
|
|
175
|
+
this.keyClock = 0
|
|
176
|
+
this.keyClockEncoder = new encoding.IntDiffOptRleEncoder()
|
|
177
|
+
this.clientEncoder = new encoding.UintOptRleEncoder()
|
|
178
|
+
this.leftClockEncoder = new encoding.IntDiffOptRleEncoder()
|
|
179
|
+
this.rightClockEncoder = new encoding.IntDiffOptRleEncoder()
|
|
180
|
+
this.infoEncoder = new encoding.RleEncoder(encoding.writeUint8)
|
|
181
|
+
this.stringEncoder = new encoding.StringEncoder()
|
|
182
|
+
this.parentInfoEncoder = new encoding.RleEncoder(encoding.writeUint8)
|
|
183
|
+
this.typeRefEncoder = new encoding.UintOptRleEncoder()
|
|
184
|
+
this.lenEncoder = new encoding.UintOptRleEncoder()
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
toUint8Array () {
|
|
188
|
+
const encoder = encoding.createEncoder()
|
|
189
|
+
encoding.writeVarUint(encoder, 0) // this is a feature flag that we might use in the future
|
|
190
|
+
encoding.writeVarUint8Array(encoder, this.keyClockEncoder.toUint8Array())
|
|
191
|
+
encoding.writeVarUint8Array(encoder, this.clientEncoder.toUint8Array())
|
|
192
|
+
encoding.writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array())
|
|
193
|
+
encoding.writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array())
|
|
194
|
+
encoding.writeVarUint8Array(encoder, encoding.toUint8Array(this.infoEncoder))
|
|
195
|
+
encoding.writeVarUint8Array(encoder, this.stringEncoder.toUint8Array())
|
|
196
|
+
encoding.writeVarUint8Array(encoder, encoding.toUint8Array(this.parentInfoEncoder))
|
|
197
|
+
encoding.writeVarUint8Array(encoder, this.typeRefEncoder.toUint8Array())
|
|
198
|
+
encoding.writeVarUint8Array(encoder, this.lenEncoder.toUint8Array())
|
|
199
|
+
// @note The rest encoder is appended! (note the missing var)
|
|
200
|
+
encoding.writeUint8Array(encoder, encoding.toUint8Array(this.restEncoder))
|
|
201
|
+
return encoding.toUint8Array(encoder)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @param {ID} id
|
|
206
|
+
*/
|
|
207
|
+
writeLeftID (id) {
|
|
208
|
+
this.clientEncoder.write(id.client)
|
|
209
|
+
this.leftClockEncoder.write(id.clock)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @param {ID} id
|
|
214
|
+
*/
|
|
215
|
+
writeRightID (id) {
|
|
216
|
+
this.clientEncoder.write(id.client)
|
|
217
|
+
this.rightClockEncoder.write(id.clock)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @param {number} client
|
|
222
|
+
*/
|
|
223
|
+
writeClient (client) {
|
|
224
|
+
this.clientEncoder.write(client)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @param {number} info An unsigned 8-bit integer
|
|
229
|
+
*/
|
|
230
|
+
writeInfo (info) {
|
|
231
|
+
this.infoEncoder.write(info)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* @param {string} s
|
|
236
|
+
*/
|
|
237
|
+
writeString (s) {
|
|
238
|
+
this.stringEncoder.write(s)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @param {boolean} isYKey
|
|
243
|
+
*/
|
|
244
|
+
writeParentInfo (isYKey) {
|
|
245
|
+
this.parentInfoEncoder.write(isYKey ? 1 : 0)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @param {number} info An unsigned 8-bit integer
|
|
250
|
+
*/
|
|
251
|
+
writeTypeRef (info) {
|
|
252
|
+
this.typeRefEncoder.write(info)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Write len of a struct - well suited for Opt RLE encoder.
|
|
257
|
+
*
|
|
258
|
+
* @param {number} len
|
|
259
|
+
*/
|
|
260
|
+
writeLen (len) {
|
|
261
|
+
this.lenEncoder.write(len)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @param {any} any
|
|
266
|
+
*/
|
|
267
|
+
writeAny (any) {
|
|
268
|
+
encoding.writeAny(this.restEncoder, any)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* @param {Uint8Array} buf
|
|
273
|
+
*/
|
|
274
|
+
writeBuf (buf) {
|
|
275
|
+
encoding.writeVarUint8Array(this.restEncoder, buf)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* This is mainly here for legacy purposes.
|
|
280
|
+
*
|
|
281
|
+
* Initial we incoded objects using JSON. Now we use the much faster lib0/any-encoder. This method mainly exists for legacy purposes for the v1 encoder.
|
|
282
|
+
*
|
|
283
|
+
* @param {any} embed
|
|
284
|
+
*/
|
|
285
|
+
writeJSON (embed) {
|
|
286
|
+
encoding.writeAny(this.restEncoder, embed)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Property keys are often reused. For example, in y-prosemirror the key `bold` might
|
|
291
|
+
* occur very often. For a 3d application, the key `position` might occur very often.
|
|
292
|
+
*
|
|
293
|
+
* We cache these keys in a Map and refer to them via a unique number.
|
|
294
|
+
*
|
|
295
|
+
* @param {string} key
|
|
296
|
+
*/
|
|
297
|
+
writeKey (key) {
|
|
298
|
+
const clock = this.keyMap.get(key)
|
|
299
|
+
if (clock === undefined) {
|
|
300
|
+
/**
|
|
301
|
+
* @todo uncomment to introduce this feature finally
|
|
302
|
+
*
|
|
303
|
+
* Background. The ContentFormat object was always encoded using writeKey, but the decoder used to use readString.
|
|
304
|
+
* Furthermore, I forgot to set the keyclock. So everything was working fine.
|
|
305
|
+
*
|
|
306
|
+
* However, this feature here is basically useless as it is not being used (it actually only consumes extra memory).
|
|
307
|
+
*
|
|
308
|
+
* I don't know yet how to reintroduce this feature..
|
|
309
|
+
*
|
|
310
|
+
* Older clients won't be able to read updates when we reintroduce this feature. So this should probably be done using a flag.
|
|
311
|
+
*
|
|
312
|
+
*/
|
|
313
|
+
// this.keyMap.set(key, this.keyClock)
|
|
314
|
+
this.keyClockEncoder.write(this.keyClock++)
|
|
315
|
+
this.stringEncoder.write(key)
|
|
316
|
+
} else {
|
|
317
|
+
this.keyClockEncoder.write(clock)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* @typedef {IdSetEncoderV1 | IdSetEncoderV2} IdSetEncoder
|
|
324
|
+
*/
|
|
325
|
+
/**
|
|
326
|
+
* @typedef {UpdateEncoderV1 | UpdateEncoderV2} UpdateEncoder
|
|
327
|
+
*/
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import {
|
|
2
|
+
diffIdSet,
|
|
3
|
+
mergeIdSets,
|
|
4
|
+
noAttributionsManager,
|
|
5
|
+
YType, Doc, AbstractAttributionManager, Item, Transaction, AbstractStruct, // eslint-disable-line
|
|
6
|
+
createAbsolutePositionFromRelativePosition,
|
|
7
|
+
createRelativePosition
|
|
8
|
+
} from '../internals.js'
|
|
9
|
+
|
|
10
|
+
import * as map from 'lib0/map'
|
|
11
|
+
import * as delta from 'lib0/delta' // eslint-disable-line
|
|
12
|
+
import * as set from 'lib0/set'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @template {delta.DeltaConf} DConf
|
|
16
|
+
* YEvent describes the changes on a YType.
|
|
17
|
+
*/
|
|
18
|
+
export class YEvent {
|
|
19
|
+
/**
|
|
20
|
+
* @param {YType<DConf>} target The changed type.
|
|
21
|
+
* @param {Transaction} transaction
|
|
22
|
+
* @param {Set<any>?} subs The keys that changed
|
|
23
|
+
*/
|
|
24
|
+
constructor (target, transaction, subs) {
|
|
25
|
+
/**
|
|
26
|
+
* The type on which this event was created on.
|
|
27
|
+
* @type {YType<DConf>}
|
|
28
|
+
*/
|
|
29
|
+
this.target = target
|
|
30
|
+
/**
|
|
31
|
+
* The current target on which the observe callback is called.
|
|
32
|
+
* @type {YType<any>}
|
|
33
|
+
*/
|
|
34
|
+
this.currentTarget = target
|
|
35
|
+
/**
|
|
36
|
+
* The transaction that triggered this event.
|
|
37
|
+
* @type {Transaction}
|
|
38
|
+
*/
|
|
39
|
+
this.transaction = transaction
|
|
40
|
+
/**
|
|
41
|
+
* @type {delta.Delta<import('../ytype.js').DeltaConfDeltaToYType<DConf>>|null}
|
|
42
|
+
*/
|
|
43
|
+
this._delta = null
|
|
44
|
+
/**
|
|
45
|
+
* @type {delta.Delta<DConf>|null}
|
|
46
|
+
*/
|
|
47
|
+
this._deltaDeep = null
|
|
48
|
+
/**
|
|
49
|
+
* Whether the children changed.
|
|
50
|
+
* @type {Boolean}
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
this.childListChanged = false
|
|
54
|
+
/**
|
|
55
|
+
* Set of all changed attributes.
|
|
56
|
+
* @type {Set<string>}
|
|
57
|
+
*/
|
|
58
|
+
this.keysChanged = new Set()
|
|
59
|
+
subs?.forEach((sub) => {
|
|
60
|
+
if (sub === null) {
|
|
61
|
+
this.childListChanged = true
|
|
62
|
+
} else {
|
|
63
|
+
this.keysChanged.add(sub)
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Check if a struct is deleted by this event.
|
|
70
|
+
*
|
|
71
|
+
* In contrast to change.deleted, this method also returns true if the struct was added and then deleted.
|
|
72
|
+
*
|
|
73
|
+
* @param {AbstractStruct} struct
|
|
74
|
+
* @return {boolean}
|
|
75
|
+
*/
|
|
76
|
+
deletes (struct) {
|
|
77
|
+
return this.transaction.deleteSet.hasId(struct.id)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Check if a struct is added by this event.
|
|
82
|
+
*
|
|
83
|
+
* In contrast to change.deleted, this method also returns true if the struct was added and then deleted.
|
|
84
|
+
*
|
|
85
|
+
* @param {AbstractStruct} struct
|
|
86
|
+
* @return {boolean}
|
|
87
|
+
*/
|
|
88
|
+
adds (struct) {
|
|
89
|
+
return this.transaction.insertSet.hasId(struct.id)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @template {boolean} [Deep=false]
|
|
94
|
+
* @param {AbstractAttributionManager} am
|
|
95
|
+
* @param {object} [opts]
|
|
96
|
+
* @param {Deep} [opts.deep]
|
|
97
|
+
* @return {Deep extends true ? delta.Delta<DConf> : delta.Delta<import('../internals.js').DeltaConfDeltaToYType<DConf>>} The Delta representation of this type.
|
|
98
|
+
*
|
|
99
|
+
* @public
|
|
100
|
+
*/
|
|
101
|
+
getDelta (am = noAttributionsManager, { deep } = {}) {
|
|
102
|
+
const itemsToRender = mergeIdSets([diffIdSet(this.transaction.insertSet, this.transaction.deleteSet), diffIdSet(this.transaction.deleteSet, this.transaction.insertSet)])
|
|
103
|
+
/**
|
|
104
|
+
* @todo this should be done only one in the transaction step
|
|
105
|
+
*
|
|
106
|
+
* @type {Map<YType,Set<string|null>>|null}
|
|
107
|
+
*/
|
|
108
|
+
let modified = this.transaction.changed
|
|
109
|
+
if (deep) {
|
|
110
|
+
// need to add deep changes to copy of modified
|
|
111
|
+
const dchanged = new Map()
|
|
112
|
+
modified.forEach((attrs, type) => {
|
|
113
|
+
dchanged.set(type, new Set(attrs))
|
|
114
|
+
})
|
|
115
|
+
for (let m of modified.keys()) {
|
|
116
|
+
while (m._item != null) {
|
|
117
|
+
const item = m._item
|
|
118
|
+
const ms = map.setIfUndefined(dchanged, item?.parent, set.create)
|
|
119
|
+
if (item && !ms.has(item.parentSub)) {
|
|
120
|
+
ms.add(item.parentSub)
|
|
121
|
+
m = /** @type {any} */ (item.parent)
|
|
122
|
+
} else {
|
|
123
|
+
break
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
modified = dchanged
|
|
128
|
+
}
|
|
129
|
+
return /** @type {any} */ (this.target.toDelta(am, { itemsToRender, retainDeletes: true, deletedItems: this.transaction.deleteSet, deep: !!deep, modified }))
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Compute the changes in the delta format.
|
|
134
|
+
* A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document.
|
|
135
|
+
*
|
|
136
|
+
* @type {delta.Delta<import('../internals.js').DeltaConfDeltaToYType<DConf>>} The Delta representation of this type.
|
|
137
|
+
* @public
|
|
138
|
+
*/
|
|
139
|
+
get delta () {
|
|
140
|
+
return /** @type {any} */ (this._delta ?? (this._delta = this.getDelta().done()))
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Compute the changes in the delta format.
|
|
145
|
+
* A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document.
|
|
146
|
+
*
|
|
147
|
+
* @type {delta.Delta<DConf>} The Delta representation of this type.
|
|
148
|
+
* @public
|
|
149
|
+
*/
|
|
150
|
+
get deltaDeep () {
|
|
151
|
+
return /** @type {any} */ (this._deltaDeep ?? (this._deltaDeep = /** @type {any} */ (this.getDelta(noAttributionsManager, { deep: true }))))
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Compute the path from this type to the specified target.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* // `child` should be accessible via `type.get(path[0]).get(path[1])..`
|
|
160
|
+
* const path = type.getPathTo(child)
|
|
161
|
+
* // assuming `type instanceof YArray`
|
|
162
|
+
* console.log(path) // might look like => [2, 'key1']
|
|
163
|
+
* child === type.get(path[0]).get(path[1])
|
|
164
|
+
*
|
|
165
|
+
* @param {YType} parent
|
|
166
|
+
* @param {YType} child target
|
|
167
|
+
* @param {AbstractAttributionManager} am
|
|
168
|
+
* @return {Array<string|number>} Path to the target
|
|
169
|
+
*
|
|
170
|
+
* @private
|
|
171
|
+
* @function
|
|
172
|
+
*/
|
|
173
|
+
export const getPathTo = (parent, child, am = noAttributionsManager) => {
|
|
174
|
+
const path = []
|
|
175
|
+
const doc = /** @type {Doc} */ (parent.doc)
|
|
176
|
+
while (child._item !== null && child !== parent) {
|
|
177
|
+
if (child._item.parentSub !== null) {
|
|
178
|
+
// parent is map-ish
|
|
179
|
+
path.unshift(child._item.parentSub)
|
|
180
|
+
} else {
|
|
181
|
+
const parent = /** @type {import('../ytype.js').YType} */ (child._item.parent)
|
|
182
|
+
// parent is array-ish
|
|
183
|
+
const apos = /** @type {import('../utils/RelativePosition.js').AbsolutePosition} */ (createAbsolutePositionFromRelativePosition(createRelativePosition(parent, child._item.id), doc, false, am))
|
|
184
|
+
path.unshift(apos.index)
|
|
185
|
+
}
|
|
186
|
+
child = /** @type {YType} */ (child._item.parent)
|
|
187
|
+
}
|
|
188
|
+
return path
|
|
189
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createInsertSetFromStructStore,
|
|
3
|
+
createDeleteSetFromStructStore,
|
|
4
|
+
createAttributionManagerFromDiff,
|
|
5
|
+
diffIdSet,
|
|
6
|
+
mergeIdSets,
|
|
7
|
+
Item,
|
|
8
|
+
YType, Doc, // eslint-disable-line
|
|
9
|
+
iterateStructsByIdSet
|
|
10
|
+
} from '../internals.js'
|
|
11
|
+
import * as delta from 'lib0/delta'
|
|
12
|
+
import * as map from 'lib0/map'
|
|
13
|
+
import * as set from 'lib0/set'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {Doc} v1
|
|
17
|
+
* @param {Doc} v2
|
|
18
|
+
* @return {delta.DeltaBuilderAny}
|
|
19
|
+
*/
|
|
20
|
+
export const diffDocsToDelta = (v1, v2, { am = createAttributionManagerFromDiff(v1, v2) } = {}) => {
|
|
21
|
+
const d = delta.create()
|
|
22
|
+
v2.transact(tr => {
|
|
23
|
+
v2.share.forEach((type, typename) => {
|
|
24
|
+
const insertDiff = diffIdSet(createInsertSetFromStructStore(v2.store, false), createInsertSetFromStructStore(v1.store, false))
|
|
25
|
+
const deleteDiff = diffIdSet(createDeleteSetFromStructStore(v2.store), createDeleteSetFromStructStore(v1.store))
|
|
26
|
+
// don't render items that have been inserted and then deleted
|
|
27
|
+
const insertsOnly = diffIdSet(insertDiff, deleteDiff)
|
|
28
|
+
const deletesOnly = diffIdSet(deleteDiff, insertDiff)
|
|
29
|
+
const itemsToRender = mergeIdSets([insertsOnly, deleteDiff])
|
|
30
|
+
/**
|
|
31
|
+
* @type {Map<YType, Set<string|null>>}
|
|
32
|
+
*/
|
|
33
|
+
const changedTypes = new Map()
|
|
34
|
+
iterateStructsByIdSet(tr, itemsToRender, /** @param {any} item */ item => {
|
|
35
|
+
while (item instanceof Item) {
|
|
36
|
+
const parent = /** @type {YType} */ (item.parent)
|
|
37
|
+
const conf = map.setIfUndefined(changedTypes, parent, set.create)
|
|
38
|
+
if (conf.has(item.parentSub)) break // has already been marked as modified
|
|
39
|
+
conf.add(item.parentSub)
|
|
40
|
+
item = parent._item
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
const typeConf = changedTypes.get(type)
|
|
44
|
+
if (typeConf) {
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
const shareDelta = type.toDelta(am, {
|
|
47
|
+
itemsToRender, retainDeletes: true, deletedItems: deletesOnly, modified: changedTypes, deep: true
|
|
48
|
+
})
|
|
49
|
+
d.modifyAttr(typename, shareDelta)
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
return d
|
|
54
|
+
}
|