@fluidframework/merge-tree 0.59.4001 → 1.1.0-75972

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 (80) hide show
  1. package/.eslintrc.js +1 -1
  2. package/README.md +1 -1
  3. package/REFERENCEPOSITIONS.md +199 -0
  4. package/dist/client.d.ts +30 -4
  5. package/dist/client.d.ts.map +1 -1
  6. package/dist/client.js +89 -47
  7. package/dist/client.js.map +1 -1
  8. package/dist/collections.d.ts +5 -4
  9. package/dist/collections.d.ts.map +1 -1
  10. package/dist/collections.js +17 -18
  11. package/dist/collections.js.map +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +4 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/localReference.d.ts +11 -3
  17. package/dist/localReference.d.ts.map +1 -1
  18. package/dist/localReference.js +25 -8
  19. package/dist/localReference.js.map +1 -1
  20. package/dist/mergeTree.d.ts +23 -3
  21. package/dist/mergeTree.d.ts.map +1 -1
  22. package/dist/mergeTree.js +136 -48
  23. package/dist/mergeTree.js.map +1 -1
  24. package/dist/mergeTreeDeltaCallback.d.ts +8 -10
  25. package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
  26. package/dist/mergeTreeDeltaCallback.js +6 -10
  27. package/dist/mergeTreeDeltaCallback.js.map +1 -1
  28. package/dist/opBuilder.js +6 -5
  29. package/dist/opBuilder.js.map +1 -1
  30. package/dist/ops.d.ts +12 -10
  31. package/dist/ops.d.ts.map +1 -1
  32. package/dist/ops.js +7 -7
  33. package/dist/ops.js.map +1 -1
  34. package/dist/referencePositions.d.ts +1 -1
  35. package/dist/referencePositions.d.ts.map +1 -1
  36. package/dist/referencePositions.js +3 -2
  37. package/dist/referencePositions.js.map +1 -1
  38. package/lib/client.d.ts +30 -4
  39. package/lib/client.d.ts.map +1 -1
  40. package/lib/client.js +89 -47
  41. package/lib/client.js.map +1 -1
  42. package/lib/collections.d.ts +5 -4
  43. package/lib/collections.d.ts.map +1 -1
  44. package/lib/collections.js +17 -18
  45. package/lib/collections.js.map +1 -1
  46. package/lib/index.d.ts +1 -1
  47. package/lib/index.d.ts.map +1 -1
  48. package/lib/index.js +1 -1
  49. package/lib/index.js.map +1 -1
  50. package/lib/localReference.d.ts +11 -3
  51. package/lib/localReference.d.ts.map +1 -1
  52. package/lib/localReference.js +23 -7
  53. package/lib/localReference.js.map +1 -1
  54. package/lib/mergeTree.d.ts +23 -3
  55. package/lib/mergeTree.d.ts.map +1 -1
  56. package/lib/mergeTree.js +137 -49
  57. package/lib/mergeTree.js.map +1 -1
  58. package/lib/mergeTreeDeltaCallback.d.ts +8 -10
  59. package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
  60. package/lib/mergeTreeDeltaCallback.js +6 -10
  61. package/lib/mergeTreeDeltaCallback.js.map +1 -1
  62. package/lib/opBuilder.js +6 -5
  63. package/lib/opBuilder.js.map +1 -1
  64. package/lib/ops.d.ts +12 -10
  65. package/lib/ops.d.ts.map +1 -1
  66. package/lib/ops.js +7 -7
  67. package/lib/ops.js.map +1 -1
  68. package/lib/referencePositions.d.ts +1 -1
  69. package/lib/referencePositions.d.ts.map +1 -1
  70. package/lib/referencePositions.js +3 -2
  71. package/lib/referencePositions.js.map +1 -1
  72. package/package.json +17 -94
  73. package/src/client.ts +87 -27
  74. package/src/collections.ts +5 -4
  75. package/src/index.ts +1 -1
  76. package/src/localReference.ts +33 -8
  77. package/src/mergeTree.ts +136 -43
  78. package/src/mergeTreeDeltaCallback.ts +8 -10
  79. package/src/ops.ts +13 -10
  80. package/src/referencePositions.ts +3 -2
