@y/y 14.0.0-rc.2 → 14.0.0-rc.21

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 (166) hide show
  1. package/README.md +36 -12
  2. package/dist/src/index.d.ts +24 -1
  3. package/dist/src/index.d.ts.map +1 -1
  4. package/dist/src/structs/AbstractStruct.d.ts +14 -17
  5. package/dist/src/structs/AbstractStruct.d.ts.map +1 -1
  6. package/dist/src/structs/GC.d.ts +9 -14
  7. package/dist/src/structs/GC.d.ts.map +1 -1
  8. package/dist/src/structs/Item.d.ts +569 -31
  9. package/dist/src/structs/Item.d.ts.map +1 -1
  10. package/dist/src/structs/Skip.d.ts +9 -11
  11. package/dist/src/structs/Skip.d.ts.map +1 -1
  12. package/dist/src/utils/BlockSet.d.ts +8 -7
  13. package/dist/src/utils/BlockSet.d.ts.map +1 -1
  14. package/dist/src/utils/Doc.d.ts +4 -9
  15. package/dist/src/utils/Doc.d.ts.map +1 -1
  16. package/dist/src/utils/ID.d.ts +0 -1
  17. package/dist/src/utils/ID.d.ts.map +1 -1
  18. package/dist/src/utils/RelativePosition.d.ts +2 -5
  19. package/dist/src/utils/RelativePosition.d.ts.map +1 -1
  20. package/dist/src/utils/Renderer.d.ts +144 -0
  21. package/dist/src/utils/Renderer.d.ts.map +1 -0
  22. package/dist/src/utils/Snapshot.d.ts +7 -11
  23. package/dist/src/utils/Snapshot.d.ts.map +1 -1
  24. package/dist/src/utils/StructStore.d.ts +45 -23
  25. package/dist/src/utils/StructStore.d.ts.map +1 -1
  26. package/dist/src/utils/Transaction.d.ts +11 -21
  27. package/dist/src/utils/Transaction.d.ts.map +1 -1
  28. package/dist/src/utils/UndoManager.d.ts +13 -14
  29. package/dist/src/utils/UndoManager.d.ts.map +1 -1
  30. package/dist/src/utils/UpdateDecoder.d.ts +1 -1
  31. package/dist/src/utils/UpdateDecoder.d.ts.map +1 -1
  32. package/dist/src/utils/UpdateEncoder.d.ts +0 -1
  33. package/dist/src/utils/UpdateEncoder.d.ts.map +1 -1
  34. package/dist/src/utils/YEvent.d.ts +22 -26
  35. package/dist/src/utils/YEvent.d.ts.map +1 -1
  36. package/dist/src/utils/content-helper.d.ts +2 -0
  37. package/dist/src/utils/content-helper.d.ts.map +1 -0
  38. package/dist/src/utils/delta-helpers.d.ts +2 -3
  39. package/dist/src/utils/delta-helpers.d.ts.map +1 -1
  40. package/dist/src/utils/encoding-helpers.d.ts +6 -0
  41. package/dist/src/utils/encoding-helpers.d.ts.map +1 -0
  42. package/dist/src/utils/encoding.d.ts +16 -18
  43. package/dist/src/utils/encoding.d.ts.map +1 -1
  44. package/dist/src/utils/ids.d.ts +331 -0
  45. package/dist/src/utils/ids.d.ts.map +1 -0
  46. package/dist/src/utils/isParentOf.d.ts +1 -2
  47. package/dist/src/utils/isParentOf.d.ts.map +1 -1
  48. package/dist/src/utils/logging.d.ts +0 -1
  49. package/dist/src/utils/logging.d.ts.map +1 -1
  50. package/dist/src/utils/meta.d.ts +15 -64
  51. package/dist/src/utils/meta.d.ts.map +1 -1
  52. package/dist/src/utils/renderer-helpers.d.ts +99 -0
  53. package/dist/src/utils/renderer-helpers.d.ts.map +1 -0
  54. package/dist/src/utils/schemas.d.ts +3 -0
  55. package/dist/src/utils/schemas.d.ts.map +1 -0
  56. package/dist/src/utils/transaction-helpers.d.ts +18 -0
  57. package/dist/src/utils/transaction-helpers.d.ts.map +1 -0
  58. package/dist/src/utils/updates.d.ts +19 -25
  59. package/dist/src/utils/updates.d.ts.map +1 -1
  60. package/dist/src/ytype.d.ts +144 -41
  61. package/dist/src/ytype.d.ts.map +1 -1
  62. package/global.d.ts +53 -0
  63. package/package.json +12 -16
  64. package/src/index.js +32 -124
  65. package/src/structs/AbstractStruct.js +21 -16
  66. package/src/structs/GC.js +15 -20
  67. package/src/structs/Item.js +992 -318
  68. package/src/structs/Skip.js +16 -19
  69. package/src/utils/BlockSet.js +20 -20
  70. package/src/utils/Doc.js +18 -29
  71. package/src/utils/ID.js +0 -2
  72. package/src/utils/RelativePosition.js +15 -25
  73. package/src/utils/{AttributionManager.js → Renderer.js} +42 -197
  74. package/src/utils/Snapshot.js +15 -37
  75. package/src/utils/StructStore.js +89 -227
  76. package/src/utils/Transaction.js +89 -321
  77. package/src/utils/UndoManager.js +157 -19
  78. package/src/utils/UpdateDecoder.js +2 -3
  79. package/src/utils/UpdateEncoder.js +0 -4
  80. package/src/utils/YEvent.js +20 -26
  81. package/src/utils/content-helper.js +0 -0
  82. package/src/utils/delta-helpers.js +21 -42
  83. package/src/utils/encoding-helpers.js +110 -0
  84. package/src/utils/encoding.js +197 -122
  85. package/src/utils/ids.js +1527 -0
  86. package/src/utils/isParentOf.js +2 -4
  87. package/src/utils/logging.js +0 -4
  88. package/src/utils/meta.js +57 -46
  89. package/src/utils/renderer-helpers.js +110 -0
  90. package/src/utils/schemas.js +3 -0
  91. package/src/utils/transaction-helpers.js +413 -0
  92. package/src/utils/updates.js +24 -146
  93. package/src/ytype.js +626 -255
  94. package/tests/testHelper.js +10 -12
  95. package/dist/src/internals.d.ts +0 -36
  96. package/dist/src/internals.d.ts.map +0 -1
  97. package/dist/src/structs/ContentAny.d.ts +0 -67
  98. package/dist/src/structs/ContentAny.d.ts.map +0 -1
  99. package/dist/src/structs/ContentBinary.d.ts +0 -64
  100. package/dist/src/structs/ContentBinary.d.ts.map +0 -1
  101. package/dist/src/structs/ContentDeleted.d.ts +0 -64
  102. package/dist/src/structs/ContentDeleted.d.ts.map +0 -1
  103. package/dist/src/structs/ContentDoc.d.ts +0 -72
  104. package/dist/src/structs/ContentDoc.d.ts.map +0 -1
  105. package/dist/src/structs/ContentEmbed.d.ts +0 -67
  106. package/dist/src/structs/ContentEmbed.d.ts.map +0 -1
  107. package/dist/src/structs/ContentFormat.d.ts +0 -69
  108. package/dist/src/structs/ContentFormat.d.ts.map +0 -1
  109. package/dist/src/structs/ContentJSON.d.ts +0 -70
  110. package/dist/src/structs/ContentJSON.d.ts.map +0 -1
  111. package/dist/src/structs/ContentString.d.ts +0 -70
  112. package/dist/src/structs/ContentString.d.ts.map +0 -1
  113. package/dist/src/structs/ContentType.d.ts +0 -77
  114. package/dist/src/structs/ContentType.d.ts.map +0 -1
  115. package/dist/src/utils/AttributionManager.d.ts +0 -238
  116. package/dist/src/utils/AttributionManager.d.ts.map +0 -1
  117. package/dist/src/utils/IdMap.d.ts +0 -164
  118. package/dist/src/utils/IdMap.d.ts.map +0 -1
  119. package/dist/src/utils/IdSet.d.ts +0 -163
  120. package/dist/src/utils/IdSet.d.ts.map +0 -1
  121. package/dist/tests/IdMap.tests.d.ts +0 -9
  122. package/dist/tests/IdMap.tests.d.ts.map +0 -1
  123. package/dist/tests/IdSet.tests.d.ts +0 -9
  124. package/dist/tests/IdSet.tests.d.ts.map +0 -1
  125. package/dist/tests/attribution.tests.d.ts +0 -9
  126. package/dist/tests/attribution.tests.d.ts.map +0 -1
  127. package/dist/tests/compatibility.tests.d.ts +0 -5
  128. package/dist/tests/compatibility.tests.d.ts.map +0 -1
  129. package/dist/tests/delta.tests.d.ts +0 -7
  130. package/dist/tests/delta.tests.d.ts.map +0 -1
  131. package/dist/tests/doc.tests.d.ts +0 -13
  132. package/dist/tests/doc.tests.d.ts.map +0 -1
  133. package/dist/tests/encoding.tests.d.ts +0 -5
  134. package/dist/tests/encoding.tests.d.ts.map +0 -1
  135. package/dist/tests/index.d.ts +0 -2
  136. package/dist/tests/index.d.ts.map +0 -1
  137. package/dist/tests/relativePositions.tests.d.ts +0 -11
  138. package/dist/tests/relativePositions.tests.d.ts.map +0 -1
  139. package/dist/tests/snapshot.tests.d.ts +0 -14
  140. package/dist/tests/snapshot.tests.d.ts.map +0 -1
  141. package/dist/tests/testHelper.d.ts +0 -171
  142. package/dist/tests/testHelper.d.ts.map +0 -1
  143. package/dist/tests/undo-redo.tests.d.ts +0 -27
  144. package/dist/tests/undo-redo.tests.d.ts.map +0 -1
  145. package/dist/tests/updates.tests.d.ts +0 -26
  146. package/dist/tests/updates.tests.d.ts.map +0 -1
  147. package/dist/tests/y-array.tests.d.ts +0 -43
  148. package/dist/tests/y-array.tests.d.ts.map +0 -1
  149. package/dist/tests/y-map.tests.d.ts +0 -42
  150. package/dist/tests/y-map.tests.d.ts.map +0 -1
  151. package/dist/tests/y-text.tests.d.ts +0 -49
  152. package/dist/tests/y-text.tests.d.ts.map +0 -1
  153. package/dist/tests/y-xml.tests.d.ts +0 -14
  154. package/dist/tests/y-xml.tests.d.ts.map +0 -1
  155. package/src/internals.js +0 -35
  156. package/src/structs/ContentAny.js +0 -115
  157. package/src/structs/ContentBinary.js +0 -93
  158. package/src/structs/ContentDeleted.js +0 -101
  159. package/src/structs/ContentDoc.js +0 -141
  160. package/src/structs/ContentEmbed.js +0 -98
  161. package/src/structs/ContentFormat.js +0 -105
  162. package/src/structs/ContentJSON.js +0 -119
  163. package/src/structs/ContentString.js +0 -113
  164. package/src/structs/ContentType.js +0 -152
  165. package/src/utils/IdMap.js +0 -673
  166. package/src/utils/IdSet.js +0 -825
