@fluidframework/merge-tree 0.59.2000-63294 → 0.59.3000-66610

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 (81) hide show
  1. package/.eslintrc.js +0 -1
  2. package/dist/client.d.ts +4 -2
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +39 -33
  5. package/dist/client.js.map +1 -1
  6. package/dist/collections.d.ts.map +1 -1
  7. package/dist/collections.js.map +1 -1
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +1 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/localReference.d.ts +58 -2
  13. package/dist/localReference.d.ts.map +1 -1
  14. package/dist/localReference.js +60 -35
  15. package/dist/localReference.js.map +1 -1
  16. package/dist/mergeTree.d.ts +25 -21
  17. package/dist/mergeTree.d.ts.map +1 -1
  18. package/dist/mergeTree.js +72 -79
  19. package/dist/mergeTree.js.map +1 -1
  20. package/dist/partialLengths.js +10 -10
  21. package/dist/partialLengths.js.map +1 -1
  22. package/dist/referencePositions.d.ts +54 -0
  23. package/dist/referencePositions.d.ts.map +1 -0
  24. package/dist/referencePositions.js +90 -0
  25. package/dist/referencePositions.js.map +1 -0
  26. package/dist/segmentGroupCollection.js +1 -1
  27. package/dist/segmentGroupCollection.js.map +1 -1
  28. package/dist/segmentPropertiesManager.js +5 -5
  29. package/dist/segmentPropertiesManager.js.map +1 -1
  30. package/dist/snapshotChunks.js.map +1 -1
  31. package/dist/snapshotLoader.d.ts.map +1 -1
  32. package/dist/snapshotLoader.js +9 -9
  33. package/dist/snapshotLoader.js.map +1 -1
  34. package/dist/snapshotV1.js +7 -7
  35. package/dist/snapshotV1.js.map +1 -1
  36. package/dist/snapshotlegacy.js +5 -5
  37. package/dist/snapshotlegacy.js.map +1 -1
  38. package/dist/sortedSegmentSet.d.ts.map +1 -1
  39. package/dist/sortedSegmentSet.js.map +1 -1
  40. package/lib/client.d.ts +4 -2
  41. package/lib/client.d.ts.map +1 -1
  42. package/lib/client.js +10 -4
  43. package/lib/client.js.map +1 -1
  44. package/lib/collections.d.ts.map +1 -1
  45. package/lib/collections.js.map +1 -1
  46. package/lib/index.d.ts +1 -0
  47. package/lib/index.d.ts.map +1 -1
  48. package/lib/index.js +1 -0
  49. package/lib/index.js.map +1 -1
  50. package/lib/localReference.d.ts +58 -2
  51. package/lib/localReference.d.ts.map +1 -1
  52. package/lib/localReference.js +54 -29
  53. package/lib/localReference.js.map +1 -1
  54. package/lib/mergeTree.d.ts +25 -21
  55. package/lib/mergeTree.d.ts.map +1 -1
  56. package/lib/mergeTree.js +39 -42
  57. package/lib/mergeTree.js.map +1 -1
  58. package/lib/referencePositions.d.ts +54 -0
  59. package/lib/referencePositions.d.ts.map +1 -0
  60. package/lib/referencePositions.js +78 -0
  61. package/lib/referencePositions.js.map +1 -0
  62. package/lib/segmentPropertiesManager.js.map +1 -1
  63. package/lib/snapshotChunks.js.map +1 -1
  64. package/lib/snapshotLoader.d.ts.map +1 -1
  65. package/lib/snapshotLoader.js.map +1 -1
  66. package/lib/snapshotV1.js.map +1 -1
  67. package/lib/snapshotlegacy.js.map +1 -1
  68. package/lib/sortedSegmentSet.d.ts.map +1 -1
  69. package/lib/sortedSegmentSet.js.map +1 -1
  70. package/package.json +83 -14
  71. package/src/client.ts +19 -17
  72. package/src/collections.ts +26 -52
  73. package/src/index.ts +1 -0
  74. package/src/localReference.ts +69 -36
  75. package/src/mergeTree.ts +71 -90
  76. package/src/referencePositions.ts +122 -0
  77. package/src/snapshotChunks.ts +8 -8
  78. package/src/snapshotLoader.ts +4 -4
  79. package/src/snapshotV1.ts +1 -1
  80. package/src/snapshotlegacy.ts +1 -1
  81. package/src/sortedSegmentSet.ts +3 -3