package/.eslintrc.js CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  module.exports = {
7
7
  "extends": [
8
- "@fluidframework/eslint-config-fluid"
8
+ require.resolve("@fluidframework/eslint-config-fluid")
9
9
  ],
10
10
  "parserOptions": {
11
11
  "project": ["./tsconfig.json", "./src/test/tsconfig.json"]
package/README.md CHANGED
@@ -89,7 +89,7 @@ A segment was inserted and/or removed on the remote client at the time client se
89
89
 
90
90
  * The referenced sequence number is greater than or equal the server-assigned sequence number of the operation
91
91
  that inserted/removed the segment.
92
- * The client sent the operation that resulted in insertion/removal. (In which case, the client hadn't yet recieved
92
+ * The client sent the operation that resulted in insertion/removal. (In which case, the client hadn't yet received
93
93
  their sequenced op from the server but was aware of the insertion/removal because the client produced it locally.)
94
94
 
95
95
  If both above conditions are false, then the insertion/removal happened "after" the remote operation, and
@@ -0,0 +1,199 @@
1
+ # ReferencePosition Documentation
2
+
3
+ ReferencePositions are used to indicates a MergeTree position which is stable as operations are performed. There are two
4
+ types:
5
+
6
+ 1. LocalReferences refer to a segment and offset within that segment
7
+ 2. Markers are actual segments in the Merge Tree
8
+
9
+ The function `Client.localReferencePositionToPosition` returns the numerical position of a reference in the client's
10
+ current view.
11
+
12
+ ## LocalReference behavior on Remove
13
+
14
+ By default, LocalReferences become detached when the segment they reference is removed.
15
+ The ReferenceTypes SlideOnRemove, StayOnRemove, and Transient change this behavior.
16
+ They are only valid for LocalReferences.
17
+ They are exclusive - a reference may be at most one of these types.
18
+
19
+ ### SlideOnRemove
20
+
21
+ The reference will slide to the next farthest segment when the segment is removed and the remove has been acknowledged.
22
+ Sliding will look for the next valid segment.
23
+ A valid segment is one whose creation has been acknowledged and either hasn't been removed
24
+ or the remove is pending (not acknowledged).
25
+ If a farther segment is found, then the LocalReference will be changed to refer to that segment and have offset 0.
26
+ In the event that the slide is happening on the acknowledgement of a remove, the slide to a farther segment will not
27
+ change the numerical position of the reference.
28
+ If there is no there is no valid segment farther in the tree, then the slide will place the reference on the last valid segment.
29
+ The offset will be set to the last position in that segment.
30
+ In the event that the slide is happening on the acknowledgement of a remove, the reference would have been on the removed
31
+ segment. This slide from the removed segment to a nearer segment does change the numerical position of the reference.
32
+ If there is no valid position (all segments removed and acknowledged) then the reference is detached.
33
+
34
+ ### StayOnRemove
35
+
36
+ The reference will stay on removed segments.
37
+ This behavior is only defined until the removed segment is cleaned up by Zamboni.
38
+ This is intended to be used only while collaborating (see below) while waiting for an acknowledgement.
39
+
40
+ ### Transient
41
+
42
+ The reference is not tracked by the MergeTree.
43
+ It will continue to reference removed segments.
44
+ This behavior is only defined until the removed segment is cleaned up by Zamboni.
45
+ This is intended to be used to create transient references which may be compared with other references.
46
+
47
+ ### Detached LocalReferences
48
+
49
+ A detached LocalReference does not reference a segment in the MergeTree.
50
+ It's position is defined to be `LocalReference.DetachedPosition` (-1).
51
+
52
+ ### LocalReferences on Removed Segments
53
+
54
+ LocalReferences may reference removed segments:
55
+
56
+ * SlideOnRemove references may reference a removed segment which is pending (not acknoweldged)
57
+ * StayOnRemove references may reference removed segments
58
+ * Transient references may reference removed segments
59
+
60
+ The numerical position of a reference which is on a removed segment will be one more than the previous (nearer) segment.
61
+ If there is a farther segment that is not removed, this will be the same as the position of the start of that segment.
62
+ If there is no farther segment, then the reference position will be the length of the tree (one more than the last valid
63
+ position in the tree).
64
+
65
+ ## Eventually Consistent References
66
+
67
+ Markers are segments in the MergeTree and are eventually consistent.
68
+ LocalReferences may be used as part of an eventually consistent feature.
69
+ For example, SharedIntervals are built using LocalReferences.
70
+
71
+ ### Implementing Eventually Consistent LocalReferences
72
+
73
+ To implement an operation which creates LocalReferences which will be have an eventually consistent position:
74
+
75
+ 1. Locally create the reference as StayOnRemove
76
+ 2. Send the reference numerical position in an op
77
+ 3. On acknowledgement of the local create:
78
+ 1. set the `refType` of the reference to include `SlideOnRemove`
79
+ 2. call `Client.getSlideToSegment` with the references current segment and offset to get the proper new location
80
+ 3. Delete the old reference and create a new one with the returned values
81
+ 4. Remote clients, on receiving the op, call `Client.getContainingSegment` followed by `Client.getSlideToSegment`
82
+ on the result. Call `Client.createLocalReferencePosition` with the result to create a `SlideOnRemove` reference.
83
+ 5. If there is a dependency on the comparison of reference positions (such as the index in IntervalCollections)
84
+ must listen to the `beforeSlide` and `afterSlide` events on `IReferencePositionEvents`. When slide occurs the
85
+ relative position of references may have changed.
86
+
87
+ ### Implementation Notes
88
+
89
+ This is the state diagram for the implementation of Eventually Consistent References.
90
+
91
+ ```mermaid
92
+ flowchart LR
93
+ subgraph StayOnRemove
94
+ localCreate[Local Create Ref]
95
+ pendingRef(("Ref:StayOnRemove\nSegment:Pending|Normal"))
96
+ pendingRefPendingRemove((Ref:StayOnRemove\nSegment:Pending Remove))
97
+ pendingRefRemoved((Ref:StayOnRemove\nSegment:Removed))
98
+ localCreate-->pendingRef
99
+ pendingRef--local remove-->pendingRefPendingRemove
100
+ pendingRefPendingRemove--remote remove-->pendingRefRemoved
101
+ pendingRef--remote remove-->pendingRefRemoved
102
+ end
103
+
104
+ subgraph SlideOnRemove
105
+ remoteCreate[Remote Create Ref]
106
+ remoteChoice{Segment Removed?}
107
+ ref((Ref:SlideOnRemove\nSegment:Normal))
108
+ refPendingRemove((Ref:SlideOnRemove\nSegment:Pending Remove))
109
+
110
+ remoteCreate-->remoteChoice
111
+ remoteChoice--no-->ref
112
+ remoteChoice--locally-->refPendingRemove
113
+ ref--local remove-->refPendingRemove
114
+ end
115
+
116
+ slide{Slide To}
117
+ detached((Ref:Detached))
118
+
119
+ pendingRef--create ack-->ref
120
+ pendingRefPendingRemove--create ack-->refPendingRemove
121
+ pendingRefRemoved--create ack-->slide
122
+ remoteChoice--yes-->slide
123
+ ref--remote remove-->slide
124
+ refPendingRemove--remove ack-->slide
125
+ refPendingRemove--remote remove-->slide
126
+ slide--segment-->ref
127
+ slide--locally removed segment-->refPendingRemove
128
+ slide--no segment-->detached
129
+ ```
130
+
131
+ This algorithm works because it ensures that slid reference slide to the same segment.
132
+ The slide only happens when both the creation of the reference and removal of the segment have been acknowledged.
133
+ When sliding we do not consider any local (unacknowledged) ops.
134
+
135
+ Keeping references on removed segments until they can be slid works well in most cases because of these properties:
136
+
137
+ 1. Interval positions on removed segments appear as if they were on the following position in the string.
138
+ If the removed segment is between positions 5 and 6, the interval positions on the removed segment appear to be at
139
+ position 6. This matches where they will eventually slide, so slide will not cause a change in position as long as
140
+ segments are not slid over and it is not necessary to slide to the near end of the string.
141
+ 2. Text inserted at the same location as the removed segment is inserted before the removed segment.
142
+ So if the removed segment is between 0 and 1 (“A[removed]B”), insertText(1, “X”) inserts before the removed segment
143
+ (“AX[removed]B”). This makes it hard to end up with local only segments to be slid over, which will mean it is rare
144
+ that slide visibly changes the interval position. It can still happen if there is a conflicting remove, but that is
145
+ much less likely.
146
+
147
+ #### Conflict Scenarios
148
+
149
+ Considering Create Interval / Remove Range conflicts, here are the scenarios
150
+ (before indicates the relative sequence order):
151
+
152
+ 1. Local create before local remove. Interval position needs to slide on ack of the local remove.
153
+ 2. Remote create before remote remove. Slide on receiving the remove.
154
+ 3. Local remove before local create. This is impossible – once the segment is removed locally an
155
+ interval position can’t be created on it.
156
+ 4. Remote remove before remote create. (Possible if ops are from different remote clients).
157
+ Slide on receiving the remote create.
158
+ 5. Remote create before local remove. Slide on the ack of the local remove.
159
+ 6. Local create before remote remove. Slide on receiving the remove.
160
+ 7. Local remove before remote create. Slide on receiving the create.
161
+ 8. Remote remove before local create. Slide on receiving the ack of the create.
162
+
163
+ ### Why Eventually Consistent References Can Not Have Stable Order
164
+
165
+ In an ideal system reference positions would have stable order. Specifically:
166
+
167
+ 1. If in any client state the position of a reference is less than the position of a specific item in the sequence,
168
+ then the position of that reference would always be less than or equal to the position of that item.
169
+ 2. If in any client state the position of reference A is less than the position of reference B,
170
+ then the position of reference A would always be less than or equal to the position of reference B.
171
+
172
+ Neither of these properties is true for SlideOnRemove references. This is a result of them sliding over local
173
+ only segments. This could change the relative positions of the sliding reference at items that are slide over,
174
+ as well as any references on those items. Note that these properties do hold for items and references
175
+ once the creation has been acknowledged (sequenced by the server).
176
+
177
+ Supporting stable order is not possible in the current system because:
178
+
179
+ 1. Removing a range may cause an multiple references that had been at different positions to all be at the same
180
+ position.
181
+ 2. To preserve stable ordering, an insert that conflicts with that remove would need to be after some of those
182
+ references and before others.
183
+ 3. Insertion position is specified as a numerical offset in the sequence, so can't specify where in the set
184
+ of references at a position to be inserted. (Technically there is enough information to do this within the
185
+ collab window. But that information is lost if reconnect/resubmit is required.)
186
+
187
+ Therefore implementing eventually consistent references with stable order would require adding additional
188
+ information to insert ops.
189
+
190
+ ## Tests
191
+
192
+ * `packages\dds\merge-tree\src\test\client.localReference.spec.ts`
193
+ unit tests for LocalReferences
194
+ * `packages\dds\sequence\src\test\intervalCollection.spec.ts`
195
+ test LocalReferences as used in interval collections (including eventual consistency)
196
+ * `packages\test\test-end-to-end-tests\src\test\sharedInterval.spec.ts`
197
+ end-to-end tests using LocalReferences for interval collections.
198
+ These tests have only been minimally updated to reflect this implementation,
199
+ so they do not comprehensively test LocalReferences.
package/dist/client.d.ts CHANGED
@@ -8,7 +8,7 @@ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions"
8
8
  import { IFluidDataStoreRuntime, IChannelStorageService } from "@fluidframework/datastore-definitions";
9
9
  import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
10
10
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
11
- import { LocalReference } from "./localReference";
11
+ import { LocalReference, LocalReferencePosition } from "./localReference";
12
12
  import { CollaborationWindow, ISegment, ISegmentAction, Marker, MergeTree, SegmentGroup } from "./mergeTree";
13
13
  import { MergeTreeDeltaCallback } from "./mergeTreeDeltaCallback";
14
14
  import { ICombiningOp, IJSONSegment, IMergeTreeAnnotateMsg, IMergeTreeDeltaOp, IMergeTreeGroupMsg, IMergeTreeInsertMsg, IMergeTreeRemoveMsg, IMergeTreeOp, IRelativePosition, ReferenceType } from "./ops";
@@ -109,9 +109,9 @@ export declare class Client {
109
109
  /**
110
110
  * @deprecated - use removeReferencePosition instead
111
111
  */
112
- removeLocalReference(lref: LocalReference): ReferencePosition | undefined;
113
- createLocalReferencePosition(segment: ISegment, offset: number, refType: ReferenceType, properties: PropertySet | undefined): ReferencePosition;
114
- removeLocalReferencePosition(lref: ReferencePosition): ReferencePosition | undefined;
112
+ removeLocalReference(lref: LocalReference): LocalReferencePosition | undefined;
113
+ createLocalReferencePosition(segment: ISegment, offset: number | undefined, refType: ReferenceType, properties: PropertySet | undefined): LocalReferencePosition;
114
+ removeLocalReferencePosition(lref: LocalReferencePosition): LocalReferencePosition | undefined;
115
115
  localReferencePositionToPosition(lref: ReferencePosition): number;
116
116
  /**
117
117
  * Given a position specified relative to a marker id, lookup the marker
@@ -152,6 +152,11 @@ export declare class Client {
152
152
  * @param clientArgs - The client args for the op
153
153
  */
154
154
  private getValidOpRange;
155
+ /**
156
+ * Gets the client args from the op if remote, otherwise uses the local clients info
157
+ * @param sequencedMessage - The sequencedMessage to get the client sequence args for
158
+ */
159
+ private getClientSequenceArgsForMessage;
155
160
  /**
156
161
  * Gets the client args from the op if remote, otherwise uses the local clients info
157
162
  * @param opArgs - The op arg to get the client sequence args for
@@ -173,6 +178,15 @@ export declare class Client {
173
178
  * @param localSeq - The localSeq to find the position of the segment at
174
179
  */
175
180
  protected findReconnectionPosition(segment: ISegment, localSeq: number): number;
181
+ /**
182
+ * Rebases a (local) position from the perspective `{ seq: seqNumberFrom, localSeq }` to the perspective
183
+ * of the current sequence number. This is desirable when rebasing operations for reconnection.
184
+ *
185
+ * If the position refers to a segment/offset that was removed by some operation between `seqNumberFrom` and
186
+ * the current sequence number, the returned position will align with the position of a reference given
187
+ * `SlideOnRemove` semantics.
188
+ */
189
+ rebasePosition(pos: number, seqNumberFrom: number, localSeq: number): number;
176
190
  private resetPendingDeltaToOps;
177
191
  private applyRemoteOp;
178
192
  applyStashedOp(op: IMergeTreeDeltaOp): SegmentGroup;
@@ -210,6 +224,18 @@ export declare class Client {
210
224
  segment: T | undefined;
211
225
  offset: number | undefined;
212
226
  };
227
+ /**
228
+ * Returns the position to slide a reference to if a slide is required.
229
+ * @param segoff - The segment and offset to slide from
230
+ * @returns - segment and offset to slide the reference to
231
+ */
232
+ getSlideToSegment(segoff: {
233
+ segment: ISegment | undefined;
234
+ offset: number | undefined;
235
+ }): {
236
+ segment: ISegment | undefined;
237
+ offset: number | undefined;
238
+ };
213
239
  getPropertiesAtPosition(pos: number): PropertySet | undefined;
214
240
  getRangeExtentsOfPosition(pos: number): {
215
241
  posStart: number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -13,11 +13,11 @@ const constants_1 = require("./constants");
13
13
  const localReference_1 = require("./localReference");
14
14
  const mergeTree_1 = require("./mergeTree");
15
15
  const opBuilder_1 = require("./opBuilder");
16
+ const ops_1 = require("./ops");
16
17
  const snapshotlegacy_1 = require("./snapshotlegacy");
17
18
  const snapshotLoader_1 = require("./snapshotLoader");
18
19
  const textSegment_1 = require("./textSegment");
19
20
  const snapshotV1_1 = require("./snapshotV1");
20
- const referencePositions_1 = require("./referencePositions");
21
21
  function elapsedMicroseconds(trace) {
22
22
  return trace.trace().duration * 1000;
23
23
  }
@@ -224,11 +224,7 @@ class Client {
224
224
  return this.mergeTree.removeLocalReferencePosition(lref);
225
225
  }
226
226
  localReferencePositionToPosition(lref) {
227
- const segment = lref.getSegment();
228
- if (segment === undefined) {
229
- return referencePositions_1.DetachedReferencePosition;
230
- }
231
- return this.getPosition(segment) + lref.getOffset();
227
+ return this.mergeTree.referencePositionToLocalPosition(lref);
232
228
  }
233
229
  /**
234
230
  * Given a position specified relative to a marker id, lookup the marker
@@ -247,7 +243,7 @@ class Client {
247
243
  * @returns True if the remove was applied. False if it could not be.
248
244
  */
249
245
  applyRemoveRangeOp(opArgs) {
250
- (0, common_utils_1.assert)(opArgs.op.type === 1 /* REMOVE */, 0x02d /* "Unexpected op type on range remove!" */);
246
+ (0, common_utils_1.assert)(opArgs.op.type === ops_1.MergeTreeDeltaType.REMOVE, 0x02d /* "Unexpected op type on range remove!" */);
251
247
  const op = opArgs.op;
252
248
  const clientArgs = this.getClientSequenceArgs(opArgs);
253
249
  const range = this.getValidOpRange(op, clientArgs);
@@ -268,7 +264,7 @@ class Client {
268
264
  * @returns True if the annotate was applied. False if it could not be.
269
265
  */
270
266
  applyAnnotateRangeOp(opArgs) {
271
- (0, common_utils_1.assert)(opArgs.op.type === 2 /* ANNOTATE */, 0x02e /* "Unexpected op type on range annotate!" */);
267
+ (0, common_utils_1.assert)(opArgs.op.type === ops_1.MergeTreeDeltaType.ANNOTATE, 0x02e /* "Unexpected op type on range annotate!" */);
272
268
  const op = opArgs.op;
273
269
  const clientArgs = this.getClientSequenceArgs(opArgs);
274
270
  const range = this.getValidOpRange(op, clientArgs);
@@ -289,7 +285,7 @@ class Client {
289
285
  * @returns True if the insert was applied. False if it could not be.
290
286
  */
291
287
  applyInsertOp(opArgs) {
292
- (0, common_utils_1.assert)(opArgs.op.type === 0 /* INSERT */, 0x02f /* "Unexpected op type on range insert!" */);
288
+ (0, common_utils_1.assert)(opArgs.op.type === ops_1.MergeTreeDeltaType.INSERT, 0x02f /* "Unexpected op type on range insert!" */);
293
289
  const op = opArgs.op;
294
290
  const clientArgs = this.getClientSequenceArgs(opArgs);
295
291
  const range = this.getValidOpRange(op, clientArgs);
@@ -358,12 +354,12 @@ class Client {
358
354
  if (start === undefined
359
355
  || start < 0
360
356
  || start > length
361
- || start === length && op.type !== 0 /* INSERT */) {
357
+ || start === length && op.type !== ops_1.MergeTreeDeltaType.INSERT) {
362
358
  invalidPositions.push("start");
363
359
  }
364
360
  // Validate end if not insert, or insert has end
365
361
  //
366
- if (op.type !== 0 /* INSERT */ || end !== undefined) {
362
+ if (op.type !== ops_1.MergeTreeDeltaType.INSERT || end !== undefined) {
367
363
  if (end === undefined || end <= start) {
368
364
  invalidPositions.push("end");
369
365
  }
@@ -389,13 +385,13 @@ class Client {
389
385
  }
390
386
  /**
391
387
  * Gets the client args from the op if remote, otherwise uses the local clients info
392
- * @param opArgs - The op arg to get the client sequence args for
388
+ * @param sequencedMessage - The sequencedMessage to get the client sequence args for
393
389
  */
394
- getClientSequenceArgs(opArgs) {
390
+ getClientSequenceArgsForMessage(sequencedMessage) {
395
391
  // If there this no sequenced message, then the op is local
396
392
  // and unacked, so use this clients sequenced args
397
393
  //
398
- if (!opArgs.sequencedMessage) {
394
+ if (!sequencedMessage) {
399
395
  const segWindow = this.getCollabWindow();
400
396
  return {
401
397
  clientId: segWindow.clientId,
@@ -405,12 +401,19 @@ class Client {
405
401
  }
406
402
  else {
407
403
  return {
408
- clientId: this.getShortClientId(opArgs.sequencedMessage.clientId),
409
- referenceSequenceNumber: opArgs.sequencedMessage.referenceSequenceNumber,
410
- sequenceNumber: opArgs.sequencedMessage.sequenceNumber,
404
+ clientId: this.getOrAddShortClientId(sequencedMessage.clientId),
405
+ referenceSequenceNumber: sequencedMessage.referenceSequenceNumber,
406
+ sequenceNumber: sequencedMessage.sequenceNumber,
411
407
  };
412
408
  }
413
409
  }
410
+ /**
411
+ * Gets the client args from the op if remote, otherwise uses the local clients info
412
+ * @param opArgs - The op arg to get the client sequence args for
413
+ */
414
+ getClientSequenceArgs(opArgs) {
415
+ return this.getClientSequenceArgsForMessage(opArgs.sequencedMessage);
416
+ }
414
417
  ackPendingSegment(opArgs) {
415
418
  const ackOp = (deltaOpArgs) => {
416
419
  let trace;
@@ -418,7 +421,7 @@ class Client {
418
421
  trace = common_utils_1.Trace.start();
419
422
  }
420
423
  this.mergeTree.ackPendingSegment(deltaOpArgs);
421
- if (deltaOpArgs.op.type === 2 /* ANNOTATE */) {
424
+ if (deltaOpArgs.op.type === ops_1.MergeTreeDeltaType.ANNOTATE) {
422
425
  if (deltaOpArgs.op.combiningOp && (deltaOpArgs.op.combiningOp.name === "consensus")) {
423
426
  this.updateConsensusProperty(deltaOpArgs.op, deltaOpArgs.sequencedMessage);
424
427
  }
@@ -429,7 +432,7 @@ class Client {
429
432
  this.accumWindow += (this.getCurrentSeq() - this.getCollabWindow().minSeq);
430
433
  }
431
434
  };
432
- if (opArgs.op.type === 3 /* GROUP */) {
435
+ if (opArgs.op.type === ops_1.MergeTreeDeltaType.GROUP) {
433
436
  for (const memberOp of opArgs.op.ops) {
434
437
  ackOp({
435
438
  groupOp: opArgs.op,
@@ -510,6 +513,47 @@ class Client {
510
513
  });
511
514
  return segmentPosition;
512
515
  }
516
+ /**
517
+ * Rebases a (local) position from the perspective `{ seq: seqNumberFrom, localSeq }` to the perspective
518
+ * of the current sequence number. This is desirable when rebasing operations for reconnection.
519
+ *
520
+ * If the position refers to a segment/offset that was removed by some operation between `seqNumberFrom` and
521
+ * the current sequence number, the returned position will align with the position of a reference given
522
+ * `SlideOnRemove` semantics.
523
+ */
524
+ rebasePosition(pos, seqNumberFrom, localSeq) {
525
+ (0, common_utils_1.assert)(localSeq <= this.mergeTree.collabWindow.localSeq, 0x300 /* localSeq greater than collab window */);
526
+ let segment;
527
+ let posAccumulated = 0;
528
+ let offset = pos;
529
+ const isInsertedInView = (seg) => (seg.seq !== undefined && seg.seq !== constants_1.UnassignedSequenceNumber && seg.seq <= seqNumberFrom)
530
+ || (seg.localSeq !== undefined && seg.localSeq <= localSeq);
531
+ const isRemovedFromView = ({ removedSeq, localRemovedSeq }) => (removedSeq !== undefined && removedSeq !== constants_1.UnassignedSequenceNumber && removedSeq <= seqNumberFrom)
532
+ || (localRemovedSeq !== undefined && localRemovedSeq <= localSeq);
533
+ this.mergeTree.walkAllSegments(this.mergeTree.root, (seg) => {
534
+ (0, common_utils_1.assert)(seg.seq !== undefined || seg.localSeq !== undefined, 0x301 /* Either seq or localSeq should be defined */);
535
+ segment = seg;
536
+ if (isInsertedInView(seg) && !isRemovedFromView(seg)) {
537
+ posAccumulated += seg.cachedLength;
538
+ if (offset >= seg.cachedLength) {
539
+ offset -= seg.cachedLength;
540
+ }
541
+ }
542
+ // Keep going while we've yet to reach the segment at the desired position
543
+ return posAccumulated <= pos;
544
+ });
545
+ (0, common_utils_1.assert)(segment !== undefined, 0x302 /* No segment found */);
546
+ const seqNumberTo = this.getCollabWindow().currentSeq;
547
+ if ((segment.removedSeq !== undefined &&
548
+ segment.removedSeq !== constants_1.UnassignedSequenceNumber &&
549
+ segment.removedSeq <= seqNumberTo)
550
+ || (segment.localRemovedSeq !== undefined && segment.localRemovedSeq <= localSeq)) {
551
+ // Segment that the position was in has been removed: null out offset.
552
+ offset = 0;
553
+ }
554
+ (0, common_utils_1.assert)(0 <= offset && offset < segment.cachedLength, 0x303 /* Invalid offset */);
555
+ return this.findReconnectionPosition(segment, localSeq) + offset;
556
+ }
513
557
  resetPendingDeltaToOps(resetOp, segmentGroup) {
514
558
  var _a, _b;
515
559
  (0, common_utils_1.assert)(!!segmentGroup, 0x033 /* "Segment group undefined" */);
@@ -527,7 +571,7 @@ class Client {
527
571
  const segmentPosition = this.findReconnectionPosition(segment, segmentGroup.localSeq);
528
572
  let newOp;
529
573
  switch (resetOp.type) {
530
- case 2 /* ANNOTATE */:
574
+ case ops_1.MergeTreeDeltaType.ANNOTATE:
531
575
  (0, common_utils_1.assert)(((_b = segment.propertyManager) === null || _b === void 0 ? void 0 : _b.hasPendingProperties()) === true, 0x036 /* "Segment has no pending properties" */);
532
576
  // if the segment has been removed, there's no need to send the annotate op
533
577
  // unless the remove was local, in which case the annotate must have come
@@ -536,11 +580,11 @@ class Client {
536
580
  newOp = (0, opBuilder_1.createAnnotateRangeOp)(segmentPosition, segmentPosition + segment.cachedLength, resetOp.props, resetOp.combiningOp);
537
581
  }
538
582
  break;
539
- case 0 /* INSERT */:
583
+ case ops_1.MergeTreeDeltaType.INSERT:
540
584
  (0, common_utils_1.assert)(segment.seq === constants_1.UnassignedSequenceNumber, 0x037 /* "Segment already has assigned sequence number" */);
541
585
  newOp = (0, opBuilder_1.createInsertSegmentOp)(segmentPosition, segment);
542
586
  break;
543
- case 1 /* REMOVE */:
587
+ case ops_1.MergeTreeDeltaType.REMOVE:
544
588
  if (segment.localRemovedSeq !== undefined) {
545
589
  newOp = (0, opBuilder_1.createRemoveRangeOp)(segmentPosition, segmentPosition + segment.cachedLength);
546
590
  }
@@ -562,16 +606,16 @@ class Client {
562
606
  const msg = opArgs.sequencedMessage;
563
607
  this.getOrAddShortClientId(msg.clientId);
564
608
  switch (op.type) {
565
- case 0 /* INSERT */:
609
+ case ops_1.MergeTreeDeltaType.INSERT:
566
610
  this.applyInsertOp(opArgs);
567
611
  break;
568
- case 1 /* REMOVE */:
612
+ case ops_1.MergeTreeDeltaType.REMOVE:
569
613
  this.applyRemoveRangeOp(opArgs);
570
614
  break;
571
- case 2 /* ANNOTATE */:
615
+ case ops_1.MergeTreeDeltaType.ANNOTATE:
572
616
  this.applyAnnotateRangeOp(opArgs);
573
617
  break;
574
- case 3 /* GROUP */: {
618
+ case ops_1.MergeTreeDeltaType.GROUP: {
575
619
  for (const memberOp of op.ops) {
576
620
  this.applyRemoteOp({
577
621
  op: memberOp,
@@ -588,19 +632,19 @@ class Client {
588
632
  applyStashedOp(op) {
589
633
  let metadata;
590
634
  switch (op.type) {
591
- case 0 /* INSERT */:
635
+ case ops_1.MergeTreeDeltaType.INSERT:
592
636
  this.applyInsertOp({ op });
593
637
  metadata = this.peekPendingSegmentGroups();
594
638
  break;
595
- case 1 /* REMOVE */:
639
+ case ops_1.MergeTreeDeltaType.REMOVE:
596
640
  this.applyRemoveRangeOp({ op });
597
641
  metadata = this.peekPendingSegmentGroups();
598
642
  break;
599
- case 2 /* ANNOTATE */:
643
+ case ops_1.MergeTreeDeltaType.ANNOTATE:
600
644
  this.applyAnnotateRangeOp({ op });
601
645
  metadata = this.peekPendingSegmentGroups();
602
646
  break;
603
- case 3 /* GROUP */:
647
+ case ops_1.MergeTreeDeltaType.GROUP:
604
648
  return op.ops.map((o) => this.applyStashedOp(o));
605
649
  default:
606
650
  (0, common_utils_1.unreachableCase)(op, "unrecognized op type");
@@ -655,7 +699,7 @@ class Client {
655
699
  */
656
700
  regeneratePendingOp(resetOp, segmentGroup) {
657
701
  const opList = [];
658
- if (resetOp.type === 3 /* GROUP */) {
702
+ if (resetOp.type === ops_1.MergeTreeDeltaType.GROUP) {
659
703
  if (Array.isArray(segmentGroup)) {
660
704
  (0, common_utils_1.assert)(resetOp.ops.length === segmentGroup.length, 0x03a /* "Number of ops in 'resetOp' must match the number of segment groups provided." */);
661
705
  for (let i = 0; i < resetOp.ops.length; i++) {
@@ -670,7 +714,7 @@ class Client {
670
714
  }
671
715
  }
672
716
  else {
673
- (0, common_utils_1.assert)(resetOp.type !== 3 /* GROUP */, 0x03c /* "Reset op has 'group' delta type!" */);
717
+ (0, common_utils_1.assert)(resetOp.type !== ops_1.MergeTreeDeltaType.GROUP, 0x03c /* "Reset op has 'group' delta type!" */);
674
718
  (0, common_utils_1.assert)(!Array.isArray(segmentGroup), 0x03d /* "segmentGroup is array rather than singleton!" */);
675
719
  opList.push(...this.resetPendingDeltaToOps(resetOp, segmentGroup));
676
720
  }
@@ -727,13 +771,13 @@ class Client {
727
771
  groupOp,
728
772
  };
729
773
  switch (op.type) {
730
- case 0 /* INSERT */:
774
+ case ops_1.MergeTreeDeltaType.INSERT:
731
775
  this.applyInsertOp(opArgs);
732
776
  break;
733
- case 2 /* ANNOTATE */:
777
+ case ops_1.MergeTreeDeltaType.ANNOTATE:
734
778
  this.applyAnnotateRangeOp(opArgs);
735
779
  break;
736
- case 1 /* REMOVE */:
780
+ case ops_1.MergeTreeDeltaType.REMOVE:
737
781
  this.applyRemoveRangeOp(opArgs);
738
782
  break;
739
783
  default:
@@ -764,18 +808,16 @@ class Client {
764
808
  }
765
809
  }
766
810
  getContainingSegment(pos, op) {
767
- let seq;
768
- let clientId;
769
- if (op) {
770
- clientId = this.getOrAddShortClientId(op.clientId);
771
- seq = op.referenceSequenceNumber;
772
- }
773
- else {
774
- const segWindow = this.mergeTree.getCollabWindow();
775
- seq = segWindow.currentSeq;
776
- clientId = segWindow.clientId;
777
- }
778
- return this.mergeTree.getContainingSegment(pos, seq, clientId);
811
+ const args = this.getClientSequenceArgsForMessage(op);
812
+ return this.mergeTree.getContainingSegment(pos, args.referenceSequenceNumber, args.clientId);
813
+ }
814
+ /**
815
+ * Returns the position to slide a reference to if a slide is required.
816
+ * @param segoff - The segment and offset to slide from
817
+ * @returns - segment and offset to slide the reference to
818
+ */
819
+ getSlideToSegment(segoff) {
820
+ return this.mergeTree._getSlideToSegment(segoff);
779
821
  }
780
822
  getPropertiesAtPosition(pos) {
781
823
  let propertiesAtPosition;