@fluidframework/merge-tree 2.1.0-274160 → 2.1.0-276985

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 (143) hide show
  1. package/README.md +3 -1
  2. package/dist/attributionCollection.d.ts +5 -0
  3. package/dist/attributionCollection.d.ts.map +1 -1
  4. package/dist/attributionCollection.js.map +1 -1
  5. package/dist/client.d.ts +2 -0
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +1 -0
  8. package/dist/client.js.map +1 -1
  9. package/dist/legacy.d.ts +1 -1
  10. package/dist/localReference.d.ts +4 -0
  11. package/dist/localReference.d.ts.map +1 -1
  12. package/dist/localReference.js +2 -0
  13. package/dist/localReference.js.map +1 -1
  14. package/dist/mergeTree.d.ts +14 -1
  15. package/dist/mergeTree.d.ts.map +1 -1
  16. package/dist/mergeTree.js +32 -7
  17. package/dist/mergeTree.js.map +1 -1
  18. package/dist/mergeTreeDeltaCallback.d.ts +8 -0
  19. package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
  20. package/dist/mergeTreeDeltaCallback.js +1 -0
  21. package/dist/mergeTreeDeltaCallback.js.map +1 -1
  22. package/dist/mergeTreeNodes.d.ts +12 -0
  23. package/dist/mergeTreeNodes.d.ts.map +1 -1
  24. package/dist/mergeTreeNodes.js +5 -0
  25. package/dist/mergeTreeNodes.js.map +1 -1
  26. package/dist/mergeTreeTracking.d.ts +4 -0
  27. package/dist/mergeTreeTracking.d.ts.map +1 -1
  28. package/dist/mergeTreeTracking.js +2 -0
  29. package/dist/mergeTreeTracking.js.map +1 -1
  30. package/dist/ops.d.ts +14 -0
  31. package/dist/ops.d.ts.map +1 -1
  32. package/dist/ops.js +2 -0
  33. package/dist/ops.js.map +1 -1
  34. package/dist/perspective.d.ts +76 -0
  35. package/dist/perspective.d.ts.map +1 -0
  36. package/dist/perspective.js +123 -0
  37. package/dist/perspective.js.map +1 -0
  38. package/dist/properties.d.ts +2 -0
  39. package/dist/properties.d.ts.map +1 -1
  40. package/dist/properties.js.map +1 -1
  41. package/dist/referencePositions.d.ts +3 -0
  42. package/dist/referencePositions.d.ts.map +1 -1
  43. package/dist/referencePositions.js +2 -0
  44. package/dist/referencePositions.js.map +1 -1
  45. package/dist/revertibles.d.ts +5 -0
  46. package/dist/revertibles.d.ts.map +1 -1
  47. package/dist/revertibles.js +3 -0
  48. package/dist/revertibles.js.map +1 -1
  49. package/dist/segmentGroupCollection.d.ts +1 -0
  50. package/dist/segmentGroupCollection.d.ts.map +1 -1
  51. package/dist/segmentGroupCollection.js +1 -0
  52. package/dist/segmentGroupCollection.js.map +1 -1
  53. package/dist/segmentPropertiesManager.d.ts +2 -0
  54. package/dist/segmentPropertiesManager.d.ts.map +1 -1
  55. package/dist/segmentPropertiesManager.js +2 -0
  56. package/dist/segmentPropertiesManager.js.map +1 -1
  57. package/dist/snapshotLoader.d.ts.map +1 -1
  58. package/dist/snapshotLoader.js +0 -3
  59. package/dist/snapshotLoader.js.map +1 -1
  60. package/dist/textSegment.d.ts +3 -0
  61. package/dist/textSegment.d.ts.map +1 -1
  62. package/dist/textSegment.js +1 -0
  63. package/dist/textSegment.js.map +1 -1
  64. package/lib/attributionCollection.d.ts +5 -0
  65. package/lib/attributionCollection.d.ts.map +1 -1
  66. package/lib/attributionCollection.js.map +1 -1
  67. package/lib/client.d.ts +2 -0
  68. package/lib/client.d.ts.map +1 -1
  69. package/lib/client.js +1 -0
  70. package/lib/client.js.map +1 -1
  71. package/lib/legacy.d.ts +1 -1
  72. package/lib/localReference.d.ts +4 -0
  73. package/lib/localReference.d.ts.map +1 -1
  74. package/lib/localReference.js +2 -0
  75. package/lib/localReference.js.map +1 -1
  76. package/lib/mergeTree.d.ts +14 -1
  77. package/lib/mergeTree.d.ts.map +1 -1
  78. package/lib/mergeTree.js +32 -7
  79. package/lib/mergeTree.js.map +1 -1
  80. package/lib/mergeTreeDeltaCallback.d.ts +8 -0
  81. package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
  82. package/lib/mergeTreeDeltaCallback.js +1 -0
  83. package/lib/mergeTreeDeltaCallback.js.map +1 -1
  84. package/lib/mergeTreeNodes.d.ts +12 -0
  85. package/lib/mergeTreeNodes.d.ts.map +1 -1
  86. package/lib/mergeTreeNodes.js +5 -0
  87. package/lib/mergeTreeNodes.js.map +1 -1
  88. package/lib/mergeTreeTracking.d.ts +4 -0
  89. package/lib/mergeTreeTracking.d.ts.map +1 -1
  90. package/lib/mergeTreeTracking.js +2 -0
  91. package/lib/mergeTreeTracking.js.map +1 -1
  92. package/lib/ops.d.ts +14 -0
  93. package/lib/ops.d.ts.map +1 -1
  94. package/lib/ops.js +2 -0
  95. package/lib/ops.js.map +1 -1
  96. package/lib/perspective.d.ts +76 -0
  97. package/lib/perspective.d.ts.map +1 -0
  98. package/lib/perspective.js +115 -0
  99. package/lib/perspective.js.map +1 -0
  100. package/lib/properties.d.ts +2 -0
  101. package/lib/properties.d.ts.map +1 -1
  102. package/lib/properties.js.map +1 -1
  103. package/lib/referencePositions.d.ts +3 -0
  104. package/lib/referencePositions.d.ts.map +1 -1
  105. package/lib/referencePositions.js +2 -0
  106. package/lib/referencePositions.js.map +1 -1
  107. package/lib/revertibles.d.ts +5 -0
  108. package/lib/revertibles.d.ts.map +1 -1
  109. package/lib/revertibles.js +3 -0
  110. package/lib/revertibles.js.map +1 -1
  111. package/lib/segmentGroupCollection.d.ts +1 -0
  112. package/lib/segmentGroupCollection.d.ts.map +1 -1
  113. package/lib/segmentGroupCollection.js +1 -0
  114. package/lib/segmentGroupCollection.js.map +1 -1
  115. package/lib/segmentPropertiesManager.d.ts +2 -0
  116. package/lib/segmentPropertiesManager.d.ts.map +1 -1
  117. package/lib/segmentPropertiesManager.js +2 -0
  118. package/lib/segmentPropertiesManager.js.map +1 -1
  119. package/lib/snapshotLoader.d.ts.map +1 -1
  120. package/lib/snapshotLoader.js +0 -3
  121. package/lib/snapshotLoader.js.map +1 -1
  122. package/lib/textSegment.d.ts +3 -0
  123. package/lib/textSegment.d.ts.map +1 -1
  124. package/lib/textSegment.js +1 -0
  125. package/lib/textSegment.js.map +1 -1
  126. package/package.json +17 -17
  127. package/src/attributionCollection.ts +5 -0
  128. package/src/client.ts +2 -0
  129. package/src/localReference.ts +4 -0
  130. package/src/mergeTree.ts +41 -9
  131. package/src/mergeTreeDeltaCallback.ts +8 -0
  132. package/src/mergeTreeNodes.ts +12 -0
  133. package/src/mergeTreeTracking.ts +4 -0
  134. package/src/ops.ts +14 -0
  135. package/src/perspective.ts +142 -0
  136. package/src/properties.ts +2 -0
  137. package/src/referencePositions.ts +3 -0
  138. package/src/revertibles.ts +5 -0
  139. package/src/segmentGroupCollection.ts +1 -0
  140. package/src/segmentPropertiesManager.ts +2 -0
  141. package/src/snapshotLoader.ts +0 -2
  142. package/src/textSegment.ts +3 -0
  143. /package/api-report/{merge-tree.alpha.api.md → merge-tree.legacy.alpha.api.md} +0 -0
