@fluidframework/sequence 2.43.0 → 2.50.0
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.
- package/CHANGELOG.md +4 -0
- package/dist/intervalCollection.d.ts +4 -5
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +93 -97
- package/dist/intervalCollection.js.map +1 -1
- package/dist/intervalCollectionMapInterfaces.d.ts +2 -11
- package/dist/intervalCollectionMapInterfaces.d.ts.map +1 -1
- package/dist/intervalCollectionMapInterfaces.js.map +1 -1
- package/dist/intervals/sequenceInterval.d.ts +7 -3
- package/dist/intervals/sequenceInterval.d.ts.map +1 -1
- package/dist/intervals/sequenceInterval.js +72 -30
- package/dist/intervals/sequenceInterval.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/lib/intervalCollection.d.ts +4 -5
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +93 -97
- package/lib/intervalCollection.js.map +1 -1
- package/lib/intervalCollectionMapInterfaces.d.ts +2 -11
- package/lib/intervalCollectionMapInterfaces.d.ts.map +1 -1
- package/lib/intervalCollectionMapInterfaces.js.map +1 -1
- package/lib/intervals/sequenceInterval.d.ts +7 -3
- package/lib/intervals/sequenceInterval.d.ts.map +1 -1
- package/lib/intervals/sequenceInterval.js +74 -32
- package/lib/intervals/sequenceInterval.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/package.json +17 -17
- package/src/intervalCollection.ts +109 -106
- package/src/intervalCollectionMapInterfaces.ts +2 -13
- package/src/intervals/sequenceInterval.ts +88 -32
- package/src/packageVersion.ts +1 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
/* eslint-disable no-bitwise */
|
|
7
7
|
|
|
8
|
+
import type { IDisposable } from "@fluidframework/core-interfaces";
|
|
8
9
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
9
10
|
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
10
11
|
import {
|
|
@@ -27,12 +28,11 @@ import {
|
|
|
27
28
|
Side,
|
|
28
29
|
endpointPosAndSide,
|
|
29
30
|
addProperties,
|
|
30
|
-
copyPropertiesAndManager,
|
|
31
31
|
type ISegmentInternal,
|
|
32
32
|
UnassignedSequenceNumber,
|
|
33
33
|
UniversalSequenceNumber,
|
|
34
34
|
} from "@fluidframework/merge-tree/internal";
|
|
35
|
-
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
35
|
+
import { LoggingError, UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
36
36
|
import { v4 as uuid } from "uuid";
|
|
37
37
|
|
|
38
38
|
import {
|
|
@@ -222,8 +222,10 @@ export interface SequenceInterval extends ISerializableInterval {
|
|
|
222
222
|
getIntervalId(): string;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
export class SequenceIntervalClass
|
|
226
|
+
// eslint-disable-next-line import/no-deprecated
|
|
227
|
+
implements SequenceInterval, ISerializableInterval, IDisposable
|
|
228
|
+
{
|
|
227
229
|
readonly #props: {
|
|
228
230
|
propertyManager?: PropertiesManager;
|
|
229
231
|
properties: PropertySet;
|
|
@@ -233,6 +235,7 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
233
235
|
* {@inheritDoc ISerializableInterval.properties}
|
|
234
236
|
*/
|
|
235
237
|
public get properties(): Readonly<PropertySet> {
|
|
238
|
+
this.verifyNotDispose();
|
|
236
239
|
return this.#props.properties;
|
|
237
240
|
}
|
|
238
241
|
|
|
@@ -241,6 +244,8 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
241
244
|
op?: ISequencedDocumentMessage,
|
|
242
245
|
rollback?: boolean,
|
|
243
246
|
) {
|
|
247
|
+
this.verifyNotDispose();
|
|
248
|
+
|
|
244
249
|
if (props !== undefined) {
|
|
245
250
|
this.#props.propertyManager ??= new PropertiesManager();
|
|
246
251
|
return this.#props.propertyManager.handleProperties(
|
|
@@ -258,6 +263,8 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
258
263
|
|
|
259
264
|
/***/
|
|
260
265
|
public get stickiness(): IntervalStickiness {
|
|
266
|
+
this.verifyNotDispose();
|
|
267
|
+
|
|
261
268
|
const startSegment: ISegmentInternal | undefined = this.start.getSegment();
|
|
262
269
|
const endSegment: ISegmentInternal | undefined = this.end.getSegment();
|
|
263
270
|
return computeStickinessFromSide(
|
|
@@ -291,6 +298,24 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
291
298
|
this.#props.properties = addProperties(this.#props.properties, props);
|
|
292
299
|
}
|
|
293
300
|
}
|
|
301
|
+
#disposed = false;
|
|
302
|
+
public get disposed() {
|
|
303
|
+
return this.#disposed;
|
|
304
|
+
}
|
|
305
|
+
public dispose(error?: Error): void {
|
|
306
|
+
if (this.#disposed) return;
|
|
307
|
+
this.#disposed = true;
|
|
308
|
+
this.client.removeLocalReferencePosition(this.start);
|
|
309
|
+
this.client.removeLocalReferencePosition(this.end);
|
|
310
|
+
this.removePositionChangeListeners();
|
|
311
|
+
this.#props.propertyManager = undefined;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
private verifyNotDispose() {
|
|
315
|
+
if (this.#disposed) {
|
|
316
|
+
throw new LoggingError("Invalid interval access after dispose");
|
|
317
|
+
}
|
|
318
|
+
}
|
|
294
319
|
|
|
295
320
|
private callbacks?: Record<"beforePositionChange" | "afterPositionChange", () => void>;
|
|
296
321
|
|
|
@@ -301,6 +326,7 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
301
326
|
beforePositionChange: () => void,
|
|
302
327
|
afterPositionChange: () => void,
|
|
303
328
|
): void {
|
|
329
|
+
this.verifyNotDispose();
|
|
304
330
|
if (this.callbacks === undefined) {
|
|
305
331
|
this.callbacks = {
|
|
306
332
|
beforePositionChange,
|
|
@@ -329,6 +355,8 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
329
355
|
* {@inheritDoc ISerializableInterval.serialize}
|
|
330
356
|
*/
|
|
331
357
|
public serialize(): ISerializedInterval {
|
|
358
|
+
this.verifyNotDispose();
|
|
359
|
+
|
|
332
360
|
return this.serializeDelta({
|
|
333
361
|
props: this.properties,
|
|
334
362
|
includeEndpoints: true,
|
|
@@ -342,6 +370,8 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
342
370
|
props: PropertySet | undefined;
|
|
343
371
|
includeEndpoints: boolean;
|
|
344
372
|
}): SerializedIntervalDelta {
|
|
373
|
+
this.verifyNotDispose();
|
|
374
|
+
|
|
345
375
|
const startSegment: ISegmentInternal | undefined = this.start.getSegment();
|
|
346
376
|
const endSegment: ISegmentInternal | undefined = this.end.getSegment();
|
|
347
377
|
const startPosition = includeEndpoints
|
|
@@ -371,6 +401,8 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
371
401
|
* {@inheritDoc IInterval.clone}
|
|
372
402
|
*/
|
|
373
403
|
public clone(): SequenceIntervalClass {
|
|
404
|
+
this.verifyNotDispose();
|
|
405
|
+
|
|
374
406
|
return new SequenceIntervalClass(
|
|
375
407
|
this.client,
|
|
376
408
|
this.id,
|
|
@@ -413,6 +445,8 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
413
445
|
* {@inheritDoc IInterval.compareStart}
|
|
414
446
|
*/
|
|
415
447
|
public compareStart(b: SequenceInterval) {
|
|
448
|
+
this.verifyNotDispose();
|
|
449
|
+
|
|
416
450
|
const dist = compareReferencePositions(this.start, b.start);
|
|
417
451
|
|
|
418
452
|
if (dist === 0) {
|
|
@@ -426,6 +460,8 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
426
460
|
* {@inheritDoc IInterval.compareEnd}
|
|
427
461
|
*/
|
|
428
462
|
public compareEnd(b: SequenceInterval): number {
|
|
463
|
+
this.verifyNotDispose();
|
|
464
|
+
|
|
429
465
|
const dist = compareReferencePositions(this.end, b.end);
|
|
430
466
|
|
|
431
467
|
if (dist === 0) {
|
|
@@ -439,6 +475,8 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
439
475
|
* {@inheritDoc IInterval.overlaps}
|
|
440
476
|
*/
|
|
441
477
|
public overlaps(b: SequenceInterval) {
|
|
478
|
+
this.verifyNotDispose();
|
|
479
|
+
|
|
442
480
|
const result =
|
|
443
481
|
compareReferencePositions(this.start, b.end) <= 0 &&
|
|
444
482
|
compareReferencePositions(this.end, b.start) >= 0;
|
|
@@ -456,6 +494,8 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
456
494
|
* {@inheritDoc IInterval.union}
|
|
457
495
|
*/
|
|
458
496
|
public union(b: SequenceIntervalClass) {
|
|
497
|
+
this.verifyNotDispose();
|
|
498
|
+
|
|
459
499
|
const newStart = minReferencePosition(this.start, b.start);
|
|
460
500
|
const newEnd = maxReferencePosition(this.end, b.end);
|
|
461
501
|
|
|
@@ -492,41 +532,41 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
492
532
|
* @returns whether this interval overlaps two numerical positions.
|
|
493
533
|
*/
|
|
494
534
|
public overlapsPos(bstart: number, bend: number) {
|
|
535
|
+
this.verifyNotDispose();
|
|
536
|
+
|
|
495
537
|
const startPos = this.client.localReferencePositionToPosition(this.start);
|
|
496
538
|
const endPos = this.client.localReferencePositionToPosition(this.end);
|
|
497
539
|
return endPos > bstart && startPos < bend;
|
|
498
540
|
}
|
|
499
541
|
|
|
500
542
|
public moveEndpointReferences(
|
|
501
|
-
rebased:
|
|
543
|
+
rebased: Record<"start" | "end", { segment: ISegment; offset: number }>,
|
|
502
544
|
) {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
this.start = startRef;
|
|
545
|
+
this.verifyNotDispose();
|
|
546
|
+
|
|
547
|
+
const startRef = createPositionReferenceFromSegoff({
|
|
548
|
+
client: this.client,
|
|
549
|
+
segoff: rebased.start,
|
|
550
|
+
refType: this.start.refType,
|
|
551
|
+
slidingPreference: this.start.slidingPreference,
|
|
552
|
+
canSlideToEndpoint: this.start.canSlideToEndpoint,
|
|
553
|
+
});
|
|
554
|
+
if (this.start.properties) {
|
|
555
|
+
startRef.addProperties(this.start.properties);
|
|
515
556
|
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
}
|
|
528
|
-
this.end = endRef;
|
|
557
|
+
this.start = startRef;
|
|
558
|
+
|
|
559
|
+
const endRef = createPositionReferenceFromSegoff({
|
|
560
|
+
client: this.client,
|
|
561
|
+
segoff: rebased.end,
|
|
562
|
+
refType: this.end.refType,
|
|
563
|
+
slidingPreference: this.end.slidingPreference,
|
|
564
|
+
canSlideToEndpoint: this.end.canSlideToEndpoint,
|
|
565
|
+
});
|
|
566
|
+
if (this.end.properties) {
|
|
567
|
+
endRef.addProperties(this.end.properties);
|
|
529
568
|
}
|
|
569
|
+
this.end = endRef;
|
|
530
570
|
}
|
|
531
571
|
|
|
532
572
|
/**
|
|
@@ -540,12 +580,17 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
540
580
|
localSeq?: number,
|
|
541
581
|
canSlideToEndpoint: boolean = false,
|
|
542
582
|
) {
|
|
583
|
+
this.verifyNotDispose();
|
|
584
|
+
|
|
543
585
|
const { startSide, endSide, startPos, endPos } = endpointPosAndSide(start, end);
|
|
544
586
|
const getRefType = (baseType: ReferenceType): ReferenceType => {
|
|
545
587
|
let refType = baseType;
|
|
546
588
|
if (op === undefined) {
|
|
547
589
|
refType &= ~ReferenceType.SlideOnRemove;
|
|
548
590
|
refType |= ReferenceType.StayOnRemove;
|
|
591
|
+
} else {
|
|
592
|
+
refType &= ~ReferenceType.StayOnRemove;
|
|
593
|
+
refType |= ReferenceType.SlideOnRemove;
|
|
549
594
|
}
|
|
550
595
|
return refType;
|
|
551
596
|
};
|
|
@@ -607,12 +652,23 @@ export class SequenceIntervalClass implements SequenceInterval, ISerializableInt
|
|
|
607
652
|
startSide ?? this.startSide,
|
|
608
653
|
endSide ?? this.endSide,
|
|
609
654
|
);
|
|
610
|
-
|
|
655
|
+
newInterval.#props.propertyManager = this.#props.propertyManager ??=
|
|
656
|
+
new PropertiesManager();
|
|
657
|
+
newInterval.#props.properties = this.#props.properties;
|
|
611
658
|
return newInterval;
|
|
612
659
|
}
|
|
613
660
|
|
|
614
661
|
public ackPropertiesChange(newProps: PropertySet, op: ISequencedDocumentMessage) {
|
|
615
|
-
this
|
|
662
|
+
this.verifyNotDispose();
|
|
663
|
+
|
|
664
|
+
if (Object.keys(newProps).length === 0) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
assert(
|
|
669
|
+
this.#props.propertyManager !== undefined,
|
|
670
|
+
0xbd5 /* must have property manager to ack */,
|
|
671
|
+
);
|
|
616
672
|
// Let the propertyManager prune its pending change-properties set.
|
|
617
673
|
this.#props.propertyManager.ack(op.sequenceNumber, op.minimumSequenceNumber, {
|
|
618
674
|
props: newProps,
|
package/src/packageVersion.ts
CHANGED