@@ -1,22 +1,18 @@
1
- import {
2
- mergeIdSets,
3
- iterateStructsByIdSet,
4
- keepItem,
5
- transact,
6
- createID,
7
- redoItem,
8
- isParentOf,
9
- followRedone,
10
- getItemCleanStart,
11
- YEvent, Transaction, Doc, Item, GC, IdSet, YType, // eslint-disable-line
12
- diffIdSet
13
- } from '../internals.js'
14
-
15
1
  import * as time from 'lib0/time'
16
2
  import * as array from 'lib0/array'
17
3
  import * as logging from 'lib0/logging'
18
4
  import { ObservableV2 } from 'lib0/observable'
19
5
 
6
+ import { mergeIdSets, iterateStructsByIdSet, diffIdSet } from './ids.js'
7
+ import { Item, followRedone } from '../structs/Item.js'
8
+
9
+ import { transact } from './Transaction.js'
10
+ import { createID } from './ID.js'
11
+ import { isParentOf } from './isParentOf.js'
12
+ import { getItemCleanStart } from './transaction-helpers.js'
13
+ import { Doc } from './Doc.js'
14
+ import { YType } from '../ytype.js'
15
+
20
16
  export class StackItem {
21
17
  /**
22
18
  * @param {IdSet} insertions
@@ -96,7 +92,7 @@ const popStackItem = (undoManager, stack, eventType) => {
96
92
  }
97
93
  })
98
94
  itemsToRedo.forEach(struct => {
99
- performedChange = redoItem(transaction, struct, itemsToRedo, stackItem.inserts, undoManager.ignoreRemoteMapChanges, undoManager) !== null || performedChange
95
+ performedChange = redoItem(transaction, struct, itemsToRedo, stackItem.inserts, undoManager.ignoreRemoteAttributeChanges, undoManager) !== null || performedChange
100
96
  })
101
97
  // We want to delete in reverse order so that children are deleted before
102
98
  // parents, so we have more information available when items are filtered.
@@ -135,7 +131,7 @@ const popStackItem = (undoManager, stack, eventType) => {
135
131
  * filter returns false, the type/item won't be deleted even it is in the
136
132
  * undo/redo scope.
137
133
  * @property {Set<any>} [UndoManagerOptions.trackedOrigins=new Set([null])]
138
- * @property {boolean} [ignoreRemoteMapChanges] Experimental. By default, the UndoManager will never overwrite remote changes. Enable this property to enable overwriting remote changes on key-value changes (Y.Map, properties on Y.Xml, etc..).
134
+ * @property {boolean} [ignoreRemoteAttributeChanges] By default, the UndoManager will never overwrite remote changes. In some cases this might be the expected behavior. This property enables overwriting remote changes on attribute changes. (previously named `ignoreRemoteMapChanges`)
139
135
  * @property {Doc} [doc] The document that this UndoManager operates on. Only needed if typeScope is empty.
140
136
  */
141
137
 
@@ -166,7 +162,7 @@ export class UndoManager extends ObservableV2 {
166
162
  captureTransaction = _tr => true,
167
163
  deleteFilter = () => true,
168
164
  trackedOrigins = new Set([null]),
169
- ignoreRemoteMapChanges = false,
165
+ ignoreRemoteAttributeChanges = false,
170
166
  doc = /** @type {Doc} */ (array.isArray(typeScope) ? typeScope[0].doc : typeScope instanceof Doc ? typeScope : typeScope.doc)
171
167
  } = {}) {
172
168
  super()
@@ -202,7 +198,7 @@ export class UndoManager extends ObservableV2 {
202
198
  */
203
199
  this.currStackItem = null
204
200
  this.lastChange = 0
205
- this.ignoreRemoteMapChanges = ignoreRemoteMapChanges
201
+ this.ignoreRemoteAttributeChanges = ignoreRemoteAttributeChanges
206
202
  this.captureTimeout = captureTimeout
207
203
  /**
208
204
  * @param {Transaction} transaction
@@ -397,7 +393,7 @@ export class UndoManager extends ObservableV2 {
397
393
  * This is not guaranteed to work on documents with gc enabled!
398
394
  *
399
395
  * @param {Doc} ydoc
400
- * @param {import('./meta.js').ContentIds} contentIds
396
+ * @param {ContentIds} contentIds
401
397
  * @param {UndoManagerOptions} opts
402
398
  */
403
399
  export const undoContentIds = (ydoc, contentIds, opts = {}) => {
@@ -405,3 +401,145 @@ export const undoContentIds = (ydoc, contentIds, opts = {}) => {
405
401
  um.undoStack.push(new StackItem(diffIdSet(contentIds.inserts, contentIds.deletes), diffIdSet(contentIds.deletes, contentIds.inserts)))
406
402
  um.undo()
407
403
  }
404
+
405
+ /**
406
+ * @param {Array<StackItem>} stack
407
+ * @param {ID} id
408
+ */
409
+ const isDeletedByUndoStack = (stack, id) => array.some(stack, /** @param {StackItem} s */ s => s.deletes.hasId(id))
410
+
411
+ /**
412
+ * Redoes the effect of this operation.
413
+ *
414
+ * @param {Transaction} transaction The Yjs instance.
415
+ * @param {Item} item
416
+ * @param {Set<Item>} redoitems
417
+ * @param {IdSet} itemsToDelete
418
+ * @param {boolean} ignoreRemoteAttributeChanges
419
+ * @param {import('../utils/UndoManager.js').UndoManager} um
420
+ *
421
+ * @return {Item|null}
422
+ *
423
+ * @private
424
+ */
425
+ export const redoItem = (transaction, item, redoitems, itemsToDelete, ignoreRemoteAttributeChanges, um) => {
426
+ const doc = transaction.doc
427
+ const store = doc.store
428
+ const ownClientID = doc.clientID
429
+ const redone = item.redone
430
+ if (redone !== null) {
431
+ return getItemCleanStart(transaction, redone)
432
+ }
433
+ let parentItem = /** @type {YType} */ (item.parent)._item
434
+ /**
435
+ * @type {Item|null}
436
+ */
437
+ let left = null
438
+ /**
439
+ * @type {Item|null}
440
+ */
441
+ let right
442
+ // make sure that parent is redone
443
+ if (parentItem !== null && parentItem.deleted === true) {
444
+ // try to undo parent if it will be undone anyway
445
+ if (parentItem.redone === null && (!redoitems.has(parentItem) || redoItem(transaction, parentItem, redoitems, itemsToDelete, ignoreRemoteAttributeChanges, um) === null)) {
446
+ return null
447
+ }
448
+ while (parentItem.redone !== null) {
449
+ parentItem = getItemCleanStart(transaction, parentItem.redone)
450
+ }
451
+ }
452
+ /**
453
+ * @type {YType}
454
+ */
455
+ const parentType = /** @type {YType} */ (parentItem === null ? item.parent : /** @type {ContentType} */ (parentItem.content).type)
456
+
457
+ if (item.parentSub === null) {
458
+ // Is an array item. Insert at the old position
459
+ left = item.left
460
+ right = item
461
+ // find next cloned_redo items
462
+ while (left !== null) {
463
+ /**
464
+ * @type {Item|null}
465
+ */
466
+ let leftTrace = left
467
+ // trace redone until parent matches
468
+ while (leftTrace !== null && /** @type {YType} */ (leftTrace.parent)._item !== parentItem) {
469
+ leftTrace = leftTrace.redone === null ? null : getItemCleanStart(transaction, leftTrace.redone)
470
+ }
471
+ if (leftTrace !== null && /** @type {YType} */ (leftTrace.parent)._item === parentItem) {
472
+ left = leftTrace
473
+ break
474
+ }
475
+ left = left.left
476
+ }
477
+ while (right !== null) {
478
+ /**
479
+ * @type {Item|null}
480
+ */
481
+ let rightTrace = right
482
+ // trace redone until parent matches
483
+ while (rightTrace !== null && /** @type {YType} */ (rightTrace.parent)._item !== parentItem) {
484
+ rightTrace = rightTrace.redone === null ? null : getItemCleanStart(transaction, rightTrace.redone)
485
+ }
486
+ if (rightTrace !== null && /** @type {YType} */ (rightTrace.parent)._item === parentItem) {
487
+ right = rightTrace
488
+ break
489
+ }
490
+ right = right.right
491
+ }
492
+ } else {
493
+ right = null
494
+ if (item.right && !ignoreRemoteAttributeChanges) {
495
+ left = item
496
+ // Iterate right while right is in itemsToDelete
497
+ // If it is intended to delete right while item is redone, we can expect that item should replace right.
498
+ while (left !== null && left.right !== null && (left.right.redone || itemsToDelete.hasId(left.right.id) || isDeletedByUndoStack(um.undoStack, left.right.id) || isDeletedByUndoStack(um.redoStack, left.right.id))) {
499
+ left = left.right
500
+ // follow redone
501
+ while (left.redone) left = getItemCleanStart(transaction, left.redone)
502
+ }
503
+ if (left && left.right !== null) {
504
+ // It is not possible to redo this item because it conflicts with a
505
+ // change from another client
506
+ return null
507
+ }
508
+ } else {
509
+ left = parentType._map.get(item.parentSub) || null
510
+ }
511
+ if (left !== null && /** @type {YType} */ (left.parent)._item !== parentItem) {
512
+ left = parentType._map.get(item.parentSub) || null
513
+ }
514
+ }
515
+ const nextClock = store.getClock(ownClientID)
516
+ const nextId = createID(ownClientID, nextClock)
517
+ const redoneItem = new Item(
518
+ nextId,
519
+ left, left && left.lastId,
520
+ right, right && right.id,
521
+ parentType,
522
+ item.parentSub,
523
+ item.content.copy()
524
+ )
525
+ item.redone = nextId
526
+ keepItem(redoneItem, true)
527
+ redoneItem.integrate(transaction, 0)
528
+ return redoneItem
529
+ }
530
+
531
+ /**
532
+ * Make sure that neither item nor any of its parents is ever deleted.
533
+ *
534
+ * This property does not persist when storing it into a database or when
535
+ * sending it to other peers
536
+ *
537
+ * @param {Item|null} item
538
+ * @param {boolean} keep
539
+ */
540
+ export const keepItem = (item, keep) => {
541
+ while (item !== null && item.keep !== keep) {
542
+ item.keep = keep
543
+ item = /** @type {YType} */ (item.parent)._item
544
+ }
545
+ }
@@ -1,8 +1,7 @@
1
1
  import * as buffer from 'lib0/buffer'
2
2
  import * as decoding from 'lib0/decoding'
3
- import {
4
- ID, createID
5
- } from '../internals.js'
3
+
4
+ import { ID, createID } from './ID.js'
6
5
 
7
6
  /**
8
7
  * @typedef {IdSetDecoderV1 | IdSetDecoderV2} IdSetDecoder
@@ -1,10 +1,6 @@
1
1
  import * as error from 'lib0/error'
2
2
  import * as encoding from 'lib0/encoding'
3
3
 
4
- import {
5
- ID // eslint-disable-line
6
- } from '../internals.js'
7
-
8
4
  export class IdSetEncoderV1 {
9
5
  constructor () {
10
6
  this.restEncoder = encoding.createEncoder()
@@ -1,30 +1,24 @@
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
1
  import * as map from 'lib0/map'
11
- import * as delta from 'lib0/delta' // eslint-disable-line
12
2
  import * as set from 'lib0/set'
13
3
 
4
+ import { diffIdSet, mergeIdSets } from './ids.js'
5
+ import { baseRenderer } from './renderer-helpers.js'
6
+ import { createAbsolutePositionFromRelativePosition, createRelativePosition } from './RelativePosition.js'
7
+
14
8
  /**
15
- * @template {delta.DeltaConf} DConf
9
+ * @template {DeltaConf} DConf
16
10
  * YEvent describes the changes on a YType.
17
11
  */
18
12
  export class YEvent {
19
13
  /**
20
14
  * @param {YType<DConf>} target The changed type.
21
- * @param {Transaction} transaction
15
+ * @param {import('./Transaction.js').Transaction} transaction
22
16
  * @param {Set<any>?} subs The keys that changed
23
17
  */
24
18
  constructor (target, transaction, subs) {
25
19
  /**
26
20
  * The type on which this event was created on.
27
- * @type {YType<DConf>}
21
+ * @type {import('../ytype.js').YType<DConf>}
28
22
  */
29
23
  this.target = target
30
24
  /**
@@ -34,15 +28,15 @@ export class YEvent {
34
28
  this.currentTarget = target
35
29
  /**
36
30
  * The transaction that triggered this event.
37
- * @type {Transaction}
31
+ * @type {import('./Transaction.js').Transaction}
38
32
  */
39
33
  this.transaction = transaction
40
34
  /**
41
- * @type {delta.Delta<import('../ytype.js').DeltaConfDeltaToYType<DConf>>|null}
35
+ * @type {Delta<import('../ytype.js').DeltaConfDeltaToYType<DConf>>|null}
42
36
  */
43
37
  this._delta = null
44
38
  /**
45
- * @type {delta.Delta<DConf>|null}
39
+ * @type {Delta<DConf>|null}
46
40
  */
47
41
  this._deltaDeep = null
48
42
  /**
@@ -91,14 +85,14 @@ export class YEvent {
91
85
 
92
86
  /**
93
87
  * @template {boolean} [Deep=false]
94
- * @param {AbstractAttributionManager} am
95
88
  * @param {object} [opts]
89
+ * @param {AbstractRenderer} [opts.renderer] - renders the content (with attributions); defaults to the target type's active renderer (see {@link YType#useRenderer}), i.e. `baseRenderer` unless changed
96
90
  * @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.
91
+ * @return {Deep extends true ? Delta<DConf> : Delta<import('../ytype.js').DeltaConfDeltaToYType<DConf>>} The Delta representation of this type.
98
92
  *
99
93
  * @public
100
94
  */
101
- getDelta (am = noAttributionsManager, { deep } = {}) {
95
+ getDelta ({ renderer = this.target._renderer, deep } = {}) {
102
96
  const itemsToRender = mergeIdSets([diffIdSet(this.transaction.insertSet, this.transaction.deleteSet), diffIdSet(this.transaction.deleteSet, this.transaction.insertSet)])
103
97
  /**
104
98
  * @todo this should be done only one in the transaction step
@@ -126,14 +120,14 @@ export class YEvent {
126
120
  }
127
121
  modified = dchanged
128
122
  }
129
- return /** @type {any} */ (this.target.toDelta(am, { itemsToRender, retainDeletes: true, deletedItems: this.transaction.deleteSet, deep: !!deep, modified }))
123
+ return /** @type {any} */ (this.target.toDelta({ renderer, itemsToRender, retainDeletes: true, deletedItems: this.transaction.deleteSet, deep: !!deep, modified }))
130
124
  }
131
125
 
132
126
  /**
133
127
  * Compute the changes in the delta format.
134
128
  * A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document.
135
129
  *
136
- * @type {delta.Delta<import('../internals.js').DeltaConfDeltaToYType<DConf>>} The Delta representation of this type.
130
+ * @type {Delta<import('../ytype.js').DeltaConfDeltaToYType<DConf>>} The Delta representation of this type.
137
131
  * @public
138
132
  */
139
133
  get delta () {
@@ -144,11 +138,11 @@ export class YEvent {
144
138
  * Compute the changes in the delta format.
145
139
  * A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document.
146
140
  *
147
- * @type {delta.Delta<DConf>} The Delta representation of this type.
141
+ * @type {Delta<DConf>} The Delta representation of this type.
148
142
  * @public
149
143
  */
150
144
  get deltaDeep () {
151
- return /** @type {any} */ (this._deltaDeep ?? (this._deltaDeep = /** @type {any} */ (this.getDelta(noAttributionsManager, { deep: true }))))
145
+ return /** @type {any} */ (this._deltaDeep ?? (this._deltaDeep = /** @type {any} */ (this.getDelta({ deep: true }))))
152
146
  }
153
147
  }
154
148
 
@@ -164,13 +158,13 @@ export class YEvent {
164
158
  *
165
159
  * @param {YType} parent
166
160
  * @param {YType} child target
167
- * @param {AbstractAttributionManager} am
161
+ * @param {AbstractRenderer} renderer
168
162
  * @return {Array<string|number>} Path to the target
169
163
  *
170
164
  * @private
171
165
  * @function
172
166
  */
173
- export const getPathTo = (parent, child, am = noAttributionsManager) => {
167
+ export const getPathTo = (parent, child, renderer = baseRenderer) => {
174
168
  const path = []
175
169
  const doc = /** @type {Doc} */ (parent.doc)
176
170
  while (child._item !== null && child !== parent) {
@@ -180,7 +174,7 @@ export const getPathTo = (parent, child, am = noAttributionsManager) => {
180
174
  } else {
181
175
  const parent = /** @type {import('../ytype.js').YType} */ (child._item.parent)
182
176
  // parent is array-ish
183
- const apos = /** @type {import('../utils/RelativePosition.js').AbsolutePosition} */ (createAbsolutePositionFromRelativePosition(createRelativePosition(parent, child._item.id), doc, false, am))
177
+ const apos = /** @type {import('../utils/RelativePosition.js').AbsolutePosition} */ (createAbsolutePositionFromRelativePosition(createRelativePosition(parent, child._item.id), doc, false, renderer))
184
178
  path.unshift(apos.index)
185
179
  }
186
180
  child = /** @type {YType} */ (child._item.parent)
File without changes
@@ -1,54 +1,33 @@
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
1
  import * as delta from 'lib0/delta'
12
- import * as map from 'lib0/map'
13
- import * as set from 'lib0/set'
2
+ import { createInsertSetFromStructStore, createDeleteSetFromStructStore, diffIdSet, mergeIdSets } from './ids.js'
3
+ import { createDiffRenderer } from './Renderer.js'
4
+ import { computeModifiedFromItems } from '../ytype.js'
14
5
 
15
6
  /**
16
7
  * @param {Doc} v1
17
8
  * @param {Doc} v2
18
9
  * @return {delta.DeltaBuilderAny}
19
10
  */
20
- export const diffDocsToDelta = (v1, v2, { am = createAttributionManagerFromDiff(v1, v2) } = {}) => {
11
+ export const diffDocsToDelta = (v1, v2, { renderer = createDiffRenderer(v1, v2) } = {}) => {
12
+ const insertDiff = diffIdSet(createInsertSetFromStructStore(v2.store, false), createInsertSetFromStructStore(v1.store, false))
13
+ const deleteDiff = diffIdSet(createDeleteSetFromStructStore(v2.store), createDeleteSetFromStructStore(v1.store))
14
+ // don't render items that have been inserted and then deleted
15
+ const insertsOnly = diffIdSet(insertDiff, deleteDiff)
16
+ const deletesOnly = diffIdSet(deleteDiff, insertDiff)
17
+ const itemsToRender = mergeIdSets([insertsOnly, deleteDiff])
18
+ /**
19
+ * @type {Map<YType, Set<string|null>>}
20
+ */
21
+ const changedTypes = computeModifiedFromItems(v2.store, itemsToRender)
21
22
  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
- }
23
+ v2.share.forEach((type, typename) => {
24
+ const typeConf = changedTypes.get(type)
25
+ if (typeConf) {
26
+ const shareDelta = type.toDelta({
27
+ renderer, itemsToRender, retainDeletes: true, deletedItems: deletesOnly, modified: changedTypes, deep: true
42
28
  })
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
- })
29
+ d.modifyAttr(typename, shareDelta)
30
+ }
52
31
  })
53
32
  return d
54
33
  }
@@ -0,0 +1,110 @@
1
+ import * as encoding from 'lib0/encoding'
2
+ import * as math from 'lib0/math'
3
+ import * as array from 'lib0/array'
4
+
5
+ import { findIndexSS } from './transaction-helpers.js'
6
+ import { Skip } from '../structs/Skip.js'
7
+ import { createID } from './ID.js'
8
+ import { writeIdSet } from './ids.js'
9
+
10
+ /**
11
+ * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
12
+ * @param {Array<GC|Item|Skip>} structs All structs by `client`
13
+ * @param {number} client
14
+ * @param {Array<IdRange>} idranges
15
+ *
16
+ * @function
17
+ */
18
+ export const writeStructs = (encoder, structs, client, idranges) => {
19
+ let structsToWrite = 0 // this accounts for the skips
20
+ /**
21
+ * @type {Array<{ start: number, end: number, startClock: number, endClock: number }>}
22
+ */
23
+ const indexRanges = []
24
+ const firstPossibleClock = structs[0].id.clock
25
+ const lastStruct = array.last(structs)
26
+ const lastPossibleClock = lastStruct.id.clock + lastStruct.length
27
+ idranges.forEach(idrange => {
28
+ const startClock = math.max(idrange.clock, firstPossibleClock)
29
+ const endClock = math.min(idrange.clock + idrange.len, lastPossibleClock)
30
+ if (startClock >= endClock) return // structs for this range do not exist
31
+ // inclusive start
32
+ const start = findIndexSS(structs, startClock)
33
+ // exclusive end
34
+ const end = findIndexSS(structs, endClock - 1) + 1
35
+ structsToWrite += end - start
36
+ indexRanges.push({
37
+ start,
38
+ end,
39
+ startClock,
40
+ endClock
41
+ })
42
+ })
43
+ structsToWrite += idranges.length - 1
44
+ // start writing with this clock. this is updated to the next clock that we expect to write
45
+ let clock = indexRanges[0].startClock
46
+ // write # encoded structs
47
+ encoding.writeVarUint(encoder.restEncoder, structsToWrite)
48
+ encoder.writeClient(client)
49
+ // write clock
50
+ encoding.writeVarUint(encoder.restEncoder, clock)
51
+ indexRanges.forEach(indexRange => {
52
+ const skipLen = indexRange.startClock - clock
53
+ if (skipLen > 0) {
54
+ new Skip(createID(client, clock), skipLen).write(encoder, 0)
55
+ clock += skipLen
56
+ }
57
+ for (let i = indexRange.start; i < indexRange.end; i++) {
58
+ const struct = structs[i]
59
+ const structEnd = struct.id.clock + struct.length
60
+ const offsetEnd = math.max(structEnd - indexRange.endClock, 0)
61
+ struct.write(encoder, clock - struct.id.clock, offsetEnd)
62
+ clock = structEnd - offsetEnd
63
+ }
64
+ })
65
+ }
66
+
67
+ /**
68
+ * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
69
+ * @param {StructStore} store
70
+ * @param {IdSet} idset
71
+ *
72
+ * @todo at the moment this writes the full deleteset range
73
+ *
74
+ * @private
75
+ * @function
76
+ */
77
+ export const writeStructsFromIdSet = (encoder, store, idset) => {
78
+ // write # states that were updated
79
+ encoding.writeVarUint(encoder.restEncoder, idset.clients.size)
80
+ // Write items with higher client ids first
81
+ // This heavily improves the conflict algorithm.
82
+ array.from(idset.clients.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, ids]) => {
83
+ const idRanges = ids.getIds()
84
+ const structs = /** @type {Array<GC|Item>} */ (store.clients.get(client))
85
+ writeStructs(encoder, structs, client, idRanges)
86
+ })
87
+ }
88
+
89
+ /**
90
+ * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
91
+ * @param {Transaction} transaction
92
+ *
93
+ * @private
94
+ * @function
95
+ */
96
+ export const writeStructsFromTransaction = (encoder, transaction) => writeStructsFromIdSet(encoder, transaction.doc.store, transaction.insertSet)
97
+
98
+ /**
99
+ * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder
100
+ * @param {Transaction} transaction
101
+ * @return {boolean} Whether data was written.
102
+ */
103
+ export const writeUpdateMessageFromTransaction = (encoder, transaction) => {
104
+ if (transaction.deleteSet.clients.size === 0 && transaction.insertSet.clients.size === 0) {
105
+ return false
106
+ }
107
+ writeStructsFromTransaction(encoder, transaction)
108
+ writeIdSet(encoder, transaction.deleteSet)
109
+ return true
110
+ }