package/src/mergeTree.ts CHANGED
@@ -76,6 +76,7 @@ import {
76
76
  ReferenceType,
77
77
  } from "./ops.js";
78
78
  import { PartialSequenceLengths } from "./partialLengths.js";
79
+ import { PerspectiveImpl, isSegmentPresent } from "./perspective.js";
79
80
  // eslint-disable-next-line import/no-deprecated
80
81
  import { PropertySet, createMap, extend, extendIfUndefined } from "./properties.js";
81
82
  import {
@@ -143,6 +144,7 @@ const LRUSegmentComparer: IComparer<LRUSegment> = {
143
144
  };
144
145
 
145
146
  /**
147
+ * @legacy
146
148
  * @alpha
147
149
  */
148
150
  export interface IMergeTreeOptions {
@@ -192,6 +194,7 @@ export interface IMergeTreeOptions {
192
194
  }
193
195
 
194
196
  /**
197
+ * @legacy
195
198
  * @alpha
196
199
  */
197
200
  export interface IMergeTreeAttributionOptions {
@@ -218,6 +221,7 @@ export interface IMergeTreeAttributionOptions {
218
221
  /**
219
222
  * Implements policy dictating which kinds of operations should be attributed and how.
220
223
  * @sealed
224
+ * @legacy
221
225
  * @alpha
222
226
  */
223
227
  export interface AttributionPolicy {
@@ -1026,27 +1030,55 @@ export class MergeTree {
1026
1030
  }
1027
1031
  }
1028
1032
 
1033
+ /**
1034
+ * Returns the count of elements before the given reference position from the given perspective.
1035
+ *
1036
+ * @param refPos - The reference position to resolve.
1037
+ * @param refSeq - The number of the latest sequenced change to consider.
1038
+ * Defaults to including all edits which have been applied.
1039
+ * @param clientId - The ID of the client from whose perspective to resolve this reference. Defaults to the current client.
1040
+ * @param localSeq - The local sequence number to consider. Defaults to including all local edits.
1041
+ * @returns the count of elements before the given reference position in the given perspective.
1042
+ */
1029
1043
  public referencePositionToLocalPosition(
1030
1044
  refPos: ReferencePosition,
1031
- refSeq = this.collabWindow.currentSeq,
1045
+ refSeq = Number.MAX_SAFE_INTEGER,
1032
1046
  clientId = this.collabWindow.clientId,
1047
+ localSeq: number | undefined = this.collabWindow.localSeq,
1033
1048
  ): number {
1034
1049
  const seg: ISegmentLeaf | undefined = refPos.getSegment();
1035
1050
  if (seg?.parent === undefined) {
1051
+ // We have no idea where this reference is, because it refers to a segment which is not in the tree.
1036
1052
  return DetachedReferencePosition;
1037
1053
  }
1038
1054
  if (refPos.isLeaf()) {
1039
- return this.getPosition(refPos, refSeq, clientId);
1055
+ return this.getPosition(refPos, refSeq, clientId, localSeq);
1040
1056
  }
1041
1057
  if (refTypeIncludesFlag(refPos, ReferenceType.Transient) || seg.localRefs?.has(refPos)) {
1042
- const offset = isRemovedOrMoved(seg) ? 0 : refPos.getOffset();
1043
- const pos = this.getPosition(seg, refSeq, clientId);
1044
-
1045
- if (isRemovedOrMoved(seg) && refPos.slidingPreference === SlidingPreference.BACKWARD) {
1046
- return pos === 0 ? 0 : pos - 1;
1058
+ if (
1059
+ seg !== this.startOfTree &&
1060
+ seg !== this.endOfTree &&
1061
+ !isSegmentPresent(seg, { refSeq, localSeq })
1062
+ ) {
1063
+ const forward = refPos.slidingPreference === SlidingPreference.FORWARD;
1064
+ const slideSeq =
1065
+ seg.movedSeq !== UnassignedSequenceNumber && seg.movedSeq !== undefined
1066
+ ? seg.movedSeq
1067
+ : seg.removedSeq !== UnassignedSequenceNumber && seg.removedSeq !== undefined
1068
+ ? seg.removedSeq
1069
+ : refSeq;
1070
+ const slideLocalSeq = seg.localMovedSeq ?? seg.localRemovedSeq;
1071
+ const perspective = new PerspectiveImpl(this, {
1072
+ refSeq: slideSeq,
1073
+ localSeq: slideLocalSeq,
1074
+ });
1075
+ const slidSegment = perspective.nextSegment(seg, forward);
1076
+ return (
1077
+ this.getPosition(slidSegment, refSeq, clientId, localSeq) +
1078
+ (forward ? 0 : slidSegment.cachedLength === 0 ? 0 : slidSegment.cachedLength - 1)
1079
+ );
1047
1080
  }
1048
-
1049
- return offset + pos;
1081
+ return this.getPosition(seg, refSeq, clientId, localSeq) + refPos.getOffset();
1050
1082
  }
1051
1083
  return DetachedReferencePosition;
1052
1084
  }
@@ -11,6 +11,7 @@ import { IMergeTreeGroupMsg, IMergeTreeOp, MergeTreeDeltaType } from "./ops.js";
11
11
  import { PropertySet } from "./properties.js";
12
12
 
13
13
  /**
14
+ * @legacy
14
15
  * @alpha
15
16
  */
16
17
  export type MergeTreeDeltaOperationType =
@@ -24,6 +25,7 @@ export type MergeTreeDeltaOperationType =
24
25
  * Maintenance events correspond to structural segment changes or acks of pending segments.
25
26
  *
26
27
  * Note: these values are assigned negative integers to avoid clashing with `MergeTreeDeltaType`.
28
+ * @legacy
27
29
  * @alpha
28
30
  */
29
31
  export const MergeTreeMaintenanceType = {
@@ -54,12 +56,14 @@ export const MergeTreeMaintenanceType = {
54
56
  ACKNOWLEDGED: -4,
55
57
  } as const;
56
58
  /**
59
+ * @legacy
57
60
  * @alpha
58
61
  */
59
62
  export type MergeTreeMaintenanceType =
60
63
  (typeof MergeTreeMaintenanceType)[keyof typeof MergeTreeMaintenanceType];
61
64
 
62
65
  /**
66
+ * @legacy
63
67
  * @alpha
64
68
  */
65
69
  export type MergeTreeDeltaOperationTypes =
@@ -67,6 +71,7 @@ export type MergeTreeDeltaOperationTypes =
67
71
  | MergeTreeMaintenanceType;
68
72
 
69
73
  /**
74
+ * @legacy
70
75
  * @alpha
71
76
  */
72
77
  export interface IMergeTreeDeltaCallbackArgs<
@@ -89,6 +94,7 @@ export interface IMergeTreeDeltaCallbackArgs<
89
94
  }
90
95
 
91
96
  /**
97
+ * @legacy
92
98
  * @alpha
93
99
  */
94
100
  export interface IMergeTreeSegmentDelta {
@@ -110,6 +116,7 @@ export interface IMergeTreeSegmentDelta {
110
116
  }
111
117
 
112
118
  /**
119
+ * @legacy
113
120
  * @alpha
114
121
  */
115
122
  export interface IMergeTreeDeltaOpArgs {
@@ -153,6 +160,7 @@ export type MergeTreeDeltaCallback = (
153
160
  ) => void;
154
161
 
155
162
  /**
163
+ * @legacy
156
164
  * @alpha
157
165
  */
158
166
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
@@ -32,6 +32,7 @@ import { PropertiesManager, PropertiesRollback } from "./segmentPropertiesManage
32
32
 
33
33
  /**
34
34
  * Common properties for a node in a merge tree.
35
+ * @legacy
35
36
  * @alpha
36
37
  */
37
38
  export interface IMergeNodeCommon {
@@ -55,6 +56,7 @@ export type IMergeNode = MergeBlock | ISegmentLeaf;
55
56
 
56
57
  /**
57
58
  * Contains removal information associated to an {@link ISegment}.
59
+ * @legacy
58
60
  * @alpha
59
61
  */
60
62
  export interface IRemovalInfo {
@@ -96,6 +98,7 @@ export function toRemovalInfo(
96
98
  * Note that merge-tree does not currently support moving and only supports
97
99
  * obliterate. The fields below include "move" in their names to avoid renaming
98
100
  * in the future, when moves _are_ supported.
101
+ * @legacy
99
102
  * @alpha
100
103
  */
101
104
  export interface IMoveInfo {
@@ -172,6 +175,7 @@ export function toMoveInfo(maybe: Partial<IMoveInfo> | undefined): IMoveInfo | u
172
175
  /**
173
176
  * A segment representing a portion of the merge tree.
174
177
  * Segments are leaf nodes of the merge tree and contain data.
178
+ * @legacy
175
179
  * @alpha
176
180
  */
177
181
  export interface ISegment extends IMergeNodeCommon, Partial<IRemovalInfo>, Partial<IMoveInfo> {
@@ -290,6 +294,7 @@ export interface IMarkerModifiedAction {
290
294
  }
291
295
 
292
296
  /**
297
+ * @legacy
293
298
  * @alpha
294
299
  */
295
300
  export interface ISegmentAction<TClientData> {
@@ -365,6 +370,7 @@ export interface SegmentActions<TClientData> {
365
370
 
366
371
  /**
367
372
  * @deprecated This functionality was not meant to be exported and will be removed in a future release
373
+ * @legacy
368
374
  * @alpha
369
375
  */
370
376
  export interface SegmentGroup {
@@ -375,6 +381,7 @@ export interface SegmentGroup {
375
381
  }
376
382
 
377
383
  /**
384
+ * @legacy
378
385
  * @alpha
379
386
  * @deprecated - unused and will be removed
380
387
  */
@@ -471,6 +478,7 @@ export function seqLTE(seq: number, minOrRefSeq: number) {
471
478
  }
472
479
 
473
480
  /**
481
+ * @legacy
474
482
  * @alpha
475
483
  */
476
484
  export abstract class BaseSegment implements ISegment {
@@ -697,6 +705,7 @@ export abstract class BaseSegment implements ISegment {
697
705
  *
698
706
  * @remarks In general, marker ids should be accessed using the inherent method
699
707
  * {@link Marker.getId}. Marker ids should not be updated after creation.
708
+ * @legacy
700
709
  * @alpha
701
710
  */
702
711
  export const reservedMarkerIdKey = "markerId";
@@ -707,6 +716,7 @@ export const reservedMarkerIdKey = "markerId";
707
716
  export const reservedMarkerSimpleTypeKey = "markerSimpleType";
708
717
 
709
718
  /**
719
+ * @legacy
710
720
  * @alpha
711
721
  */
712
722
  export interface IJSONMarkerSegment extends IJSONSegment {
@@ -722,6 +732,7 @@ export interface IJSONMarkerSegment extends IJSONSegment {
722
732
  * start of a paragraph to the end, assuming a paragraph is bound by markers at
723
733
  * the start and end.
724
734
  *
735
+ * @legacy
725
736
  * @alpha
726
737
  */
727
738
  export class Marker extends BaseSegment implements ReferencePosition, ISegment {
@@ -798,6 +809,7 @@ export class Marker extends BaseSegment implements ReferencePosition, ISegment {
798
809
 
799
810
  /**
800
811
  * @deprecated This functionality was not meant to be exported and will be removed in a future release
812
+ * @legacy
801
813
  * @alpha
802
814
  */
803
815
  export class CollaborationWindow {
@@ -9,11 +9,13 @@ import { ISegment } from "./mergeTreeNodes.js";
9
9
  import { SortedSegmentSet } from "./sortedSegmentSet.js";
10
10
 
11
11
  /**
12
+ * @legacy
12
13
  * @alpha
13
14
  */
14
15
  export type Trackable = ISegment | LocalReferencePosition;
15
16
 
16
17
  /**
18
+ * @legacy
17
19
  * @alpha
18
20
  */
19
21
  export interface ITrackingGroup {
@@ -25,6 +27,7 @@ export interface ITrackingGroup {
25
27
  }
26
28
 
27
29
  /**
30
+ * @legacy
28
31
  * @alpha
29
32
  */
30
33
  export class TrackingGroup implements ITrackingGroup {
@@ -104,6 +107,7 @@ export class UnorderedTrackingGroup implements ITrackingGroup {
104
107
 
105
108
  /**
106
109
  * A collection of {@link ITrackingGroup}.
110
+ * @legacy
107
111
  * @alpha
108
112
  */
109
113
  export class TrackingGroupCollection {
package/src/ops.ts CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  /**
7
7
  * Flags enum that dictates behavior of a {@link ReferencePosition}
8
+ * @legacy
8
9
  * @alpha
9
10
  */
10
11
  export enum ReferenceType {
@@ -48,6 +49,7 @@ export enum ReferenceType {
48
49
  }
49
50
 
50
51
  /**
52
+ * @legacy
51
53
  * @alpha
52
54
  */
53
55
  export interface IMarkerDef {
@@ -56,6 +58,7 @@ export interface IMarkerDef {
56
58
 
57
59
  // Note: Assigned positive integers to avoid clashing with MergeTreeMaintenanceType
58
60
  /**
61
+ * @legacy
59
62
  * @alpha
60
63
  */
61
64
  export const MergeTreeDeltaType = {
@@ -70,11 +73,13 @@ export const MergeTreeDeltaType = {
70
73
  } as const;
71
74
 
72
75
  /**
76
+ * @legacy
73
77
  * @alpha
74
78
  */
75
79
  export type MergeTreeDeltaType = (typeof MergeTreeDeltaType)[keyof typeof MergeTreeDeltaType];
76
80
 
77
81
  /**
82
+ * @legacy
78
83
  * @alpha
79
84
  */
80
85
  export interface IMergeTreeDelta {
@@ -86,6 +91,7 @@ export interface IMergeTreeDelta {
86
91
 
87
92
  /**
88
93
  * A position specified relative to a segment.
94
+ * @legacy
89
95
  * @alpha
90
96
  */
91
97
  export interface IRelativePosition {
@@ -106,6 +112,7 @@ export interface IRelativePosition {
106
112
  }
107
113
 
108
114
  /**
115
+ * @legacy
109
116
  * @alpha
110
117
  */
111
118
  export interface IMergeTreeInsertMsg extends IMergeTreeDelta {
@@ -118,6 +125,7 @@ export interface IMergeTreeInsertMsg extends IMergeTreeDelta {
118
125
  }
119
126
 
120
127
  /**
128
+ * @legacy
121
129
  * @alpha
122
130
  */
123
131
  export interface IMergeTreeRemoveMsg extends IMergeTreeDelta {
@@ -132,6 +140,7 @@ export interface IMergeTreeRemoveMsg extends IMergeTreeDelta {
132
140
  * @deprecated We no longer intend to support this functionality and it will
133
141
  * be removed in a future release. There is no replacement for this
134
142
  * functionality.
143
+ * @legacy
135
144
  * @alpha
136
145
  */
137
146
  export interface IMergeTreeObliterateMsg extends IMergeTreeDelta {
@@ -151,6 +160,7 @@ export interface IMergeTreeObliterateMsg extends IMergeTreeDelta {
151
160
  }
152
161
 
153
162
  /**
163
+ * @legacy
154
164
  * @alpha
155
165
  */
156
166
  export interface IMergeTreeAnnotateMsg extends IMergeTreeDelta {
@@ -167,6 +177,7 @@ export interface IMergeTreeAnnotateMsg extends IMergeTreeDelta {
167
177
  * release, as group ops are redundant with the native batching capabilities
168
178
  * of the runtime
169
179
  *
180
+ * @legacy
170
181
  * @alpha
171
182
  */
172
183
  export interface IMergeTreeGroupMsg extends IMergeTreeDelta {
@@ -175,6 +186,7 @@ export interface IMergeTreeGroupMsg extends IMergeTreeDelta {
175
186
  }
176
187
 
177
188
  /**
189
+ * @legacy
178
190
  * @alpha
179
191
  */
180
192
  export interface IJSONSegment {
@@ -182,6 +194,7 @@ export interface IJSONSegment {
182
194
  }
183
195
 
184
196
  /**
197
+ * @legacy
185
198
  * @alpha
186
199
  */
187
200
  export type IMergeTreeDeltaOp =
@@ -191,6 +204,7 @@ export type IMergeTreeDeltaOp =
191
204
  | IMergeTreeObliterateMsg;
192
205
 
193
206
  /**
207
+ * @legacy
194
208
  * @alpha
195
209
  */
196
210
  export type IMergeTreeOp = IMergeTreeDeltaOp | IMergeTreeGroupMsg;
@@ -0,0 +1,142 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { UnassignedSequenceNumber } from "./constants.js";
7
+ import { type MergeTree } from "./mergeTree.js";
8
+ import { LeafAction, backwardExcursion, forwardExcursion } from "./mergeTreeNodeWalk.js";
9
+ import { seqLTE, type ISegment } from "./mergeTreeNodes.js";
10
+
11
+ /**
12
+ * Provides a view of a MergeTree from the perspective of a specific client at a specific sequence number.
13
+ */
14
+ export interface Perspective {
15
+ nextSegment(segment: ISegment, forward?: boolean): ISegment;
16
+ previousSegment(segment: ISegment): ISegment;
17
+ }
18
+
19
+ /**
20
+ * Represents a point in time inside the collaboration window.
21
+ */
22
+ export interface SeqTime {
23
+ refSeq: number;
24
+ localSeq?: number;
25
+ }
26
+
27
+ /**
28
+ * Implementation of {@link Perspective}.
29
+ * See {@link Client.createPerspective}.
30
+ */
31
+ export class PerspectiveImpl implements Perspective {
32
+ /**
33
+ * @param _mergeTree - The {@link MergeTree} to view.
34
+ * @param _seqTime - The latest sequence number and local sequence number to consider.
35
+ */
36
+ public constructor(
37
+ private readonly _mergeTree: MergeTree,
38
+ private readonly _seqTime: SeqTime,
39
+ ) {}
40
+
41
+ /**
42
+ * Returns the immediately adjacent segment in the specified direction from this perspective.
43
+ * There may actually be multiple segments between the given segment and the returned segment,
44
+ * but they were either inserted after this perspective, or have been removed or moved before this perspective.
45
+ *
46
+ * @param segment - The segment to start from.
47
+ * @param forward - The direction to search.
48
+ * @returns the next segment in the specified direction, or the start or end of the tree if there is no next segment.
49
+ */
50
+ public nextSegment(segment: ISegment, forward: boolean = true): ISegment {
51
+ let next: ISegment | undefined;
52
+ const action = (seg: ISegment) => {
53
+ if (isSegmentPresent(seg, this._seqTime)) {
54
+ next = seg;
55
+ return LeafAction.Exit;
56
+ }
57
+ };
58
+ (forward ? forwardExcursion : backwardExcursion)(segment, action);
59
+ return next ?? (forward ? this._mergeTree.endOfTree : this._mergeTree.startOfTree);
60
+ }
61
+
62
+ /**
63
+ * @param segment - The segment to start from.
64
+ * @returns the previous segment, or the start of the tree if there is no previous segment.
65
+ * @remarks This is a convenient equivalent to calling `nextSegment(segment, false)`.
66
+ */
67
+ public previousSegment(segment: ISegment): ISegment {
68
+ return this.nextSegment(segment, false);
69
+ }
70
+ }
71
+
72
+ /**
73
+ * @param seg - The segment to check.
74
+ * @param seq - The latest sequence number to consider.
75
+ * @param localSeq - The latest local sequence number to consider.
76
+ * @returns true iff this segment was removed in the given perspective.
77
+ */
78
+ export function wasRemovedBefore(seg: ISegment, { refSeq, localSeq }: SeqTime): boolean {
79
+ if (
80
+ seg.removedSeq === UnassignedSequenceNumber &&
81
+ localSeq !== undefined &&
82
+ seg.localRemovedSeq !== undefined
83
+ ) {
84
+ return seg.localRemovedSeq <= localSeq;
85
+ }
86
+ return seg.removedSeq !== undefined && seqLTE(seg.removedSeq, refSeq);
87
+ }
88
+
89
+ /**
90
+ * @param seg - The segment to check.
91
+ * @param refSeq - The latest sequence number to consider.
92
+ * @param localSeq - The latest local sequence number to consider.
93
+ * @returns true iff this segment was moved (aka obliterated) in the given perspective.
94
+ */
95
+ export function wasMovedBefore(seg: ISegment, { refSeq, localSeq }: SeqTime): boolean {
96
+ if (
97
+ seg.movedSeq === UnassignedSequenceNumber &&
98
+ localSeq !== undefined &&
99
+ seg.localMovedSeq !== undefined
100
+ ) {
101
+ return seg.localMovedSeq <= localSeq;
102
+ }
103
+ return seg.movedSeq !== undefined && seqLTE(seg.movedSeq, refSeq);
104
+ }
105
+
106
+ /**
107
+ * See {@link wasRemovedBefore} and {@link wasMovedBefore}.
108
+ */
109
+ export function wasRemovedOrMovedBefore(seg: ISegment, seqTime: SeqTime): boolean {
110
+ return wasRemovedBefore(seg, seqTime) || wasMovedBefore(seg, seqTime);
111
+ }
112
+
113
+ /**
114
+ *
115
+ * @param seg - The segment to check.
116
+ * @param seqTime - The latest sequence number and local sequence number to consider.
117
+ * @returns true iff this segment was inserted before the given perspective,
118
+ * and it was not removed or moved in the given perspective.
119
+ */
120
+ export function isSegmentPresent(seg: ISegment, seqTime: SeqTime): boolean {
121
+ const { refSeq, localSeq } = seqTime;
122
+ // If seg.seq is undefined, then this segment has existed since minSeq.
123
+ // It may have been moved or removed since.
124
+ if (seg.seq !== undefined) {
125
+ if (seg.seq !== UnassignedSequenceNumber) {
126
+ if (!seqLTE(seg.seq, refSeq)) {
127
+ return false;
128
+ }
129
+ } else if (seg.localSeq !== undefined) {
130
+ // seg.seq === UnassignedSequenceNumber
131
+ // If the current perspective does not include local sequence numbers,
132
+ // then this segment does not exist yet.
133
+ if (localSeq === undefined || seg.localSeq > localSeq) {
134
+ return false;
135
+ }
136
+ }
137
+ }
138
+ if (wasRemovedOrMovedBefore(seg, seqTime)) {
139
+ return false;
140
+ }
141
+ return true;
142
+ }
package/src/properties.ts CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  /**
7
7
  * Any mapping from a string to values of type `T`
8
+ * @legacy
8
9
  * @alpha
9
10
  */
10
11
  export interface MapLike<T> {
@@ -19,6 +20,7 @@ export interface MapLike<T> {
19
20
  * @privateRemarks PropertySet is typed using `any` because when you include
20
21
  * custom methods such as toJSON(), JSON.stringify accepts most types other than
21
22
  * functions
23
+ * @legacy
22
24
  * @alpha
23
25
  */
24
26
  export type PropertySet = MapLike<any>;
@@ -30,6 +30,7 @@ export function refTypeIncludesFlag(
30
30
  }
31
31
 
32
32
  /**
33
+ * @legacy
33
34
  * @alpha
34
35
  */
35
36
  export const refGetTileLabels = (refPos: ReferencePosition): string[] | undefined =>
@@ -38,6 +39,7 @@ export const refGetTileLabels = (refPos: ReferencePosition): string[] | undefine
38
39
  : undefined;
39
40
 
40
41
  /**
42
+ * @legacy
41
43
  * @alpha
42
44
  */
43
45
  export function refHasTileLabel(refPos: ReferencePosition, label: string): boolean {
@@ -56,6 +58,7 @@ export function refHasTileLabels(refPos: ReferencePosition): boolean {
56
58
  * Represents a reference to a place within a merge tree. This place conceptually remains stable over time
57
59
  * by referring to a particular segment and offset within that segment.
58
60
  * Thus, this reference's character position changes as the tree is edited.
61
+ * @legacy
59
62
  * @alpha
60
63
  */
61
64
  export interface ReferencePosition {
@@ -19,6 +19,7 @@ import { PropertySet, matchProperties } from "./properties.js";
19
19
  import { DetachedReferencePosition } from "./referencePositions.js";
20
20
 
21
21
  /**
22
+ * @legacy
22
23
  * @alpha
23
24
  */
24
25
  export type MergeTreeDeltaRevertible =
@@ -61,6 +62,7 @@ interface RemoveSegmentRefProperties {
61
62
  }
62
63
 
63
64
  /**
65
+ * @legacy
64
66
  * @alpha
65
67
  */
66
68
  export interface MergeTreeRevertibleDriver {
@@ -189,6 +191,7 @@ function appendLocalAnnotateToRevertibles(
189
191
  }
190
192
 
191
193
  /**
194
+ * @legacy
192
195
  * @alpha
193
196
  */
194
197
  export function appendToMergeTreeDeltaRevertibles(
@@ -219,6 +222,7 @@ export function appendToMergeTreeDeltaRevertibles(
219
222
  }
220
223
 
221
224
  /**
225
+ * @legacy
222
226
  * @alpha
223
227
  */
224
228
  export function discardMergeTreeDeltaRevertible(revertibles: MergeTreeDeltaRevertible[]) {
@@ -381,6 +385,7 @@ function getPosition(mergeTreeWithRevert: MergeTreeWithRevert, segment: ISegment
381
385
  }
382
386
 
383
387
  /**
388
+ * @legacy
384
389
  * @alpha
385
390
  */
386
391
  export function revertMergeTreeDeltaRevertibles(
@@ -8,6 +8,7 @@ import { DoublyLinkedList, walkList } from "./collections/index.js";
8
8
  import { ISegment, SegmentGroup } from "./mergeTreeNodes.js";
9
9
 
10
10
  /**
11
+ * @legacy
11
12
  * @alpha
12
13
  */
13
14
  export class SegmentGroupCollection {
@@ -13,6 +13,7 @@ import { IMergeTreeAnnotateMsg } from "./ops.js";
13
13
  import { MapLike, PropertySet, createMap } from "./properties.js";
14
14
 
15
15
  /**
16
+ * @legacy
16
17
  * @alpha
17
18
  */
18
19
  export enum PropertiesRollback {
@@ -24,6 +25,7 @@ export enum PropertiesRollback {
24
25
  }
25
26
 
26
27
  /**
28
+ * @legacy
27
29
  * @alpha
28
30
  */
29
31
  export class PropertiesManager {
@@ -280,8 +280,6 @@ export class SnapshotLoader {
280
280
  }
281
281
 
282
282
  private extractAttribution(segments: ISegment[], chunk: MergeTreeChunkV1): void {
283
- this.mergeTree.options ??= {};
284
- this.mergeTree.options.attribution ??= {};
285
283
  if (chunk.attribution) {
286
284
  const { attributionPolicy } = this.mergeTree;
287
285
  if (attributionPolicy === undefined) {
@@ -21,6 +21,7 @@ import { PropertySet } from "./properties.js";
21
21
  export const TextSegmentGranularity = 256;
22
22
 
23
23
  /**
24
+ * @legacy
24
25
  * @alpha
25
26
  */
26
27
  export interface IJSONTextSegment extends IJSONSegment {
@@ -28,6 +29,7 @@ export interface IJSONTextSegment extends IJSONSegment {
28
29
  }
29
30
 
30
31
  /**
32
+ * @legacy
31
33
  * @alpha
32
34
  */
33
35
  export class TextSegment extends BaseSegment {
@@ -106,6 +108,7 @@ export class TextSegment extends BaseSegment {
106
108
 
107
109
  /**
108
110
  * @deprecated This functionality was not meant to be exported and will be removed in a future release
111
+ * @legacy
109
112
  * @alpha
110
113
  */
111
114
  export interface IMergeTreeTextHelper {