@fluidframework/sequence 2.41.0 → 2.43.0-343119

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 (75) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/api-report/sequence.legacy.alpha.api.md +13 -5
  3. package/dist/intervalCollection.d.ts +14 -19
  4. package/dist/intervalCollection.d.ts.map +1 -1
  5. package/dist/intervalCollection.js +113 -128
  6. package/dist/intervalCollection.js.map +1 -1
  7. package/dist/intervalCollectionMap.d.ts +3 -3
  8. package/dist/intervalCollectionMap.d.ts.map +1 -1
  9. package/dist/intervalCollectionMap.js.map +1 -1
  10. package/dist/intervalCollectionMapInterfaces.d.ts +22 -4
  11. package/dist/intervalCollectionMapInterfaces.d.ts.map +1 -1
  12. package/dist/intervalCollectionMapInterfaces.js.map +1 -1
  13. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +4 -4
  14. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
  15. package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
  16. package/dist/intervals/intervalUtils.d.ts +12 -1
  17. package/dist/intervals/intervalUtils.d.ts.map +1 -1
  18. package/dist/intervals/intervalUtils.js.map +1 -1
  19. package/dist/intervals/sequenceInterval.d.ts +18 -5
  20. package/dist/intervals/sequenceInterval.d.ts.map +1 -1
  21. package/dist/intervals/sequenceInterval.js +2 -1
  22. package/dist/intervals/sequenceInterval.js.map +1 -1
  23. package/dist/packageVersion.d.ts +1 -1
  24. package/dist/packageVersion.d.ts.map +1 -1
  25. package/dist/packageVersion.js +1 -1
  26. package/dist/packageVersion.js.map +1 -1
  27. package/dist/revertibles.d.ts.map +1 -1
  28. package/dist/revertibles.js +6 -3
  29. package/dist/revertibles.js.map +1 -1
  30. package/dist/sequence.d.ts +2 -1
  31. package/dist/sequence.d.ts.map +1 -1
  32. package/dist/sequence.js +6 -3
  33. package/dist/sequence.js.map +1 -1
  34. package/lib/intervalCollection.d.ts +14 -19
  35. package/lib/intervalCollection.d.ts.map +1 -1
  36. package/lib/intervalCollection.js +114 -129
  37. package/lib/intervalCollection.js.map +1 -1
  38. package/lib/intervalCollectionMap.d.ts +3 -3
  39. package/lib/intervalCollectionMap.d.ts.map +1 -1
  40. package/lib/intervalCollectionMap.js.map +1 -1
  41. package/lib/intervalCollectionMapInterfaces.d.ts +22 -4
  42. package/lib/intervalCollectionMapInterfaces.d.ts.map +1 -1
  43. package/lib/intervalCollectionMapInterfaces.js.map +1 -1
  44. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts +4 -4
  45. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
  46. package/lib/intervalIndex/overlappingIntervalsIndex.js +1 -1
  47. package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
  48. package/lib/intervals/intervalUtils.d.ts +12 -1
  49. package/lib/intervals/intervalUtils.d.ts.map +1 -1
  50. package/lib/intervals/intervalUtils.js.map +1 -1
  51. package/lib/intervals/sequenceInterval.d.ts +18 -5
  52. package/lib/intervals/sequenceInterval.d.ts.map +1 -1
  53. package/lib/intervals/sequenceInterval.js +2 -1
  54. package/lib/intervals/sequenceInterval.js.map +1 -1
  55. package/lib/packageVersion.d.ts +1 -1
  56. package/lib/packageVersion.d.ts.map +1 -1
  57. package/lib/packageVersion.js +1 -1
  58. package/lib/packageVersion.js.map +1 -1
  59. package/lib/revertibles.d.ts.map +1 -1
  60. package/lib/revertibles.js +6 -3
  61. package/lib/revertibles.js.map +1 -1
  62. package/lib/sequence.d.ts +2 -1
  63. package/lib/sequence.d.ts.map +1 -1
  64. package/lib/sequence.js +6 -3
  65. package/lib/sequence.js.map +1 -1
  66. package/package.json +17 -17
  67. package/src/intervalCollection.ts +191 -195
  68. package/src/intervalCollectionMap.ts +4 -11
  69. package/src/intervalCollectionMapInterfaces.ts +25 -5
  70. package/src/intervalIndex/overlappingIntervalsIndex.ts +15 -11
  71. package/src/intervals/intervalUtils.ts +12 -1
  72. package/src/intervals/sequenceInterval.ts +22 -4
  73. package/src/packageVersion.ts +1 -1
  74. package/src/revertibles.ts +7 -6
  75. package/src/sequence.ts +11 -13