package/src/mergeTree.ts CHANGED
@@ -50,27 +50,19 @@ import {
50
50
  matchProperties,
51
51
  PropertySet,
52
52
  } from "./properties";
53
+ import {
54
+ RangeStackMap,
55
+ ReferencePosition,
56
+ refGetRangeLabels,
57
+ refGetTileLabels,
58
+ refHasRangeLabel,
59
+ refHasRangeLabels,
60
+ refHasTileLabel,
61
+ refHasTileLabels,
62
+ } from "./referencePositions";
53
63
  import { SegmentGroupCollection } from "./segmentGroupCollection";
54
64
  import { PropertiesManager } from "./segmentPropertiesManager";
55
65
 
56
- export interface ReferencePosition {
57
- properties?: PropertySet;
58
- refType: ReferenceType;
59
- // True if this reference is a segment.
60
- isLeaf(): boolean;
61
- getSegment(): ISegment | undefined;
62
- getOffset(): number;
63
- addProperties(newProps: PropertySet, op?: ICombiningOp): void;
64
- hasTileLabels(): boolean;
65
- hasRangeLabels(): boolean;
66
- hasTileLabel(label: string): boolean;
67
- hasRangeLabel(label: string): boolean;
68
- getTileLabels(): string[] | undefined;
69
- getRangeLabels(): string[] | undefined;
70
- }
71
-
72
- export type RangeStackMap = MapLike<Stack<ReferencePosition>>;
73
-
74
66
  export interface IMergeNodeCommon {
75
67
  parent?: IMergeBlock;
76
68
  /**
@@ -265,7 +257,7 @@ export class MergeNode implements IMergeNodeCommon {
265
257
  }
266
258
 
267
259
  function addTile(tile: ReferencePosition, tiles: object) {
268
- const tileLabels = tile.getTileLabels();
260
+ const tileLabels = refGetTileLabels(tile);
269
261
  if (tileLabels) {
270
262
  for (const tileLabel of tileLabels) {
271
263
  tiles[tileLabel] = tile;
@@ -274,7 +266,7 @@ function addTile(tile: ReferencePosition, tiles: object) {
274
266
  }
275
267
 
276
268
  function addTileIfNotPresent(tile: ReferencePosition, tiles: object) {
277
- const tileLabels = tile.getTileLabels();
269
+ const tileLabels = refGetTileLabels(tile);
278
270
  if (tileLabels) {
279
271
  for (const tileLabel of tileLabels) {
280
272
  if (tiles[tileLabel] === undefined) {
@@ -345,9 +337,9 @@ function addNodeReferences(
345
337
  addTileIfNotPresent(segment, leftmostTiles);
346
338
  }
347
339
  if (segment.refType & (ReferenceType.NestBegin | ReferenceType.NestEnd)) {
348
- const rangeLabels = segment.getRangeLabels();
340
+ const rangeLabels = refGetRangeLabels(segment);
349
341
  if (rangeLabels) {
350
- for (const label of segment.getRangeLabels()!) {
342
+ for (const label of rangeLabels) {
351
343
  updateRangeInfo(label, segment);
352
344
  }
353
345
  }
@@ -362,7 +354,7 @@ function addNodeReferences(
362
354
  addTileIfNotPresent(lref, leftmostTiles);
363
355
  }
364
356
  if (lref.refType & (ReferenceType.NestBegin | ReferenceType.NestEnd)) {
365
- for (const label of lref.getRangeLabels()!) {
357
+ for (const label of refGetRangeLabels(lref)!) {
366
358
  updateRangeInfo(label, lref);
367
359
  }
368
360
  }
@@ -622,43 +614,9 @@ export abstract class BaseSegment extends MergeNode implements ISegment {
622
614
  protected abstract createSplitSegmentAt(pos: number): BaseSegment | undefined;
623
615
  }
624
616
 
625
- export const reservedTileLabelsKey = "referenceTileLabels";
626
- export const reservedRangeLabelsKey = "referenceRangeLabels";
627
617
  export const reservedMarkerIdKey = "markerId";
628
618
  export const reservedMarkerSimpleTypeKey = "markerSimpleType";
629
619
 
630
- export const refGetTileLabels = (refPos: ReferencePosition) =>
631
- (refPos.refType & ReferenceType.Tile)
632
- && refPos.properties ? refPos.properties[reservedTileLabelsKey] as string[] : undefined;
633
-
634
- export const refGetRangeLabels = (refPos: ReferencePosition) =>
635
- (refPos.refType & (ReferenceType.NestBegin | ReferenceType.NestEnd))
636
- && refPos.properties ? refPos.properties[reservedRangeLabelsKey] as string[] : undefined;
637
-
638
- export function refHasTileLabel(refPos: ReferencePosition, label: string) {
639
- const tileLabels = refPos.getTileLabels();
640
- if (tileLabels) {
641
- for (const refLabel of tileLabels) {
642
- if (label === refLabel) {
643
- return true;
644
- }
645
- }
646
- }
647
- return false;
648
- }
649
-
650
- export function refHasRangeLabel(refPos: ReferencePosition, label: string) {
651
- const rangeLabels = refPos.getRangeLabels();
652
- if (rangeLabels) {
653
- for (const refLabel of rangeLabels) {
654
- if (label === refLabel) {
655
- return true;
656
- }
657
- }
658
- }
659
- return false;
660
- }
661
-
662
620
  export interface IJSONMarkerSegment extends IJSONSegment {
663
621
  marker: IMarkerDef;
664
622
  }
@@ -728,26 +686,39 @@ export class Marker extends BaseSegment implements ReferencePosition {
728
686
  }
729
687
  }
730
688
 
689
+ /**
690
+ * @deprecated - use refHasTileLabels
691
+ */
731
692
  hasTileLabels() {
732
- return !!this.getTileLabels();
693
+ return refHasTileLabels(this);
733
694
  }
734
-
695
+ /**
696
+ * @deprecated - use refHasRangeLabels
697
+ */
735
698
  hasRangeLabels() {
736
- return !!this.getRangeLabels();
699
+ return refHasRangeLabels(this);
737
700
  }
738
-
701
+ /**
702
+ * @deprecated - use refHasTileLabel
703
+ */
739
704
  hasTileLabel(label: string): boolean {
740
705
  return refHasTileLabel(this, label);
741
706
  }
742
-
707
+ /**
708
+ * @deprecated - use refHasRangeLabel
709
+ */
743
710
  hasRangeLabel(label: string): boolean {
744
711
  return refHasRangeLabel(this, label);
745
712
  }
746
-
713
+ /**
714
+ * @deprecated - use refGetTileLabels
715
+ */
747
716
  getTileLabels(): string[] | undefined {
748
717
  return refGetTileLabels(this);
749
718
  }
750
-
719
+ /**
720
+ * @deprecated - use refGetRangeLabels
721
+ */
751
722
  getRangeLabels(): string[] | undefined {
752
723
  return refGetRangeLabels(this);
753
724
  }
@@ -774,7 +745,7 @@ export class Marker extends BaseSegment implements ReferencePosition {
774
745
  if (id) {
775
746
  bbuf += ` (${id}) `;
776
747
  }
777
- const tileLabels = this.getTileLabels();
748
+ const tileLabels = refGetTileLabels(this);
778
749
  if (tileLabels) {
779
750
  lbuf += "tile -- ";
780
751
  for (let i = 0, len = tileLabels.length; i < len; i++) {
@@ -785,7 +756,7 @@ export class Marker extends BaseSegment implements ReferencePosition {
785
756
  lbuf += tileLabel;
786
757
  }
787
758
  }
788
- const rangeLabels = this.getRangeLabels();
759
+ const rangeLabels = refGetRangeLabels(this);
789
760
  if (rangeLabels) {
790
761
  let rangeKind = "begin";
791
762
  if (this.refType & ReferenceType.NestEnd) {
@@ -931,7 +902,7 @@ interface IMarkerSearchRangeInfo {
931
902
 
932
903
  function applyLeafRangeMarker(marker: Marker, searchInfo: IMarkerSearchRangeInfo) {
933
904
  for (const rangeLabel of searchInfo.rangeLabels) {
934
- if (marker.hasRangeLabel(rangeLabel)) {
905
+ if (refHasRangeLabel(marker, rangeLabel)) {
935
906
  let currentStack = searchInfo.stacks[rangeLabel];
936
907
  if (currentStack === undefined) {
937
908
  currentStack = new Stack<Marker>();
@@ -981,7 +952,7 @@ function recordTileStart(
981
952
  end: number,
982
953
  searchInfo: IReferenceSearchInfo) {
983
954
  if (Marker.is(segment)) {
984
- if (segment.hasTileLabel(searchInfo.tileLabel)) {
955
+ if (refHasTileLabel(segment, searchInfo.tileLabel)) {
985
956
  searchInfo.tile = segment;
986
957
  }
987
958
  }
@@ -994,7 +965,7 @@ function tileShift(
994
965
  if (node.isLeaf()) {
995
966
  const seg = node;
996
967
  if ((searchInfo.mergeTree.localNetLength(seg) > 0) && Marker.is(seg)) {
997
- if (seg.hasTileLabel(searchInfo.tileLabel)) {
968
+ if (refHasTileLabel(seg, searchInfo.tileLabel)) {
998
969
  searchInfo.tile = seg;
999
970
  }
1000
971
  }
@@ -1134,7 +1105,7 @@ export class MergeTree {
1134
1105
  // and update the block's info.
1135
1106
  for (let childIndex = 0;
1136
1107
  childIndex < maxChildren && nodeIndex < nodes.length; // While we still have children & nodes left
1137
- childIndex++ , nodeIndex++ // Advance to next child & node
1108
+ childIndex++, nodeIndex++ // Advance to next child & node
1138
1109
  ) {
1139
1110
  // Insert the next node into the current block
1140
1111
  this.addNode(block, nodes[nodeIndex]);
@@ -1202,11 +1173,13 @@ export class MergeTree {
1202
1173
  } else {
1203
1174
  // Notify maintenance event observers that the segment is being unlinked from the MergeTree
1204
1175
  if (this.mergeTreeMaintenanceCallback) {
1205
- this.mergeTreeMaintenanceCallback({
1206
- operation: MergeTreeMaintenanceType.UNLINK,
1207
- deltaSegments: [{ segment }],
1208
- },
1209
- undefined);
1176
+ this.mergeTreeMaintenanceCallback(
1177
+ {
1178
+ operation: MergeTreeMaintenanceType.UNLINK,
1179
+ deltaSegments: [{ segment }],
1180
+ },
1181
+ undefined,
1182
+ );
1210
1183
  }
1211
1184
 
1212
1185
  segment.parent = undefined;
@@ -1223,11 +1196,13 @@ export class MergeTree {
1223
1196
  if (canAppend) {
1224
1197
  prevSegment!.append(segment);
1225
1198
  if (this.mergeTreeMaintenanceCallback) {
1226
- this.mergeTreeMaintenanceCallback({
1227
- operation: MergeTreeMaintenanceType.APPEND,
1228
- deltaSegments: [{ segment: prevSegment! }, { segment }],
1229
- },
1230
- undefined);
1199
+ this.mergeTreeMaintenanceCallback(
1200
+ {
1201
+ operation: MergeTreeMaintenanceType.APPEND,
1202
+ deltaSegments: [{ segment: prevSegment! }, { segment }],
1203
+ },
1204
+ undefined,
1205
+ );
1231
1206
  }
1232
1207
  segment.parent = undefined;
1233
1208
  segment.trackingCollection.trackingGroups.forEach((tg) => tg.unlink(segment));
@@ -1461,7 +1436,7 @@ export class MergeTree {
1461
1436
  const segment = node;
1462
1437
  const removalInfo = toRemovalInfo(segment);
1463
1438
 
1464
- if(removalInfo !== undefined
1439
+ if (removalInfo !== undefined
1465
1440
  && removalInfo.removedSeq !== UnassignedSequenceNumber
1466
1441
  && removalInfo.removedSeq <= refSeq) {
1467
1442
  // this segment is a tombstone eligible for zamboni
@@ -1485,7 +1460,7 @@ export class MergeTree {
1485
1460
  // the segment was inserted and removed before the
1486
1461
  // this context, so it will never exist for this
1487
1462
  // context
1488
- if(removalInfo !== undefined
1463
+ if (removalInfo !== undefined
1489
1464
  && removalInfo.removedSeq !== UnassignedSequenceNumber) {
1490
1465
  return undefined;
1491
1466
  }
@@ -1707,10 +1682,10 @@ export class MergeTree {
1707
1682
  nodesToUpdate.push(pendingSegment.parent!);
1708
1683
  }
1709
1684
  deltaSegments.push({
1710
- segment:pendingSegment,
1685
+ segment: pendingSegment,
1711
1686
  });
1712
1687
  });
1713
- if(this.mergeTreeMaintenanceCallback) {
1688
+ if (this.mergeTreeMaintenanceCallback) {
1714
1689
  this.mergeTreeMaintenanceCallback(
1715
1690
  {
1716
1691
  deltaSegments,
@@ -1874,7 +1849,7 @@ export class MergeTree {
1874
1849
  }
1875
1850
  const backLen = this.nodeLength(backSeg, this.collabWindow.currentSeq, clientId);
1876
1851
  // ignore removed segments
1877
- if(backLen === undefined) {
1852
+ if (backLen === undefined) {
1878
1853
  return true;
1879
1854
  }
1880
1855
  // Find the nearest 0 length seg we can insert over, as all other inserts
@@ -1940,7 +1915,7 @@ export class MergeTree {
1940
1915
  remoteClientPosition: number,
1941
1916
  remoteClientRefSeq: number,
1942
1917
  remoteClientId: number): number | undefined {
1943
- if(remoteClientRefSeq < this.collabWindow.minSeq) {
1918
+ if (remoteClientRefSeq < this.collabWindow.minSeq) {
1944
1919
  return undefined;
1945
1920
  }
1946
1921
 
@@ -2001,9 +1976,9 @@ export class MergeTree {
2001
1976
  const saveIfLocal = (locSegment: ISegment) => {
2002
1977
  // Save segment so can assign sequence number when acked by server
2003
1978
  if (this.collabWindow.collaborating) {
2004
- if ((locSegment.seq === UnassignedSequenceNumber) &&
2005
- (clientId === this.collabWindow.clientId)) {
1979
+ if ((locSegment.seq === UnassignedSequenceNumber) && (clientId === this.collabWindow.clientId)) {
2006
1980
  segmentGroup = this.addToPendingList(locSegment, segmentGroup, localSeq);
1981
+ // eslint-disable-next-line @typescript-eslint/brace-style
2007
1982
  }
2008
1983
  // LocSegment.seq === 0 when coming from SharedSegmentSequence.loadBody()
2009
1984
  // In all other cases this has to be true (checked by addToLRUSet):
@@ -2070,7 +2045,7 @@ export class MergeTree {
2070
2045
  operation: MergeTreeMaintenanceType.SPLIT,
2071
2046
  deltaSegments: [{ segment }, { segment: next }],
2072
2047
  },
2073
- undefined);
2048
+ undefined);
2074
2049
  }
2075
2050
 
2076
2051
  return { next };
@@ -2178,7 +2153,7 @@ export class MergeTree {
2178
2153
  for (childIndex = 0; childIndex < block.childCount; childIndex++) {
2179
2154
  child = children[childIndex];
2180
2155
  const len = this.nodeLength(child, refSeq, clientId);
2181
- if(len === undefined) {
2156
+ if (len === undefined) {
2182
2157
  // if the seg len in undefined, the segment
2183
2158
  // will be removed, so should just be skipped for now
2184
2159
  continue;
@@ -2467,6 +2442,9 @@ export class MergeTree {
2467
2442
  }
2468
2443
  }
2469
2444
 
2445
+ /**
2446
+ * @deprecated - use removeLocalReferencePosition
2447
+ */
2470
2448
  public removeLocalReference(segment: ISegment, lref: LocalReference) {
2471
2449
  if (segment.localRefs) {
2472
2450
  const removedRef = segment.localRefs.removeLocalRef(lref);
@@ -2477,6 +2455,9 @@ export class MergeTree {
2477
2455
  }
2478
2456
  }
2479
2457
 
2458
+ /**
2459
+ * @deprecated - use createLocalReference
2460
+ */
2480
2461
  public addLocalReference(lref: LocalReference) {
2481
2462
  const segment = lref.segment!;
2482
2463
  let localRefs = segment.localRefs;
@@ -0,0 +1,122 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { Stack } from "./collections";
7
+ import { ISegment } from "./mergeTree";
8
+ import { ReferenceType, ICombiningOp } from "./ops";
9
+ import { PropertySet, MapLike } from "./properties";
10
+
11
+ export const reservedTileLabelsKey = "referenceTileLabels";
12
+ export const reservedRangeLabelsKey = "referenceRangeLabels";
13
+
14
+ export const refGetTileLabels = (refPos: ReferencePosition): string[] | undefined =>
15
+ // eslint-disable-next-line no-bitwise
16
+ (refPos.refType & ReferenceType.Tile)
17
+ && refPos.properties ? refPos.properties[reservedTileLabelsKey] as string[] : undefined;
18
+
19
+ export const refGetRangeLabels = (refPos: ReferencePosition): string[] | undefined =>
20
+ // eslint-disable-next-line no-bitwise
21
+ (refPos.refType & (ReferenceType.NestBegin | ReferenceType.NestEnd))
22
+ && refPos.properties ? refPos.properties[reservedRangeLabelsKey] as string[] : undefined;
23
+
24
+ export function refHasTileLabel(refPos: ReferencePosition, label: string): boolean {
25
+ const tileLabels = refGetTileLabels(refPos);
26
+ if (tileLabels) {
27
+ for (const refLabel of tileLabels) {
28
+ if (label === refLabel) {
29
+ return true;
30
+ }
31
+ }
32
+ }
33
+ return false;
34
+ }
35
+
36
+ export function refHasRangeLabel(refPos: ReferencePosition, label: string): boolean {
37
+ const rangeLabels = refGetRangeLabels(refPos);
38
+ if (rangeLabels) {
39
+ for (const refLabel of rangeLabels) {
40
+ if (label === refLabel) {
41
+ return true;
42
+ }
43
+ }
44
+ }
45
+ return false;
46
+ }
47
+ export function refHasTileLabels(refPos: ReferencePosition): boolean {
48
+ return refGetTileLabels(refPos) !== undefined;
49
+ }
50
+ export function refHasRangeLabels(refPos: ReferencePosition): boolean {
51
+ return refGetRangeLabels(refPos) !== undefined;
52
+ }
53
+
54
+ export interface ReferencePosition {
55
+ properties?: PropertySet;
56
+ refType: ReferenceType;
57
+
58
+ getSegment(): ISegment | undefined;
59
+ getOffset(): number;
60
+ addProperties(newProps: PropertySet, op?: ICombiningOp): void;
61
+ isLeaf(): boolean;
62
+
63
+ /**
64
+ * @deprecated - use refHasTileLabels
65
+ */
66
+ hasTileLabels(): boolean;
67
+ /**
68
+ * @deprecated - use refHasRangeLabels
69
+ */
70
+ hasRangeLabels(): boolean;
71
+ /**
72
+ * @deprecated - use refHasTileLabel
73
+ */
74
+ hasTileLabel(label: string): boolean;
75
+ /**
76
+ * @deprecated - use refHasRangeLabel
77
+ */
78
+ hasRangeLabel(label: string): boolean;
79
+ /**
80
+ * @deprecated - use refGetTileLabels
81
+ */
82
+ getTileLabels(): string[] | undefined;
83
+ /**
84
+ * @deprecated - use refGetRangeLabels
85
+ */
86
+ getRangeLabels(): string[] | undefined;
87
+ }
88
+
89
+ export type RangeStackMap = MapLike<Stack<ReferencePosition>>;
90
+ export const DetachedReferencePosition = -1;
91
+
92
+ export function minReferencePosition<T extends ReferencePosition>(a: T, b: T): T {
93
+ if (compareReferencePositions(a, b) < 0) {
94
+ return a;
95
+ } else {
96
+ return b;
97
+ }
98
+ }
99
+
100
+ export function maxReferencePosition<T extends ReferencePosition>(a: T, b: T): T {
101
+ if (compareReferencePositions(a, b) > 0) {
102
+ return a;
103
+ } else {
104
+ return b;
105
+ }
106
+ }
107
+
108
+ export function compareReferencePositions(a: ReferencePosition, b: ReferencePosition): number {
109
+ const aSeg = a.getSegment();
110
+ const bSeg = b.getSegment();
111
+ if (aSeg === bSeg) {
112
+ return a.getOffset() - b.getOffset();
113
+ } else {
114
+ if (aSeg === undefined
115
+ || (bSeg !== undefined &&
116
+ aSeg.ordinal < bSeg.ordinal)) {
117
+ return -1;
118
+ } else {
119
+ return 1;
120
+ }
121
+ }
122
+ }
@@ -20,7 +20,7 @@ export type JsonSegmentSpecs = IJSONSegment | IJSONSegmentWithMergeInfo;
20
20
 
21
21
  export interface MergeTreeChunkLegacy extends VersionedMergeTreeChunk {
22
22
  version: undefined;
23
- chunkStartSegmentIndex: number,
23
+ chunkStartSegmentIndex: number;
24
24
  chunkSegmentCount: number;
25
25
  chunkLengthChars: number;
26
26
  totalLengthChars?: number;
@@ -32,19 +32,19 @@ export interface MergeTreeChunkLegacy extends VersionedMergeTreeChunk {
32
32
  }
33
33
 
34
34
  export interface MergeTreeHeaderChunkMetadata {
35
- id: string,
35
+ id: string;
36
36
  }
37
37
 
38
38
  export interface MergeTreeHeaderMetadata {
39
- totalLength: number,
40
- totalSegmentCount: number,
41
- orderedChunkMetadata: MergeTreeHeaderChunkMetadata[],
42
- sequenceNumber: number,
43
- minSequenceNumber: number,
39
+ totalLength: number;
40
+ totalSegmentCount: number;
41
+ orderedChunkMetadata: MergeTreeHeaderChunkMetadata[];
42
+ sequenceNumber: number;
43
+ minSequenceNumber: number;
44
44
  }
45
45
 
46
46
  export interface MergeTreeChunkV1 extends VersionedMergeTreeChunk {
47
- version: "1",
47
+ version: "1";
48
48
  startIndex: number;
49
49
  segmentCount: number;
50
50
  length: number;
@@ -38,18 +38,18 @@ export class SnapshotLoader {
38
38
 
39
39
  public async initialize(
40
40
  services: IChannelStorageService,
41
- ): Promise<{ catchupOpsP: Promise<ISequencedDocumentMessage[]> }> {
41
+ ): Promise<{ catchupOpsP: Promise<ISequencedDocumentMessage[]>; }> {
42
42
  const headerLoadedP =
43
43
  services.readBlob(SnapshotLegacy.header).then((header) => {
44
44
  assert(!!header, 0x05f /* "Missing blob header on legacy snapshot!" */);
45
- return this.loadHeader(bufferToString(header,"utf8"));
45
+ return this.loadHeader(bufferToString(header, "utf8"));
46
46
  });
47
47
 
48
48
  const catchupOpsP =
49
49
  this.loadBodyAndCatchupOps(headerLoadedP, services);
50
50
 
51
51
  catchupOpsP.catch(
52
- (err)=>this.logger.sendErrorEvent({ eventName: "CatchupOpsLoadFailure" },err));
52
+ (err) => this.logger.sendErrorEvent({ eventName: "CatchupOpsLoadFailure" }, err));
53
53
 
54
54
  await headerLoadedP;
55
55
 
@@ -111,7 +111,7 @@ export class SnapshotLoader {
111
111
  }
112
112
  if (spec.removedClientIds !== undefined) {
113
113
  seg.removedClientIds = spec.removedClientIds?.map(
114
- (sid)=> this.client.getOrAddShortClientId(sid));
114
+ (sid) => this.client.getOrAddShortClientId(sid));
115
115
  }
116
116
  } else {
117
117
  seg = this.client.specToSegment(spec);
package/src/snapshotV1.ts CHANGED
@@ -225,7 +225,7 @@ export class SnapshotV1 {
225
225
  ? this.getLongClientId(segment.removedClientIds[0])
226
226
  : undefined;
227
227
 
228
- raw.removedClientIds = segment.removedClientIds?.map((id)=>this.getLongClientId(id));
228
+ raw.removedClientIds = segment.removedClientIds?.map((id) => this.getLongClientId(id));
229
229
  }
230
230
 
231
231
  // Sanity check that we are preserving either the seq < minSeq or a removed segment's info.
@@ -131,7 +131,7 @@ export class SnapshotLegacy {
131
131
  segments === chunk1.totalSegmentCount,
132
132
  0x05e /* "emit: mismatch in totalSegmentCount" */);
133
133
 
134
- if(catchUpMsgs !== undefined && catchUpMsgs.length > 0) {
134
+ if (catchUpMsgs !== undefined && catchUpMsgs.length > 0) {
135
135
  builder.addBlob(
136
136
  this.mergeTree.options?.catchUpBlobName ?? SnapshotLegacy.catchupOps,
137
137
  serializer ? serializer.stringify(catchUpMsgs, bind) : JSON.stringify(catchUpMsgs));
@@ -15,7 +15,7 @@ import { ISegment } from "./mergeTree";
15
15
  * the segments changes. This invariant allows ensure the segments stay ordered and unique, and that new segments
16
16
  * can be inserted into that order.
17
17
  */
18
- export class SortedSegmentSet<T extends ISegment | { readonly segment: ISegment } = ISegment> {
18
+ export class SortedSegmentSet<T extends ISegment | { readonly segment: ISegment; } = ISegment> {
19
19
  private readonly ordinalSortedItems: T[] = [];
20
20
 
21
21
  public get size(): number {
@@ -52,7 +52,7 @@ export class SortedSegmentSet<T extends ISegment | { readonly segment: ISegment
52
52
  }
53
53
 
54
54
  private getOrdinal(item: T): string {
55
- const maybeObject = item as { readonly segment: ISegment };
55
+ const maybeObject = item as { readonly segment: ISegment; };
56
56
  if (maybeObject && maybeObject.segment) {
57
57
  return maybeObject.segment.ordinal;
58
58
  }
@@ -61,7 +61,7 @@ export class SortedSegmentSet<T extends ISegment | { readonly segment: ISegment
61
61
  return maybeSegment.ordinal;
62
62
  }
63
63
 
64
- private findOrdinalPosition(ordinal: string, start?: number, end?: number): { exists: boolean, index: number } {
64
+ private findOrdinalPosition(ordinal: string, start?: number, end?: number): { exists: boolean; index: number; } {
65
65
  if (this.ordinalSortedItems.length === 0) {
66
66
  return { exists: false, index: 0 };
67
67
  }