@fluidframework/sequence 1.2.0 → 2.0.0-internal.1.0.0.81589

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 (46) hide show
  1. package/dist/intervalCollection.d.ts +17 -11
  2. package/dist/intervalCollection.d.ts.map +1 -1
  3. package/dist/intervalCollection.js +30 -42
  4. package/dist/intervalCollection.js.map +1 -1
  5. package/dist/packageVersion.d.ts +1 -1
  6. package/dist/packageVersion.d.ts.map +1 -1
  7. package/dist/packageVersion.js +1 -1
  8. package/dist/packageVersion.js.map +1 -1
  9. package/dist/sequence.d.ts +5 -17
  10. package/dist/sequence.d.ts.map +1 -1
  11. package/dist/sequence.js +4 -28
  12. package/dist/sequence.js.map +1 -1
  13. package/dist/sequenceDeltaEvent.d.ts +0 -6
  14. package/dist/sequenceDeltaEvent.d.ts.map +1 -1
  15. package/dist/sequenceDeltaEvent.js +0 -1
  16. package/dist/sequenceDeltaEvent.js.map +1 -1
  17. package/dist/sharedString.d.ts +4 -0
  18. package/dist/sharedString.d.ts.map +1 -1
  19. package/dist/sharedString.js +11 -0
  20. package/dist/sharedString.js.map +1 -1
  21. package/lib/intervalCollection.d.ts +17 -11
  22. package/lib/intervalCollection.d.ts.map +1 -1
  23. package/lib/intervalCollection.js +31 -43
  24. package/lib/intervalCollection.js.map +1 -1
  25. package/lib/packageVersion.d.ts +1 -1
  26. package/lib/packageVersion.d.ts.map +1 -1
  27. package/lib/packageVersion.js +1 -1
  28. package/lib/packageVersion.js.map +1 -1
  29. package/lib/sequence.d.ts +5 -17
  30. package/lib/sequence.d.ts.map +1 -1
  31. package/lib/sequence.js +5 -29
  32. package/lib/sequence.js.map +1 -1
  33. package/lib/sequenceDeltaEvent.d.ts +0 -6
  34. package/lib/sequenceDeltaEvent.d.ts.map +1 -1
  35. package/lib/sequenceDeltaEvent.js +0 -1
  36. package/lib/sequenceDeltaEvent.js.map +1 -1
  37. package/lib/sharedString.d.ts +4 -0
  38. package/lib/sharedString.d.ts.map +1 -1
  39. package/lib/sharedString.js +11 -0
  40. package/lib/sharedString.js.map +1 -1
  41. package/package.json +60 -20
  42. package/src/intervalCollection.ts +73 -65
  43. package/src/packageVersion.ts +1 -1
  44. package/src/sequence.ts +4 -36
  45. package/src/sequenceDeltaEvent.ts +0 -7
  46. package/src/sharedString.ts +13 -2