@@ -18,7 +18,6 @@ import {
18
18
  } from "./intervalCollection.js";
19
19
  import {
20
20
  IIntervalCollectionTypeOperationValue,
21
- IMapMessageLocalMetadata,
22
21
  ISerializableIntervalCollection,
23
22
  SequenceOptions,
24
23
  } from "./intervalCollectionMapInterfaces.js";
@@ -94,10 +93,7 @@ export class IntervalCollectionMap {
94
93
  constructor(
95
94
  private readonly serializer: IFluidSerializer,
96
95
  private readonly handle: IFluidHandle,
97
- private readonly submitMessage: (
98
- op: IMapOperation,
99
- localOpMetadata: IMapMessageLocalMetadata,
100
- ) => void,
96
+ private readonly submitMessage: (op: IMapOperation, localOpMetadata: unknown) => void,
101
97
  private readonly options?: Partial<SequenceOptions>,
102
98
  ) {}
103
99
 
@@ -192,10 +188,7 @@ export class IntervalCollectionMap {
192
188
  * also sent if we are asked to resubmit the message.
193
189
  * @returns True if the operation was submitted, false otherwise.
194
190
  */
195
- public tryResubmitMessage(
196
- content: unknown,
197
- localOpMetadata: IMapMessageLocalMetadata,
198
- ): boolean {
191
+ public tryResubmitMessage(content: unknown, localOpMetadata: unknown): boolean {
199
192
  if (isMapOperation(content)) {
200
193
  const { value, key } = content;
201
194
  const localValue = this.data.get(key);
@@ -212,7 +205,7 @@ export class IntervalCollectionMap {
212
205
 
213
206
  assert(localValue !== undefined, 0xb7e /* Local value expected on rollback */);
214
207
 
215
- localValue.rollback(content.value, localOpMetadata as IMapMessageLocalMetadata);
208
+ localValue.rollback(content.value, localOpMetadata);
216
209
 
217
210
  return true;
218
211
  }
@@ -254,7 +247,7 @@ export class IntervalCollectionMap {
254
247
  if (isMapOperation(content)) {
255
248
  const { value, key } = content;
256
249
  const localValue = this.data.get(key) ?? this.createCore(key, local);
257
- localValue.process(value, local, message, localOpMetadata as IMapMessageLocalMetadata);
250
+ localValue.process(value, local, message, localOpMetadata);
258
251
  return true;
259
252
  }
260
253
  return false;
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
7
- import type { IMergeTreeOptions } from "@fluidframework/merge-tree/internal";
7
+ import { IMergeTreeOptions, ListNode } from "@fluidframework/merge-tree/internal";
8
8
 
9
9
  import type {
10
10
  IntervalCollection,
@@ -17,11 +17,31 @@ import {
17
17
  SerializedIntervalDelta,
18
18
  } from "./intervals/index.js";
19
19
 
20
- export interface IMapMessageLocalMetadata {
20
+ export interface IntervalAddLocalMetadata {
21
+ type: typeof IntervalDeltaOpType.ADD;
21
22
  localSeq: number;
22
- previous?: ISerializedInterval;
23
+ endpointChangesNode?: ListNode<IntervalAddLocalMetadata | IntervalChangeLocalMetadata>;
24
+ rebased?: ISerializedInterval;
25
+ original: ISerializedInterval;
23
26
  }
24
-
27
+ export interface IntervalChangeLocalMetadata {
28
+ type: typeof IntervalDeltaOpType.CHANGE;
29
+ localSeq: number;
30
+ previous: ISerializedInterval;
31
+ endpointChangesNode?: ListNode<IntervalChangeLocalMetadata | IntervalChangeLocalMetadata>;
32
+ rebased?: SerializedIntervalDelta;
33
+ original: SerializedIntervalDelta;
34
+ }
35
+ export interface IntervalDeleteLocalMetadata {
36
+ type: typeof IntervalDeltaOpType.DELETE;
37
+ localSeq: number;
38
+ previous: ISerializedInterval;
39
+ endpointChangesNode?: undefined;
40
+ }
41
+ export type IntervalMessageLocalMetadata =
42
+ | IntervalAddLocalMetadata
43
+ | IntervalChangeLocalMetadata
44
+ | IntervalDeleteLocalMetadata;
25
45
  /**
26
46
  * Optional flags that configure options for sequence DDSs
27
47
  * @internal
@@ -73,7 +93,7 @@ export interface IIntervalCollectionOperation {
73
93
  params: ISerializedInterval,
74
94
  local: boolean,
75
95
  message: ISequencedDocumentMessage | undefined,
76
- localOpMetadata: IMapMessageLocalMetadata | undefined,
96
+ localOpMetadata: IntervalMessageLocalMetadata | undefined,
77
97
  ): void;
78
98
  }
79
99
 
@@ -12,7 +12,11 @@ import {
12
12
  } from "@fluidframework/merge-tree/internal";
13
13
 
14
14
  import { IntervalNode, IntervalTree } from "../intervalTree.js";
15
- import { SequenceInterval, createTransientInterval } from "../intervals/index.js";
15
+ import {
16
+ SequenceInterval,
17
+ SequenceIntervalClass,
18
+ createTransientInterval,
19
+ } from "../intervals/index.js";
16
20
  import { ISharedString } from "../sharedString.js";
17
21
 
18
22
  import { type SequenceIntervalIndex } from "./intervalIndex.js";
@@ -40,7 +44,7 @@ export interface ISequenceOverlappingIntervalsIndex extends SequenceIntervalInde
40
44
  }
41
45
 
42
46
  export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsIndex {
43
- protected readonly intervalTree = new IntervalTree<SequenceInterval>();
47
+ protected readonly intervalTree = new IntervalTree<SequenceIntervalClass>();
44
48
  protected readonly client: Client;
45
49
 
46
50
  constructor(client: Client) {
@@ -68,7 +72,7 @@ export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsI
68
72
  if (start === undefined && end === undefined) {
69
73
  // No start/end provided. Gather the whole tree in the specified order.
70
74
  if (iteratesForward) {
71
- this.intervalTree.map((interval: SequenceInterval) => {
75
+ this.intervalTree.map((interval: SequenceIntervalClass) => {
72
76
  results.push(interval);
73
77
  });
74
78
  } else {
@@ -77,7 +81,7 @@ export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsI
77
81
  });
78
82
  }
79
83
  } else {
80
- const transientInterval: SequenceInterval = createTransientInterval(
84
+ const transientInterval: SequenceIntervalClass = createTransientInterval(
81
85
  start ?? "start",
82
86
  end ?? "end",
83
87
  this.client,
@@ -87,13 +91,13 @@ export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsI
87
91
  // Only end position provided. Since the tree is not sorted by end position,
88
92
  // walk the whole tree in the specified order, gathering intervals that match the end.
89
93
  if (iteratesForward) {
90
- this.intervalTree.map((interval: SequenceInterval) => {
94
+ this.intervalTree.map((interval: SequenceIntervalClass) => {
91
95
  if (transientInterval.compareEnd(interval) === 0) {
92
96
  results.push(interval);
93
97
  }
94
98
  });
95
99
  } else {
96
- this.intervalTree.mapBackward((interval: SequenceInterval) => {
100
+ this.intervalTree.mapBackward((interval: SequenceIntervalClass) => {
97
101
  if (transientInterval.compareEnd(interval) === 0) {
98
102
  results.push(interval);
99
103
  }
@@ -104,15 +108,15 @@ export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsI
104
108
  // this start position.
105
109
  const compareFn =
106
110
  end === undefined
107
- ? (node: IntervalNode<SequenceInterval>) => {
111
+ ? (node: IntervalNode<SequenceIntervalClass>) => {
108
112
  return transientInterval.compareStart(node.key);
109
113
  }
110
- : (node: IntervalNode<SequenceInterval>) => {
114
+ : (node: IntervalNode<SequenceIntervalClass>) => {
111
115
  return transientInterval.compare(node.key);
112
116
  };
113
117
  const continueLeftFn = (cmpResult: number) => cmpResult <= 0;
114
118
  const continueRightFn = (cmpResult: number) => cmpResult >= 0;
115
- const actionFn = (node: IntervalNode<SequenceInterval>) => {
119
+ const actionFn = (node: IntervalNode<SequenceIntervalClass>) => {
116
120
  results.push(node.key);
117
121
  };
118
122
 
@@ -157,11 +161,11 @@ export class OverlappingIntervalsIndex implements ISequenceOverlappingIntervalsI
157
161
  return overlappingIntervalNodes.map((node) => node.key);
158
162
  }
159
163
 
160
- public remove(interval: SequenceInterval) {
164
+ public remove(interval: SequenceIntervalClass) {
161
165
  this.intervalTree.removeExisting(interval);
162
166
  }
163
167
 
164
- public add(interval: SequenceInterval) {
168
+ public add(interval: SequenceIntervalClass) {
165
169
  this.intervalTree.put(interval);
166
170
  }
167
171
  }
@@ -21,6 +21,9 @@ import {
21
21
  export interface IInterval {
22
22
  /**
23
23
  * @returns a new interval object with identical semantics.
24
+ *
25
+ * @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
26
+ * @privateRemarks Move to ISerializableInterval after deprecation period
24
27
  */
25
28
  clone(): IInterval;
26
29
  /**
@@ -45,6 +48,8 @@ export interface IInterval {
45
48
  compareEnd(b: IInterval): number;
46
49
  /**
47
50
  * Modifies one or more of the endpoints of this interval, returning a new interval representing the result.
51
+ *
52
+ * @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
48
53
  */
49
54
  modify(
50
55
  label: string,
@@ -63,6 +68,8 @@ export interface IInterval {
63
68
  * Unions this interval with `b`, returning a new interval.
64
69
  * The union operates as a convex hull, i.e. if the two intervals are disjoint, the return value includes
65
70
  * intermediate values between the two intervals.
71
+ * @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
72
+ * @privateRemarks Move to ISerializableInterval after deprecation period
66
73
  */
67
74
  union(b: IInterval): IInterval;
68
75
  }
@@ -152,12 +159,16 @@ export interface ISerializedInterval {
152
159
  /**
153
160
  * @legacy
154
161
  * @alpha
162
+ * @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
163
+ * @privateRemarks Remove from external exports, and replace usages of IInterval with this interface after deprecation period
155
164
  */
156
165
  export interface ISerializableInterval extends IInterval {
157
166
  /** Serializable bag of properties associated with the interval. */
158
167
  properties: PropertySet;
159
168
 
160
- /***/
169
+ /**
170
+ * @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
171
+ */
161
172
  serialize(): ISerializedInterval;
162
173
 
163
174
  /**
@@ -38,6 +38,7 @@ import { v4 as uuid } from "uuid";
38
38
  import { computeStickinessFromSide } from "../intervalCollection.js";
39
39
 
40
40
  import {
41
+ // eslint-disable-next-line import/no-deprecated
41
42
  ISerializableInterval,
42
43
  ISerializedInterval,
43
44
  IntervalStickiness,
@@ -128,6 +129,7 @@ export function getSerializedProperties(
128
129
  * @alpha
129
130
  * @legacy
130
131
  */
132
+ // eslint-disable-next-line import/no-deprecated
131
133
  export interface SequenceInterval extends ISerializableInterval {
132
134
  readonly start: LocalReferencePosition;
133
135
  /**
@@ -140,8 +142,12 @@ export interface SequenceInterval extends ISerializableInterval {
140
142
  readonly endSide: Side;
141
143
  readonly stickiness: IntervalStickiness;
142
144
 
145
+ /** Serializable bag of properties associated with the interval. */
146
+ properties: PropertySet;
147
+
143
148
  /**
144
149
  * @returns a new interval object with identical semantics.
150
+ * @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
145
151
  */
146
152
  clone(): SequenceInterval;
147
153
  /**
@@ -166,6 +172,7 @@ export interface SequenceInterval extends ISerializableInterval {
166
172
  compareEnd(b: SequenceInterval): number;
167
173
  /**
168
174
  * Modifies one or more of the endpoints of this interval, returning a new interval representing the result.
175
+ * @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
169
176
  */
170
177
  modify(
171
178
  label: string,
@@ -184,11 +191,13 @@ export interface SequenceInterval extends ISerializableInterval {
184
191
  * Unions this interval with `b`, returning a new interval.
185
192
  * The union operates as a convex hull, i.e. if the two intervals are disjoint, the return value includes
186
193
  * intermediate values between the two intervals.
194
+ * @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
187
195
  */
188
196
  union(b: SequenceInterval): SequenceInterval;
189
197
 
190
198
  /**
191
199
  * Subscribes to position change events on this interval if there are no current listeners.
200
+ * @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
192
201
  */
193
202
  addPositionChangeListeners(
194
203
  beforePositionChange: () => void,
@@ -197,6 +206,7 @@ export interface SequenceInterval extends ISerializableInterval {
197
206
 
198
207
  /**
199
208
  * Removes the currently subscribed position change listeners.
209
+ * @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
200
210
  */
201
211
  removePositionChangeListeners(): void;
202
212
 
@@ -204,9 +214,17 @@ export interface SequenceInterval extends ISerializableInterval {
204
214
  * @returns whether this interval overlaps two numerical positions.
205
215
  */
206
216
  overlapsPos(bstart: number, bend: number): boolean;
217
+
218
+ /**
219
+ * Gets the id associated with this interval.
220
+ * When the interval is used as part of an interval collection, this id can be used to modify or remove the
221
+ * interval.
222
+ */
223
+ getIntervalId(): string;
207
224
  }
208
225
 
209
- export class SequenceIntervalClass implements SequenceInterval {
226
+ // eslint-disable-next-line import/no-deprecated
227
+ export class SequenceIntervalClass implements SequenceInterval, ISerializableInterval {
210
228
  readonly #props: {
211
229
  propertyManager?: PropertiesManager;
212
230
  properties: PropertySet;
@@ -438,7 +456,7 @@ export class SequenceIntervalClass implements SequenceInterval {
438
456
  /**
439
457
  * {@inheritDoc IInterval.union}
440
458
  */
441
- public union(b: SequenceInterval) {
459
+ public union(b: SequenceIntervalClass) {
442
460
  const newStart = minReferencePosition(this.start, b.start);
443
461
  const newEnd = maxReferencePosition(this.end, b.end);
444
462
 
@@ -571,7 +589,7 @@ export class SequenceIntervalClass implements SequenceInterval {
571
589
 
572
590
  export function createPositionReferenceFromSegoff(
573
591
  client: Client,
574
- segoff: { segment: ISegment | undefined; offset: number | undefined } | "start" | "end",
592
+ segoff: { segment: ISegment; offset: number } | undefined | "start" | "end",
575
593
  refType: ReferenceType,
576
594
  op?: ISequencedDocumentMessage,
577
595
  localSeq?: number,
@@ -591,7 +609,7 @@ export function createPositionReferenceFromSegoff(
591
609
  );
592
610
  }
593
611
 
594
- if (segoff.segment) {
612
+ if (segoff?.segment) {
595
613
  const ref = client.createLocalReferencePosition(
596
614
  segoff.segment,
597
615
  segoff.offset,
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/sequence";
9
- export const pkgVersion = "2.41.0";
9
+ export const pkgVersion = "2.43.0-343119";
@@ -398,12 +398,13 @@ function getSlidePosition(
398
398
  lref: LocalReferencePosition,
399
399
  pos: number,
400
400
  ): number {
401
- const slide = getSlideToSegoff(
402
- { segment: lref.getSegment(), offset: undefined },
403
- lref.slidingPreference,
404
- );
405
- return slide?.segment !== undefined &&
406
- slide.offset !== undefined &&
401
+ const segment = lref.getSegment();
402
+ const offset = lref.getOffset();
403
+ const slide =
404
+ segment === undefined
405
+ ? undefined
406
+ : getSlideToSegoff({ segment, offset }, lref.slidingPreference);
407
+ return slide !== undefined &&
407
408
  string.getPosition(slide.segment) !== -1 &&
408
409
  (pos < 0 || pos >= string.getLength())
409
410
  ? string.getPosition(slide.segment) + slide.offset
package/src/sequence.ts CHANGED
@@ -71,10 +71,7 @@ import Deque from "double-ended-queue";
71
71
 
72
72
  import { type ISequenceIntervalCollection } from "./intervalCollection.js";
73
73
  import { IMapOperation, IntervalCollectionMap } from "./intervalCollectionMap.js";
74
- import {
75
- IMapMessageLocalMetadata,
76
- type SequenceOptions,
77
- } from "./intervalCollectionMapInterfaces.js";
74
+ import { type SequenceOptions } from "./intervalCollectionMapInterfaces.js";
78
75
  import {
79
76
  SequenceDeltaEvent,
80
77
  SequenceDeltaEventClass,
@@ -586,7 +583,9 @@ export abstract class SharedSegmentSequence<T extends ISegment>
586
583
  segment: T | undefined;
587
584
  offset: number | undefined;
588
585
  } {
589
- return this.client.getContainingSegment<T>(pos);
586
+ return (
587
+ this.client.getContainingSegment<T>(pos) ?? { segment: undefined, offset: undefined }
588
+ );
590
589
  }
591
590
 
592
591
  public getLength(): number {
@@ -776,26 +775,25 @@ export abstract class SharedSegmentSequence<T extends ISegment>
776
775
  /**
777
776
  * {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitCore}
778
777
  */
779
- protected reSubmitCore(content: any, localOpMetadata: unknown) {
778
+ protected reSubmitCore(content: any, localOpMetadata: unknown, squash: boolean = false) {
780
779
  const originalRefSeq = this.inFlightRefSeqs.shift();
781
780
  assert(
782
781
  originalRefSeq !== undefined,
783
782
  0x8bb /* Expected a recorded refSeq when resubmitting an op */,
784
783
  );
785
784
  this.useResubmitRefSeq(originalRefSeq, () => {
786
- if (
787
- !this.intervalCollections.tryResubmitMessage(
788
- content,
789
- localOpMetadata as IMapMessageLocalMetadata,
790
- )
791
- ) {
785
+ if (!this.intervalCollections.tryResubmitMessage(content, localOpMetadata)) {
792
786
  this.submitSequenceMessage(
793
- this.client.regeneratePendingOp(content as IMergeTreeOp, localOpMetadata),
787
+ this.client.regeneratePendingOp(content as IMergeTreeOp, localOpMetadata, squash),
794
788
  );
795
789
  }
796
790
  });
797
791
  }
798
792
 
793
+ protected reSubmitSquashed(content: unknown, localOpMetadata: unknown): void {
794
+ this.reSubmitCore(content, localOpMetadata, true);
795
+ }
796
+
799
797
  /**
800
798
  * Revert an op
801
799
  */