@fluidframework/sequence 2.0.0-dev.3.1.0.125672 → 2.0.0-dev.4.2.0.153917

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.
@@ -78,9 +78,9 @@ export interface ISerializedInterval {
78
78
  * At the time of writing, it's not plumbed through to the reconnect/rebase code, however, which does need it.
79
79
  */
80
80
  sequenceNumber: number;
81
- /** Start position of the interval (inclusive) */
81
+ /** Start position of the interval */
82
82
  start: number;
83
- /** End position of the interval (inclusive) */
83
+ /** End position of the interval */
84
84
  end: number;
85
85
  /** Interval type to create */
86
86
  intervalType: IntervalType;
@@ -209,6 +209,7 @@ export class Interval implements ISerializableInterval {
209
209
  public auxProps: PropertySet[] | undefined;
210
210
  /**
211
211
  * {@inheritDoc ISerializableInterval.propertyManager}
212
+ * @deprecated - This API was never intended to be public and will be marked internal in a future release.
212
213
  */
213
214
  public propertyManager: PropertiesManager;
214
215
  constructor(public start: number, public end: number, props?: PropertySet) {
@@ -223,11 +224,9 @@ export class Interval implements ISerializableInterval {
223
224
  /**
224
225
  * {@inheritDoc ISerializableInterval.getIntervalId}
225
226
  */
226
- public getIntervalId(): string | undefined {
227
+ public getIntervalId(): string {
227
228
  const id = this.properties?.[reservedIntervalIdKey];
228
- if (id === undefined) {
229
- return undefined;
230
- }
229
+ assert(id !== undefined, 0x5e1 /* interval ID should not be undefined */);
231
230
  return `${id}`;
232
231
  }
233
232
 
@@ -326,6 +325,7 @@ export class Interval implements ISerializableInterval {
326
325
 
327
326
  /**
328
327
  * {@inheritDoc IInterval.union}
328
+ * @deprecated - This API was never intended to be public and will be marked internal in a future release.
329
329
  */
330
330
  public union(b: Interval) {
331
331
  return new Interval(
@@ -341,6 +341,7 @@ export class Interval implements ISerializableInterval {
341
341
 
342
342
  /**
343
343
  * {@inheritDoc ISerializableInterval.addProperties}
344
+ * @deprecated - This API was never intended to be public and will be marked internal in a future release.
344
345
  */
345
346
  public addProperties(
346
347
  newProps: PropertySet,
@@ -362,6 +363,7 @@ export class Interval implements ISerializableInterval {
362
363
 
363
364
  /**
364
365
  * {@inheritDoc IInterval.modify}
366
+ * @deprecated - This API was never intended to be public and will be marked internal in a future release.
365
367
  */
366
368
  public modify(label: string, start: number, end: number, op?: ISequencedDocumentMessage) {
367
369
  const startPos = start ?? this.start;
@@ -396,6 +398,22 @@ export class Interval implements ISerializableInterval {
396
398
  * Interval impelmentation whose ends are associated with positions in a mutatable sequence.
397
399
  * As such, when content is inserted into the middle of the interval, the interval expands to
398
400
  * include that content.
401
+ *
402
+ * @remarks - The endpoint's position should be treated exclusively to get reasonable behavior--i.e.
403
+ * an interval referring to "hello" in "hello world" should have a start position of 0 and an end
404
+ * position of 5.
405
+ *
406
+ * To see why, consider what happens if "llo wor" is removed from the string to make "held".
407
+ * The interval's startpoint remains on the "h" (it isn't altered), but the interval's endpoint
408
+ * slides forward to the next unremoved position, which is the "l" in "held".
409
+ * Users would generally expect the interval to now refer to "he" (as it is the subset of content
410
+ * remaining after the removal), hence the "l" should be excluded.
411
+ * If the interval endpoint was treated inclusively, the interval would now refer to "hel", which
412
+ * is undesirable.
413
+ *
414
+ * Since the end of an interval is treated exclusively but cannot be greater than or equal to the
415
+ * length of the associated sequence, application models which leverage interval collections should
416
+ * consider inserting a marker at the end of the sequence to represent the end of the content.
399
417
  */
400
418
  export class SequenceInterval implements ISerializableInterval {
401
419
  /**
@@ -404,6 +422,7 @@ export class SequenceInterval implements ISerializableInterval {
404
422
  public properties: PropertySet;
405
423
  /**
406
424
  * {@inheritDoc ISerializableInterval.propertyManager}
425
+ * @deprecated - This API was never intended to be public and will be marked internal in a future release.
407
426
  */
408
427
  public propertyManager: PropertiesManager;
409
428
 
@@ -551,16 +570,15 @@ export class SequenceInterval implements ISerializableInterval {
551
570
  /**
552
571
  * {@inheritDoc ISerializableInterval.getIntervalId}
553
572
  */
554
- public getIntervalId(): string | undefined {
573
+ public getIntervalId(): string {
555
574
  const id = this.properties?.[reservedIntervalIdKey];
556
- if (id === undefined) {
557
- return undefined;
558
- }
575
+ assert(id !== undefined, 0x5e2 /* interval ID should not be undefined */);
559
576
  return `${id}`;
560
577
  }
561
578
 
562
579
  /**
563
580
  * {@inheritDoc IInterval.union}
581
+ * @deprecated - This API was never intended to be public and will be marked internal in a future release.
564
582
  */
565
583
  public union(b: SequenceInterval) {
566
584
  return new SequenceInterval(
@@ -573,6 +591,7 @@ export class SequenceInterval implements ISerializableInterval {
573
591
 
574
592
  /**
575
593
  * {@inheritDoc ISerializableInterval.addProperties}
594
+ * @deprecated - This API was never intended to be public and will be marked internal in a future release.
576
595
  */
577
596
  public addProperties(
578
597
  newProps: PropertySet,
@@ -586,7 +605,6 @@ export class SequenceInterval implements ISerializableInterval {
586
605
 
587
606
  /**
588
607
  * @returns whether this interval overlaps two numerical positions.
589
- * @remarks - this is currently strict overlap, which doesn't align with the endpoint treatment of`.overlaps()`
590
608
  */
591
609
  public overlapsPos(bstart: number, bend: number) {
592
610
  const startPos = this.client.localReferencePositionToPosition(this.start);
@@ -596,6 +614,7 @@ export class SequenceInterval implements ISerializableInterval {
596
614
 
597
615
  /**
598
616
  * {@inheritDoc IInterval.modify}
617
+ * @deprecated - This API was never intended to be public and will be marked internal in a future release.
599
618
  */
600
619
  public modify(
601
620
  label: string,
@@ -671,6 +690,7 @@ function createPositionReferenceFromSegoff(
671
690
  refType: ReferenceType,
672
691
  op?: ISequencedDocumentMessage,
673
692
  localSeq?: number,
693
+ fromSnapshot?: boolean,
674
694
  ): LocalReferencePosition {
675
695
  if (segoff.segment) {
676
696
  const ref = client.createLocalReferencePosition(
@@ -687,7 +707,12 @@ function createPositionReferenceFromSegoff(
687
707
  // - References coming from a remote client (location may have been concurrently removed)
688
708
  // - References being rebased to a new sequence number
689
709
  // (segment they originally referred to may have been removed with no suitable replacement)
690
- if (!op && !localSeq && !refTypeIncludesFlag(refType, ReferenceType.Transient)) {
710
+ if (
711
+ !op &&
712
+ !localSeq &&
713
+ !fromSnapshot &&
714
+ !refTypeIncludesFlag(refType, ReferenceType.Transient)
715
+ ) {
691
716
  throw new UsageError("Non-transient references need segment");
692
717
  }
693
718
 
@@ -720,7 +745,7 @@ function createPositionReference(
720
745
  );
721
746
  segoff = client.getContainingSegment(pos, undefined, localSeq);
722
747
  }
723
- return createPositionReferenceFromSegoff(client, segoff, refType, op, localSeq);
748
+ return createPositionReferenceFromSegoff(client, segoff, refType, op, localSeq, fromSnapshot);
724
749
  }
725
750
 
726
751
  export function createSequenceInterval(
@@ -945,7 +970,7 @@ export class LocalIntervalCollection<TInterval extends ISerializableInterval> {
945
970
 
946
971
  /**
947
972
  * @returns an array of all intervals contained in this collection that overlap the range
948
- * `[startPosition, endPosition]`.
973
+ * `[startPosition, endPosition)`.
949
974
  */
950
975
  public findOverlappingIntervals(startPosition: number, endPosition: number) {
951
976
  if (endPosition < startPosition || this.intervalTree.intervals.isEmpty()) {
@@ -1626,11 +1651,13 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
1626
1651
 
1627
1652
  /**
1628
1653
  * Creates a new interval and add it to the collection.
1629
- * @param start - interval start position
1630
- * @param end - interval end position
1654
+ * @param start - interval start position (inclusive)
1655
+ * @param end - interval end position (exclusive)
1631
1656
  * @param intervalType - type of the interval. All intervals are SlideOnRemove. Intervals may not be Transient.
1632
1657
  * @param props - properties of the interval
1633
1658
  * @returns - the created interval
1659
+ * @remarks - See documentation on {@link SequenceInterval} for comments on interval endpoint semantics: there are subtleties
1660
+ * with how the current half-open behavior is represented.
1634
1661
  */
1635
1662
  public add(
1636
1663
  start: number,
@@ -1931,6 +1958,13 @@ export class IntervalCollection<TInterval extends ISerializableInterval> extends
1931
1958
  }
1932
1959
  }
1933
1960
 
1961
+ /**
1962
+ * @deprecated - This functionality was useful when adding two intervals at the same start/end positions resulted
1963
+ * in a conflict. This is no longer the case (as of PR#6407), as interval collections support multiple intervals
1964
+ * at the same location and gives each interval a unique id.
1965
+ *
1966
+ * As such, the conflict resolver is never invoked and unnecessary. This API will be removed in an upcoming release.
1967
+ */
1934
1968
  public addConflictResolver(conflictResolver: IntervalConflictResolver<TInterval>): void {
1935
1969
  if (!this.localCollection) {
1936
1970
  throw new LoggingError("attachSequence must be called");
@@ -61,7 +61,7 @@ export interface IInterval {
61
61
  ): IInterval | undefined;
62
62
  /**
63
63
  * @returns whether this interval overlaps with `b`.
64
- * Since intervals are inclusive, this includes cases where endpoints are equal.
64
+ * Intervals are considered to overlap if their intersection is non-empty.
65
65
  */
66
66
  overlaps(b: IInterval): boolean;
67
67
  /**
@@ -77,6 +77,13 @@ const intervalComparer = (a: IInterval, b: IInterval) => a.compare(b);
77
77
 
78
78
  export type IntervalNode<T extends IInterval> = RBNode<T, AugmentedIntervalNode>;
79
79
 
80
+ /**
81
+ * @deprecated - This functionality was useful when adding two intervals at the same start/end positions resulted
82
+ * in a conflict. This is no longer the case (as of PR#6407), as interval collections support multiple intervals
83
+ * at the same location and gives each interval a unique id.
84
+ *
85
+ * As such, conflict resolvers are never invoked and unnecessary. They will be removed in an upcoming release.
86
+ */
80
87
  export type IntervalConflictResolver<TInterval> = (a: TInterval, b: TInterval) => TInterval;
81
88
 
82
89
  export class IntervalTree<T extends IInterval>
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/sequence";
9
- export const pkgVersion = "2.0.0-dev.3.1.0.125672";
9
+ export const pkgVersion = "2.0.0-dev.4.2.0.153917";
package/src/sequence.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { Deferred, bufferToString, assert } from "@fluidframework/common-utils";
6
- import { ChildLogger, loggerToMonitoringContext } from "@fluidframework/telemetry-utils";
6
+ import { ChildLogger } from "@fluidframework/telemetry-utils";
7
7
  import { ISequencedDocumentMessage, MessageType } from "@fluidframework/protocol-definitions";
8
8
  import {
9
9
  IChannelAttributes,
@@ -22,7 +22,6 @@ import {
22
22
  IMergeTreeDeltaOp,
23
23
  IMergeTreeGroupMsg,
24
24
  IMergeTreeOp,
25
- IMergeTreeOptions,
26
25
  IMergeTreeRemoveMsg,
27
26
  IRelativePosition,
28
27
  ISegment,
@@ -197,22 +196,10 @@ export abstract class SharedSegmentSequence<T extends ISegment>
197
196
  this.logger.sendErrorEvent({ eventName: "SequenceLoadFailed" }, error);
198
197
  });
199
198
 
200
- const mergeTreeOptions = {
201
- ...(dataStoreRuntime.options as IMergeTreeOptions),
202
- };
203
-
204
- const configSetAttribution = loggerToMonitoringContext(this.logger).config.getBoolean(
205
- "Fluid.Attribution.EnableOnNewFile",
206
- );
207
- if (configSetAttribution !== undefined) {
208
- mergeTreeOptions.attribution ??= {};
209
- mergeTreeOptions.attribution.track = configSetAttribution;
210
- }
211
-
212
199
  this.client = new Client(
213
200
  segmentFromSpec,
214
201
  ChildLogger.create(this.logger, "SharedSegmentSequence.MergeTreeClient"),
215
- mergeTreeOptions,
202
+ dataStoreRuntime.options,
216
203
  );
217
204
 
218
205
  this.client.on("delta", (opArgs, deltaArgs) => {
package/.editorconfig DELETED
@@ -1,7 +0,0 @@
1
- [*]
2
- indent_size = 4
3
- trim_trailing_whitespace = true
4
- insert_final_newline = true
5
-
6
- [package.json]
7
- indent_size = 2