@@ -11,6 +11,7 @@ import { UsageError } from "@fluidframework/container-utils";
11
11
  import {
12
12
  addProperties,
13
13
  Client,
14
+ compareReferencePositions,
14
15
  ConflictAction,
15
16
  createMap,
16
17
  ICombiningOp,
@@ -19,15 +20,18 @@ import {
19
20
  IntervalNode,
20
21
  IntervalTree,
21
22
  ISegment,
22
- LocalReference,
23
23
  MergeTreeDeltaType,
24
+ minReferencePosition,
24
25
  PropertiesManager,
25
26
  PropertySet,
26
27
  RedBlackTree,
28
+ LocalReferencePosition,
27
29
  ReferenceType,
28
30
  refTypeIncludesFlag,
29
31
  reservedRangeLabelsKey,
30
32
  UnassignedSequenceNumber,
33
+ maxReferencePosition,
34
+ createDetachedLocalReferencePosition,
31
35
  } from "@fluidframework/merge-tree";
32
36
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
33
37
  import { LoggingError } from "@fluidframework/telemetry-utils";
@@ -128,8 +132,26 @@ export interface ISerializableInterval extends IInterval {
128
132
 
129
133
  export interface IIntervalHelpers<TInterval extends ISerializableInterval> {
130
134
  compareEnds(a: TInterval, b: TInterval): number;
131
- create(label: string, start: number, end: number,
132
- client: Client, intervalType?: IntervalType, op?: ISequencedDocumentMessage): TInterval;
135
+ /**
136
+ *
137
+ * @param label - label of the interval collection this interval is being added to. This parameter is
138
+ * irrelevant for transient intervals.
139
+ * @param start - numerical start position of the interval
140
+ * @param end - numberical end position of the interval
141
+ * @param client - client creating the interval
142
+ * @param intervalType - Type of interval to create. Default is SlideOnRemove
143
+ * @param op - If this create came from a remote client, op that created it. Default is undefined (i.e. local)
144
+ * @param fromSnapshot - If this create came from loading a snapshot. Default is false.
145
+ */
146
+ create(
147
+ label: string,
148
+ start: number,
149
+ end: number,
150
+ client: Client,
151
+ intervalType?: IntervalType,
152
+ op?: ISequencedDocumentMessage,
153
+ fromSnapshot?: boolean,
154
+ ): TInterval;
133
155
  }
134
156
 
135
157
  export class Interval implements ISerializableInterval {
@@ -277,8 +299,9 @@ export class SequenceInterval implements ISerializableInterval {
277
299
  public propertyManager: PropertiesManager;
278
300
 
279
301
  constructor(
280
- public start: LocalReference,
281
- public end: LocalReference,
302
+ private readonly client: Client,
303
+ public start: LocalReferencePosition,
304
+ public end: LocalReferencePosition,
282
305
  public intervalType: IntervalType,
283
306
  props?: PropertySet,
284
307
  ) {
@@ -323,8 +346,8 @@ export class SequenceInterval implements ISerializableInterval {
323
346
  }
324
347
 
325
348
  public serialize(client: Client): ISerializedInterval {
326
- const startPosition = this.start.toPosition();
327
- const endPosition = this.end.toPosition();
349
+ const startPosition = client.localReferencePositionToPosition(this.start);
350
+ const endPosition = client.localReferencePositionToPosition(this.end);
328
351
  const serializedInterval: ISerializedInterval = {
329
352
  end: endPosition,
330
353
  intervalType: this.intervalType,
@@ -340,7 +363,7 @@ export class SequenceInterval implements ISerializableInterval {
340
363
  }
341
364
 
342
365
  public clone() {
343
- return new SequenceInterval(this.start, this.end, this.intervalType, this.properties);
366
+ return new SequenceInterval(this.client, this.start, this.end, this.intervalType, this.properties);
344
367
  }
345
368
 
346
369
  public compare(b: SequenceInterval) {
@@ -366,16 +389,16 @@ export class SequenceInterval implements ISerializableInterval {
366
389
  }
367
390
 
368
391
  public compareStart(b: SequenceInterval) {
369
- return this.start.compare(b.start);
392
+ return compareReferencePositions(this.start, b.start);
370
393
  }
371
394
 
372
395
  public compareEnd(b: SequenceInterval) {
373
- return this.end.compare(b.end);
396
+ return compareReferencePositions(this.end, b.end);
374
397
  }
375
398
 
376
399
  public overlaps(b: SequenceInterval) {
377
- const result = (this.start.compare(b.end) <= 0) &&
378
- (this.end.compare(b.start) >= 0);
400
+ const result = (compareReferencePositions(this.start, b.end) <= 0) &&
401
+ (compareReferencePositions(this.end, b.start) >= 0);
379
402
  return result;
380
403
  }
381
404
 
@@ -388,8 +411,8 @@ export class SequenceInterval implements ISerializableInterval {
388
411
  }
389
412
 
390
413
  public union(b: SequenceInterval) {
391
- return new SequenceInterval(this.start.min(b.start),
392
- this.end.max(b.end), this.intervalType);
414
+ return new SequenceInterval(this.client, minReferencePosition(this.start, b.start),
415
+ maxReferencePosition(this.end, b.end), this.intervalType);
393
416
  }
394
417
 
395
418
  public addProperties(
@@ -403,8 +426,8 @@ export class SequenceInterval implements ISerializableInterval {
403
426
  }
404
427
 
405
428
  public overlapsPos(bstart: number, bend: number) {
406
- const startPos = this.start.toPosition();
407
- const endPos = this.start.toPosition();
429
+ const startPos = this.client.localReferencePositionToPosition(this.start);
430
+ const endPos = this.client.localReferencePositionToPosition(this.end);
408
431
  return (endPos > bstart) && (startPos < bend);
409
432
  }
410
433
 
@@ -420,20 +443,17 @@ export class SequenceInterval implements ISerializableInterval {
420
443
 
421
444
  let startRef = this.start;
422
445
  if (start !== undefined) {
423
- startRef = createPositionReference(this.start.getClient(), start, getRefType(this.start.refType), op);
446
+ startRef = createPositionReference(this.client, start, getRefType(this.start.refType), op);
424
447
  startRef.addProperties(this.start.properties);
425
448
  }
426
449
 
427
450
  let endRef = this.end;
428
451
  if (end !== undefined) {
429
- endRef = createPositionReference(this.end.getClient(), end, getRefType(this.end.refType), op);
452
+ endRef = createPositionReference(this.client, end, getRefType(this.end.refType), op);
430
453
  endRef.addProperties(this.end.properties);
431
454
  }
432
455
 
433
- startRef.pairedRef = endRef;
434
- endRef.pairedRef = startRef;
435
-
436
- const newInterval = new SequenceInterval(startRef, endRef, this.intervalType);
456
+ const newInterval = new SequenceInterval(this.client, startRef, endRef, this.intervalType);
437
457
  if (this.properties) {
438
458
  newInterval.initializeProperties();
439
459
  this.propertyManager.copyTo(this.properties, newInterval.properties, newInterval.propertyManager);
@@ -455,30 +475,32 @@ function createPositionReferenceFromSegoff(
455
475
  client: Client,
456
476
  segoff: { segment: ISegment | undefined; offset: number | undefined; },
457
477
  refType: ReferenceType,
458
- op?: ISequencedDocumentMessage): LocalReference {
478
+ op?: ISequencedDocumentMessage): LocalReferencePosition {
459
479
  if (segoff.segment) {
460
480
  const ref = client.createLocalReferencePosition(segoff.segment, segoff.offset, refType, undefined);
461
- return ref as LocalReference;
481
+ return ref;
462
482
  } else {
463
483
  if (!op && !refTypeIncludesFlag(refType, ReferenceType.Transient)) {
464
484
  throw new UsageError("Non-transient references need segment");
465
485
  }
466
- return new LocalReference(client, undefined, 0, refType);
467
486
  }
487
+ return createDetachedLocalReferencePosition(refType);
468
488
  }
469
489
 
470
490
  function createPositionReference(
471
491
  client: Client,
472
492
  pos: number,
473
493
  refType: ReferenceType,
474
- op?: ISequencedDocumentMessage): LocalReference {
494
+ op?: ISequencedDocumentMessage,
495
+ fromSnapshot?: boolean): LocalReferencePosition {
475
496
  let segoff;
476
497
  if (op) {
477
498
  assert((refType & ReferenceType.SlideOnRemove) !== 0, 0x2f5 /* op create references must be SlideOnRemove */);
478
499
  segoff = client.getContainingSegment(pos, op);
479
500
  segoff = client.getSlideToSegment(segoff);
480
501
  } else {
481
- assert((refType & ReferenceType.SlideOnRemove) === 0, 0x2f6 /* SlideOnRemove references must be op created */);
502
+ assert((refType & ReferenceType.SlideOnRemove) === 0 || fromSnapshot,
503
+ 0x2f6 /* SlideOnRemove references must be op created */);
482
504
  segoff = client.getContainingSegment(pos);
483
505
  }
484
506
  return createPositionReferenceFromSegoff(client, segoff, refType, op);
@@ -490,7 +512,8 @@ function createSequenceInterval(
490
512
  end: number,
491
513
  client: Client,
492
514
  intervalType?: IntervalType,
493
- op?: ISequencedDocumentMessage): SequenceInterval {
515
+ op?: ISequencedDocumentMessage,
516
+ fromSnapshot?: boolean): SequenceInterval {
494
517
  let beginRefType = ReferenceType.RangeBegin;
495
518
  let endRefType = ReferenceType.RangeEnd;
496
519
  if (intervalType === IntervalType.Transient) {
@@ -504,7 +527,7 @@ function createSequenceInterval(
504
527
  // All non-transient interval references must eventually be SlideOnRemove
505
528
  // To ensure eventual consistency, they must start as StayOnRemove when
506
529
  // pending (created locally and creation op is not acked)
507
- if (op) {
530
+ if (op || fromSnapshot) {
508
531
  beginRefType |= ReferenceType.SlideOnRemove;
509
532
  endRefType |= ReferenceType.SlideOnRemove;
510
533
  } else {
@@ -513,17 +536,15 @@ function createSequenceInterval(
513
536
  }
514
537
  }
515
538
 
516
- const startLref = createPositionReference(client, start, beginRefType, op);
517
- const endLref = createPositionReference(client, end, endRefType, op);
518
- startLref.pairedRef = endLref;
519
- endLref.pairedRef = startLref;
539
+ const startLref = createPositionReference(client, start, beginRefType, op, fromSnapshot);
540
+ const endLref = createPositionReference(client, end, endRefType, op, fromSnapshot);
520
541
  const rangeProp = {
521
542
  [reservedRangeLabelsKey]: [label],
522
543
  };
523
544
  startLref.addProperties(rangeProp);
524
545
  endLref.addProperties(rangeProp);
525
546
 
526
- const ival = new SequenceInterval(startLref, endLref, intervalType, rangeProp);
547
+ const ival = new SequenceInterval(client, startLref, endLref, intervalType, rangeProp);
527
548
  return ival;
528
549
  }
529
550
 
@@ -846,7 +867,8 @@ export class LocalIntervalCollection<TInterval extends ISerializableInterval> {
846
867
  }
847
868
  }
848
869
 
849
- const compareSequenceIntervalEnds = (a: SequenceInterval, b: SequenceInterval): number => a.end.compare(b.end);
870
+ const compareSequenceIntervalEnds = (a: SequenceInterval, b: SequenceInterval): number =>
871
+ compareReferencePositions(a.end, b.end);
850
872
 
851
873
  class SequenceIntervalCollectionFactory
852
874
  implements IValueFactory<IntervalCollection<SequenceInterval>> {
@@ -1086,11 +1108,18 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
1086
1108
  if (this.savedSerializedIntervals) {
1087
1109
  for (const serializedInterval of this.savedSerializedIntervals) {
1088
1110
  this.localCollection.ensureSerializedId(serializedInterval);
1089
- this.localCollection.addInterval(
1090
- serializedInterval.start,
1091
- serializedInterval.end,
1092
- serializedInterval.intervalType,
1093
- serializedInterval.properties);
1111
+ const { start, end, intervalType, properties } = serializedInterval;
1112
+ const interval = this.helpers.create(
1113
+ label,
1114
+ start,
1115
+ end,
1116
+ client,
1117
+ intervalType,
1118
+ undefined,
1119
+ true,
1120
+ );
1121
+ interval.addProperties(properties);
1122
+ this.localCollection.add(interval);
1094
1123
  }
1095
1124
  }
1096
1125
  this.savedSerializedIntervals = undefined;
@@ -1302,11 +1331,6 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
1302
1331
  return entries && entries.length !== 0;
1303
1332
  }
1304
1333
 
1305
- /** @deprecated - use ackChange */
1306
- public changeInterval(serializedInterval: ISerializedInterval, local: boolean, op: ISequencedDocumentMessage) {
1307
- return this.ackChange(serializedInterval, local, op);
1308
- }
1309
-
1310
1334
  /** @internal */
1311
1335
  public ackChange(serializedInterval: ISerializedInterval, local: boolean, op: ISequencedDocumentMessage) {
1312
1336
  if (!this.attached) {
@@ -1418,15 +1442,15 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
1418
1442
  return rebased;
1419
1443
  }
1420
1444
 
1421
- private getSlideToSegment(lref: LocalReference) {
1422
- const segoff = { segment: lref.segment, offset: lref.offset };
1445
+ private getSlideToSegment(lref: LocalReferencePosition) {
1446
+ const segoff = { segment: lref.getSegment(), offset: lref.getOffset() };
1423
1447
  const newSegoff = this.client.getSlideToSegment(segoff);
1424
1448
  const value: { segment: ISegment | undefined; offset: number | undefined; } | undefined
1425
1449
  = (segoff.segment === newSegoff.segment && segoff.offset === newSegoff.offset) ? undefined : newSegoff;
1426
1450
  return value;
1427
1451
  }
1428
1452
 
1429
- private setSlideOnRemove(lref: LocalReference) {
1453
+ private setSlideOnRemove(lref: LocalReferencePosition) {
1430
1454
  let refType = lref.refType;
1431
1455
  refType = refType & ~ReferenceType.StayOnRemove;
1432
1456
  refType = refType | ReferenceType.SlideOnRemove;
@@ -1465,7 +1489,7 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
1465
1489
  if (needsStartUpdate || needsEndUpdate) {
1466
1490
  // In this case, where we change the start or end of an interval,
1467
1491
  // it is necessary to remove and re-add the interval listeners.
1468
- // This ensures that the correct listeners are added to the ReferencePosition.
1492
+ // This ensures that the correct listeners are added to the LocalReferencePosition.
1469
1493
  this.localCollection.removeExistingInterval(interval);
1470
1494
 
1471
1495
  if (needsStartUpdate) {
@@ -1488,14 +1512,6 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
1488
1512
  }
1489
1513
  }
1490
1514
 
1491
- /** @deprecated - use ackAdd */
1492
- public addInternal(
1493
- serializedInterval: ISerializedInterval,
1494
- local: boolean,
1495
- op: ISequencedDocumentMessage) {
1496
- return this.ackAdd(serializedInterval, local, op);
1497
- }
1498
-
1499
1515
  /** @internal */
1500
1516
  public ackAdd(
1501
1517
  serializedInterval: ISerializedInterval,
@@ -1534,14 +1550,6 @@ export class IntervalCollection<TInterval extends ISerializableInterval>
1534
1550
  return interval;
1535
1551
  }
1536
1552
 
1537
- /** @deprecated - use ackDelete */
1538
- public deleteInterval(
1539
- serializedInterval: ISerializedInterval,
1540
- local: boolean,
1541
- op: ISequencedDocumentMessage): void {
1542
- return this.ackDelete(serializedInterval, local, op);
1543
- }
1544
-
1545
1553
  /** @internal */
1546
1554
  public ackDelete(
1547
1555
  serializedInterval: ISerializedInterval,
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/sequence";
9
- export const pkgVersion = "1.2.0";
9
+ export const pkgVersion = "2.0.0-internal.1.0.0.81589";
package/src/sequence.ts CHANGED
@@ -29,7 +29,6 @@ import {
29
29
  IRelativePosition,
30
30
  ISegment,
31
31
  ISegmentAction,
32
- LocalReference,
33
32
  LocalReferencePosition,
34
33
  matchProperties,
35
34
  MergeTreeDeltaType,
@@ -298,20 +297,6 @@ export abstract class SharedSegmentSequence<T extends ISegment>
298
297
  return this.client.getRangeExtentsOfPosition(pos);
299
298
  }
300
299
 
301
- /**
302
- * @deprecated - use createLocalReferencePosition
303
- */
304
- public createPositionReference(
305
- segment: T,
306
- offset: number,
307
- refType: ReferenceType): LocalReference {
308
- const lref = new LocalReference(this.client, segment, offset, refType);
309
- if (refType !== ReferenceType.Transient) {
310
- this.addLocalReference(lref);
311
- }
312
- return lref;
313
- }
314
-
315
300
  public createLocalReferencePosition(
316
301
  segment: T,
317
302
  offset: number,
@@ -324,13 +309,6 @@ export abstract class SharedSegmentSequence<T extends ISegment>
324
309
  properties);
325
310
  }
326
311
 
327
- /**
328
- * @deprecated - use localReferencePositionToPosition
329
- */
330
- public localRefToPos(localRef: LocalReference) {
331
- return this.client.localReferencePositionToPosition(localRef);
332
- }
333
-
334
312
  public localReferencePositionToPosition(lref: ReferencePosition): number {
335
313
  return this.client.localReferencePositionToPosition(lref);
336
314
  }
@@ -377,20 +355,6 @@ export abstract class SharedSegmentSequence<T extends ISegment>
377
355
  }
378
356
  }
379
357
 
380
- /**
381
- * @deprecated - use createLocalReferencePosition
382
- */
383
- public addLocalReference(lref: LocalReference) {
384
- return this.client.addLocalReference(lref);
385
- }
386
-
387
- /**
388
- * @deprecated - use removeLocalReferencePosition
389
- */
390
- public removeLocalReference(lref: LocalReference) {
391
- return this.client.removeLocalReferencePosition(lref);
392
- }
393
-
394
358
  public removeLocalReferencePosition(lref: LocalReferencePosition) {
395
359
  return this.client.removeLocalReferencePosition(lref);
396
360
  }
@@ -424,6 +388,10 @@ export abstract class SharedSegmentSequence<T extends ISegment>
424
388
  return this.client.walkSegments<TClientData>(handler, start, end, accum, splitRange);
425
389
  }
426
390
 
391
+ /**
392
+ * @deprecated for internal use only. public export will be removed.
393
+ * @internal
394
+ */
427
395
  public getStackContext(startPos: number, rangeLabels: string[]): RangeStackMap {
428
396
  return this.client.getStackContext(startPos, rangeLabels);
429
397
  }
@@ -25,12 +25,6 @@ import {
25
25
  * They will not take into any future modifications performed to the underlying sequence and merge tree.
26
26
  */
27
27
  export abstract class SequenceEvent<TOperation extends MergeTreeDeltaOperationTypes = MergeTreeDeltaOperationTypes> {
28
- /**
29
- * @deprecated - Events no longer fire when the change they correspond to had no impact (e.g. a remote delete
30
- * event for a range that had already been deleted locally).
31
- * Clients can therefore assume this property is false.
32
- */
33
- public readonly isEmpty: boolean;
34
28
  public readonly deltaOperation: TOperation;
35
29
  private readonly sortedRanges: Lazy<SortedSegmentSet<ISequenceDeltaRange<TOperation>>>;
36
30
  private readonly pFirst: Lazy<ISequenceDeltaRange<TOperation>>;
@@ -41,7 +35,6 @@ export abstract class SequenceEvent<TOperation extends MergeTreeDeltaOperationTy
41
35
  private readonly mergeTreeClient: Client,
42
36
  ) {
43
37
  assert(deltaArgs.deltaSegments.length > 0, 0x2d8 /* "Empty change event should not be emitted." */);
44
- this.isEmpty = false;
45
38
  this.deltaOperation = deltaArgs.operation;
46
39
 
47
40
  this.sortedRanges = new Lazy<SortedSegmentSet<ISequenceDeltaRange<TOperation>>>(
@@ -7,10 +7,10 @@ import {
7
7
  ICombiningOp,
8
8
  IMergeTreeInsertMsg,
9
9
  IMergeTreeRemoveMsg,
10
+ IMergeTreeTextHelper,
10
11
  IRelativePosition,
11
12
  ISegment,
12
13
  Marker,
13
- MergeTreeTextHelper,
14
14
  PropertySet,
15
15
  ReferencePosition,
16
16
  ReferenceType,
@@ -81,7 +81,7 @@ export class SharedString extends SharedSegmentSequence<SharedStringSegment> imp
81
81
  return this;
82
82
  }
83
83
 
84
- private readonly mergeTreeTextHelper: MergeTreeTextHelper;
84
+ private readonly mergeTreeTextHelper: IMergeTreeTextHelper;
85
85
 
86
86
  constructor(document: IFluidDataStoreRuntime, public id: string, attributes: IChannelAttributes) {
87
87
  super(document, id, attributes, SharedStringFactory.segmentFromSpec);
@@ -260,4 +260,15 @@ export class SharedString extends SharedSegmentSequence<SharedStringSegment> imp
260
260
  public getMarkerFromId(id: string): ISegment {
261
261
  return this.client.getMarkerFromId(id);
262
262
  }
263
+
264
+ /**
265
+ * Revert an op
266
+ */
267
+ protected rollback(content: any, localOpMetadata: unknown): void {
268
+ if (this.client.rollback !== undefined) {
269
+ this.client.rollback(content, localOpMetadata);
270
+ } else {
271
+ super.rollback(content, localOpMetadata);
272
+ }
273
+ }
263
274
  }