@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.
- package/CHANGELOG.md +4 -0
- package/api-report/sequence.legacy.alpha.api.md +13 -5
- package/dist/intervalCollection.d.ts +14 -19
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +113 -128
- package/dist/intervalCollection.js.map +1 -1
- package/dist/intervalCollectionMap.d.ts +3 -3
- package/dist/intervalCollectionMap.d.ts.map +1 -1
- package/dist/intervalCollectionMap.js.map +1 -1
- package/dist/intervalCollectionMapInterfaces.d.ts +22 -4
- package/dist/intervalCollectionMapInterfaces.d.ts.map +1 -1
- package/dist/intervalCollectionMapInterfaces.js.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +4 -4
- package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
- package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/dist/intervals/intervalUtils.d.ts +12 -1
- package/dist/intervals/intervalUtils.d.ts.map +1 -1
- package/dist/intervals/intervalUtils.js.map +1 -1
- package/dist/intervals/sequenceInterval.d.ts +18 -5
- package/dist/intervals/sequenceInterval.d.ts.map +1 -1
- package/dist/intervals/sequenceInterval.js +2 -1
- package/dist/intervals/sequenceInterval.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/revertibles.d.ts.map +1 -1
- package/dist/revertibles.js +6 -3
- package/dist/revertibles.js.map +1 -1
- package/dist/sequence.d.ts +2 -1
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +6 -3
- package/dist/sequence.js.map +1 -1
- package/lib/intervalCollection.d.ts +14 -19
- package/lib/intervalCollection.d.ts.map +1 -1
- package/lib/intervalCollection.js +114 -129
- package/lib/intervalCollection.js.map +1 -1
- package/lib/intervalCollectionMap.d.ts +3 -3
- package/lib/intervalCollectionMap.d.ts.map +1 -1
- package/lib/intervalCollectionMap.js.map +1 -1
- package/lib/intervalCollectionMapInterfaces.d.ts +22 -4
- package/lib/intervalCollectionMapInterfaces.d.ts.map +1 -1
- package/lib/intervalCollectionMapInterfaces.js.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts +4 -4
- package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.js +1 -1
- package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
- package/lib/intervals/intervalUtils.d.ts +12 -1
- package/lib/intervals/intervalUtils.d.ts.map +1 -1
- package/lib/intervals/intervalUtils.js.map +1 -1
- package/lib/intervals/sequenceInterval.d.ts +18 -5
- package/lib/intervals/sequenceInterval.d.ts.map +1 -1
- package/lib/intervals/sequenceInterval.js +2 -1
- package/lib/intervals/sequenceInterval.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/revertibles.d.ts.map +1 -1
- package/lib/revertibles.js +6 -3
- package/lib/revertibles.js.map +1 -1
- package/lib/sequence.d.ts +2 -1
- package/lib/sequence.d.ts.map +1 -1
- package/lib/sequence.js +6 -3
- package/lib/sequence.js.map +1 -1
- package/package.json +17 -17
- package/src/intervalCollection.ts +191 -195
- package/src/intervalCollectionMap.ts +4 -11
- package/src/intervalCollectionMapInterfaces.ts +25 -5
- package/src/intervalIndex/overlappingIntervalsIndex.ts +15 -11
- package/src/intervals/intervalUtils.ts +12 -1
- package/src/intervals/sequenceInterval.ts +22 -4
- package/src/packageVersion.ts +1 -1
- package/src/revertibles.ts +7 -6
- package/src/sequence.ts +11 -13
|
@@ -6,7 +6,7 @@ import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
|
6
6
|
import { IEvent } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
8
8
|
import { Client, LocalReferencePosition, PropertySet, Side, SequencePlace } from "@fluidframework/merge-tree/internal";
|
|
9
|
-
import {
|
|
9
|
+
import { SequenceOptions, type IIntervalCollectionTypeOperationValue, type IntervalAddLocalMetadata, type IntervalChangeLocalMetadata } from "./intervalCollectionMapInterfaces.js";
|
|
10
10
|
import { type IEndpointIndex, type IIdIntervalIndex, type ISequenceOverlappingIntervalsIndex, type SequenceIntervalIndex } from "./intervalIndex/index.js";
|
|
11
11
|
import { CompressedSerializedInterval, ISerializedInterval, IntervalStickiness, SequenceInterval, SequenceIntervalClass, SerializedIntervalDelta } from "./intervals/index.js";
|
|
12
12
|
export type ISerializedIntervalCollectionV1 = ISerializedInterval[];
|
|
@@ -241,6 +241,9 @@ export interface ISequenceIntervalCollection extends TypedEventEmitter<ISequence
|
|
|
241
241
|
end?: SequencePlace;
|
|
242
242
|
props?: PropertySet;
|
|
243
243
|
}): SequenceInterval | undefined;
|
|
244
|
+
/**
|
|
245
|
+
* @deprecated This api is not meant or necessary for external consumption and will be removed in subsequent release
|
|
246
|
+
*/
|
|
244
247
|
attachDeserializer(onDeserialize: DeserializeCallback): void;
|
|
245
248
|
/**
|
|
246
249
|
* @returns an iterator over all intervals in this collection.
|
|
@@ -316,18 +319,15 @@ export interface ISequenceIntervalCollection extends TypedEventEmitter<ISequence
|
|
|
316
319
|
* {@inheritdoc IIntervalCollection}
|
|
317
320
|
*/
|
|
318
321
|
export declare class IntervalCollection extends TypedEventEmitter<ISequenceIntervalCollectionEvents> implements ISequenceIntervalCollection {
|
|
319
|
-
private readonly submitDelta;
|
|
320
322
|
private readonly options;
|
|
321
323
|
private savedSerializedIntervals?;
|
|
322
324
|
private localCollection;
|
|
323
325
|
private onDeserialize;
|
|
324
326
|
private client;
|
|
325
|
-
private readonly
|
|
326
|
-
private readonly localSeqToRebasedInterval;
|
|
327
|
-
private readonly pendingChangesStart;
|
|
328
|
-
private readonly pendingChangesEnd;
|
|
327
|
+
private readonly pending;
|
|
329
328
|
get attached(): boolean;
|
|
330
|
-
|
|
329
|
+
private readonly submitDelta;
|
|
330
|
+
constructor(submitDelta: (op: IIntervalCollectionTypeOperationValue, md: unknown) => void, serializedIntervals: ISerializedIntervalCollectionV1 | ISerializedIntervalCollectionV2, options?: Partial<SequenceOptions>);
|
|
331
331
|
/**
|
|
332
332
|
* {@inheritdoc IIntervalCollection.attachIndex}
|
|
333
333
|
*/
|
|
@@ -336,9 +336,9 @@ export declare class IntervalCollection extends TypedEventEmitter<ISequenceInter
|
|
|
336
336
|
* {@inheritdoc IIntervalCollection.detachIndex}
|
|
337
337
|
*/
|
|
338
338
|
detachIndex(index: SequenceIntervalIndex): boolean;
|
|
339
|
-
rollback(op: IIntervalCollectionTypeOperationValue,
|
|
340
|
-
process(op: IIntervalCollectionTypeOperationValue, local: boolean, message: ISequencedDocumentMessage,
|
|
341
|
-
resubmitMessage(op: IIntervalCollectionTypeOperationValue,
|
|
339
|
+
rollback(op: IIntervalCollectionTypeOperationValue, maybeMetadata: unknown): void;
|
|
340
|
+
process(op: IIntervalCollectionTypeOperationValue, local: boolean, message: ISequencedDocumentMessage, maybeMetadata: unknown): void;
|
|
341
|
+
resubmitMessage(op: IIntervalCollectionTypeOperationValue, maybeMetadata: unknown): void;
|
|
342
342
|
applyStashedOp(op: IIntervalCollectionTypeOperationValue): void;
|
|
343
343
|
private rebasePositionWithSegmentSlide;
|
|
344
344
|
private computeRebasedPositions;
|
|
@@ -378,13 +378,8 @@ export declare class IntervalCollection extends TypedEventEmitter<ISequenceInter
|
|
|
378
378
|
rollback?: boolean;
|
|
379
379
|
}): SequenceIntervalClass | undefined;
|
|
380
380
|
private get isCollaborating();
|
|
381
|
-
private
|
|
382
|
-
|
|
383
|
-
private removePendingChange;
|
|
384
|
-
private removePendingChangeHelper;
|
|
385
|
-
private hasPendingChangeStart;
|
|
386
|
-
private hasPendingChangeEnd;
|
|
387
|
-
ackChange(serializedInterval: SerializedIntervalDelta, local: boolean, op: ISequencedDocumentMessage, localOpMetadata: IMapMessageLocalMetadata | undefined): void;
|
|
381
|
+
private hasPendingEndpointChanges;
|
|
382
|
+
ackChange(serializedInterval: SerializedIntervalDelta, local: boolean, op: ISequencedDocumentMessage): void;
|
|
388
383
|
/**
|
|
389
384
|
* {@inheritdoc IIntervalCollection.attachDeserializer}
|
|
390
385
|
*/
|
|
@@ -395,10 +390,10 @@ export declare class IntervalCollection extends TypedEventEmitter<ISequenceInter
|
|
|
395
390
|
* to a range that no longer exists, and the interval was unable to slide.
|
|
396
391
|
*
|
|
397
392
|
*/
|
|
398
|
-
rebaseLocalInterval(
|
|
393
|
+
rebaseLocalInterval(localOpMetadata: IntervalAddLocalMetadata | IntervalChangeLocalMetadata): SerializedIntervalDelta | undefined;
|
|
399
394
|
private getSlideToSegment;
|
|
400
395
|
private ackInterval;
|
|
401
|
-
ackAdd(serializedInterval: ISerializedInterval, local: boolean, op: ISequencedDocumentMessage, localOpMetadata:
|
|
396
|
+
ackAdd(serializedInterval: ISerializedInterval, local: boolean, op: ISequencedDocumentMessage, localOpMetadata: IntervalAddLocalMetadata | undefined): SequenceIntervalClass | undefined;
|
|
402
397
|
ackDelete(serializedInterval: SerializedIntervalDelta, local: boolean, op: ISequencedDocumentMessage): void;
|
|
403
398
|
serializeInternal(version: "1" | "2"): ISerializedIntervalCollectionV1 | ISerializedIntervalCollectionV2;
|
|
404
399
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intervalCollection.d.ts","sourceRoot":"","sources":["../src/intervalCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAEzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EACN,MAAM,EAGN,sBAAsB,EACtB,WAAW,EAMX,IAAI,EACJ,aAAa,
|
|
1
|
+
{"version":3,"file":"intervalCollection.d.ts","sourceRoot":"","sources":["../src/intervalCollection.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/* eslint-disable no-bitwise */
|
|
6
6
|
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
7
7
|
import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
|
|
8
|
-
import { DetachedReferencePosition, ReferenceType, SlidingPreference, getSlideToSegoff, refTypeIncludesFlag, reservedRangeLabelsKey, Side, endpointPosAndSide, createLocalReconnectingPerspective, } from "@fluidframework/merge-tree/internal";
|
|
8
|
+
import { DetachedReferencePosition, ReferenceType, SlidingPreference, getSlideToSegoff, refTypeIncludesFlag, reservedRangeLabelsKey, Side, endpointPosAndSide, createLocalReconnectingPerspective, DoublyLinkedList, } from "@fluidframework/merge-tree/internal";
|
|
9
9
|
import { LoggingError, UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
10
10
|
import { v4 as uuid } from "uuid";
|
|
11
11
|
import { createIdIntervalIndex, EndpointIndex, OverlappingIntervalsIndex, } from "./intervalIndex/index.js";
|
|
@@ -208,6 +208,25 @@ class IntervalCollectionIterator {
|
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
|
+
function removeMetadataFromPendingChanges(localOpMetadataNode) {
|
|
212
|
+
const acked = localOpMetadataNode?.remove()
|
|
213
|
+
?.data;
|
|
214
|
+
assert(acked !== undefined, "local change must exist");
|
|
215
|
+
acked.endpointChangesNode?.remove();
|
|
216
|
+
return acked;
|
|
217
|
+
}
|
|
218
|
+
function clearEmptyPendingEntry(pendingChanges, id) {
|
|
219
|
+
const pending = pendingChanges[id];
|
|
220
|
+
assert(pending !== undefined, "pending must exist for local process");
|
|
221
|
+
if (pending.local.empty) {
|
|
222
|
+
assert(pending.endpointChanges?.empty !== false, "endpointChanges must be empty if not pending changes");
|
|
223
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
224
|
+
delete pendingChanges[id];
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function hasEndpointChanges(serialized) {
|
|
228
|
+
return serialized.start !== undefined && serialized.end !== undefined;
|
|
229
|
+
}
|
|
211
230
|
/**
|
|
212
231
|
* {@inheritdoc IIntervalCollection}
|
|
213
232
|
*/
|
|
@@ -217,12 +236,19 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
217
236
|
}
|
|
218
237
|
constructor(submitDelta, serializedIntervals, options = {}) {
|
|
219
238
|
super();
|
|
220
|
-
this.submitDelta = submitDelta;
|
|
221
239
|
this.options = options;
|
|
222
|
-
this.
|
|
223
|
-
this.
|
|
224
|
-
|
|
225
|
-
|
|
240
|
+
this.pending = {};
|
|
241
|
+
this.submitDelta = (op, md) => {
|
|
242
|
+
const { id } = getSerializedProperties(op.value);
|
|
243
|
+
const pending = (this.pending[id] ??= {
|
|
244
|
+
local: new DoublyLinkedList(),
|
|
245
|
+
});
|
|
246
|
+
if (md.type === "add" || (md.type === "change" && hasEndpointChanges(op.value))) {
|
|
247
|
+
const endpointChanges = (pending.endpointChanges ??= new DoublyLinkedList());
|
|
248
|
+
md.endpointChangesNode = endpointChanges.push(md).last;
|
|
249
|
+
}
|
|
250
|
+
submitDelta(op, pending.local.push(md).last);
|
|
251
|
+
};
|
|
226
252
|
this.savedSerializedIntervals = Array.isArray(serializedIntervals)
|
|
227
253
|
? serializedIntervals
|
|
228
254
|
: serializedIntervals.intervals.map((i) => decompressInterval(i, serializedIntervals.label));
|
|
@@ -255,11 +281,12 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
255
281
|
}
|
|
256
282
|
return true;
|
|
257
283
|
}
|
|
258
|
-
rollback(op,
|
|
259
|
-
const
|
|
284
|
+
rollback(op, maybeMetadata) {
|
|
285
|
+
const localOpMetadata = removeMetadataFromPendingChanges(maybeMetadata);
|
|
286
|
+
const { value } = op;
|
|
260
287
|
const { id, properties } = getSerializedProperties(value);
|
|
261
|
-
const {
|
|
262
|
-
switch (
|
|
288
|
+
const { type } = localOpMetadata;
|
|
289
|
+
switch (type) {
|
|
263
290
|
case "add": {
|
|
264
291
|
const interval = this.getIntervalById(id);
|
|
265
292
|
if (interval) {
|
|
@@ -268,8 +295,8 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
268
295
|
break;
|
|
269
296
|
}
|
|
270
297
|
case "change": {
|
|
271
|
-
|
|
272
|
-
const endpointsChanged = value
|
|
298
|
+
const { previous } = localOpMetadata;
|
|
299
|
+
const endpointsChanged = hasEndpointChanges(value);
|
|
273
300
|
const start = endpointsChanged
|
|
274
301
|
? toOptionalSequencePlace(previous.start, previous.startSide)
|
|
275
302
|
: undefined;
|
|
@@ -282,14 +309,10 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
282
309
|
props: Object.keys(properties).length > 0 ? properties : undefined,
|
|
283
310
|
rollback: true,
|
|
284
311
|
});
|
|
285
|
-
this.localSeqToSerializedInterval.delete(localSeq);
|
|
286
|
-
if (endpointsChanged) {
|
|
287
|
-
this.removePendingChange(value);
|
|
288
|
-
}
|
|
289
312
|
break;
|
|
290
313
|
}
|
|
291
314
|
case "delete": {
|
|
292
|
-
|
|
315
|
+
const { previous } = localOpMetadata;
|
|
293
316
|
this.add({
|
|
294
317
|
id,
|
|
295
318
|
start: toSequencePlace(previous.start, previous.startSide),
|
|
@@ -300,14 +323,22 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
300
323
|
break;
|
|
301
324
|
}
|
|
302
325
|
default:
|
|
303
|
-
unreachableCase(
|
|
326
|
+
unreachableCase(type);
|
|
304
327
|
}
|
|
328
|
+
clearEmptyPendingEntry(this.pending, id);
|
|
305
329
|
}
|
|
306
|
-
process(op, local, message,
|
|
330
|
+
process(op, local, message, maybeMetadata) {
|
|
331
|
+
const localOpMetadata = local
|
|
332
|
+
? removeMetadataFromPendingChanges(maybeMetadata)
|
|
333
|
+
: undefined;
|
|
307
334
|
const { opName, value } = op;
|
|
335
|
+
assert((local === false && localOpMetadata === undefined) || opName === localOpMetadata?.type, "must be same type");
|
|
308
336
|
switch (opName) {
|
|
309
337
|
case "add": {
|
|
310
|
-
this.ackAdd(value, local, message,
|
|
338
|
+
this.ackAdd(value, local, message,
|
|
339
|
+
// this cast is safe because of the above assert which
|
|
340
|
+
// validates the op and metadata types match for local changes
|
|
341
|
+
localOpMetadata);
|
|
311
342
|
break;
|
|
312
343
|
}
|
|
313
344
|
case "delete": {
|
|
@@ -315,19 +346,27 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
315
346
|
break;
|
|
316
347
|
}
|
|
317
348
|
case "change": {
|
|
318
|
-
this.ackChange(value, local, message
|
|
349
|
+
this.ackChange(value, local, message);
|
|
319
350
|
break;
|
|
320
351
|
}
|
|
321
352
|
default:
|
|
322
353
|
unreachableCase(opName);
|
|
323
354
|
}
|
|
355
|
+
if (local) {
|
|
356
|
+
const { id } = getSerializedProperties(value);
|
|
357
|
+
clearEmptyPendingEntry(this.pending, id);
|
|
358
|
+
}
|
|
324
359
|
}
|
|
325
|
-
resubmitMessage(op,
|
|
360
|
+
resubmitMessage(op, maybeMetadata) {
|
|
326
361
|
const { opName, value } = op;
|
|
327
|
-
const
|
|
328
|
-
const rebasedValue =
|
|
362
|
+
const localOpMetadata = removeMetadataFromPendingChanges(maybeMetadata);
|
|
363
|
+
const rebasedValue = localOpMetadata.endpointChangesNode === undefined
|
|
364
|
+
? value
|
|
365
|
+
: this.rebaseLocalInterval(localOpMetadata);
|
|
329
366
|
if (rebasedValue === undefined) {
|
|
330
|
-
|
|
367
|
+
const { id } = getSerializedProperties(value);
|
|
368
|
+
clearEmptyPendingEntry(this.pending, id);
|
|
369
|
+
return;
|
|
331
370
|
}
|
|
332
371
|
this.submitDelta({ opName, value: rebasedValue }, localOpMetadata);
|
|
333
372
|
}
|
|
@@ -372,21 +411,20 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
372
411
|
const { segment, offset } = this.client.getContainingSegment(pos, {
|
|
373
412
|
referenceSequenceNumber: seqNumberFrom,
|
|
374
413
|
clientId: this.client.getLongClientId(clientId),
|
|
375
|
-
}, localSeq);
|
|
414
|
+
}, localSeq) ?? {};
|
|
376
415
|
// if segment is undefined, it slid off the string
|
|
377
|
-
assert(segment !== undefined, 0x54e /* No segment found */);
|
|
378
|
-
const segoff = getSlideToSegoff({ segment, offset }, undefined, createLocalReconnectingPerspective(this.client.getCurrentSeq(), clientId, localSeq), this.options.mergeTreeReferencesCanSlideToEndpoint)
|
|
416
|
+
assert(segment !== undefined && offset !== undefined, 0x54e /* No segment found */);
|
|
417
|
+
const segoff = getSlideToSegoff({ segment, offset }, undefined, createLocalReconnectingPerspective(this.client.getCurrentSeq(), clientId, localSeq), this.options.mergeTreeReferencesCanSlideToEndpoint);
|
|
379
418
|
// case happens when rebasing op, but concurrently entire string has been deleted
|
|
380
|
-
if (segoff
|
|
419
|
+
if (segoff?.segment === undefined || segoff.offset === undefined) {
|
|
381
420
|
return DetachedReferencePosition;
|
|
382
421
|
}
|
|
383
422
|
assert(offset !== undefined && 0 <= offset && offset < segment.cachedLength, 0x54f /* Invalid offset */);
|
|
384
423
|
return this.client.findReconnectionPosition(segoff.segment, localSeq) + segoff.offset;
|
|
385
424
|
}
|
|
386
|
-
computeRebasedPositions(
|
|
425
|
+
computeRebasedPositions(localOpMetadata) {
|
|
387
426
|
assert(this.client !== undefined, 0x550 /* Client should be defined when computing rebased position */);
|
|
388
|
-
const original =
|
|
389
|
-
assert(original !== undefined, 0x551 /* Failed to store pending serialized interval info for this localSeq. */);
|
|
427
|
+
const { localSeq, original } = localOpMetadata;
|
|
390
428
|
const rebased = { ...original };
|
|
391
429
|
const { start, end, sequenceNumber } = original;
|
|
392
430
|
if (start !== undefined) {
|
|
@@ -408,8 +446,12 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
408
446
|
this.client = client;
|
|
409
447
|
if (client) {
|
|
410
448
|
client.on("normalize", () => {
|
|
411
|
-
for (const
|
|
412
|
-
|
|
449
|
+
for (const pending of Object.values(this.pending)) {
|
|
450
|
+
if (pending?.endpointChanges !== undefined) {
|
|
451
|
+
for (const local of pending.endpointChanges) {
|
|
452
|
+
local.data.rebased = this.computeRebasedPositions(local.data);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
413
455
|
}
|
|
414
456
|
});
|
|
415
457
|
}
|
|
@@ -480,7 +522,8 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
480
522
|
startSide !== undefined &&
|
|
481
523
|
endSide !== undefined, 0x793 /* start and end cannot be undefined because they were not passed in as undefined */);
|
|
482
524
|
this.assertStickinessEnabled(start, end);
|
|
483
|
-
const
|
|
525
|
+
const intervalId = id ?? uuid();
|
|
526
|
+
const interval = this.localCollection.addInterval(intervalId, toSequencePlace(startPos, startSide), toSequencePlace(endPos, endSide), props, undefined, rollback);
|
|
484
527
|
if (interval) {
|
|
485
528
|
if (!this.isCollaborating) {
|
|
486
529
|
setSlideOnRemove(interval.start);
|
|
@@ -489,12 +532,13 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
489
532
|
const serializedInterval = interval.serialize();
|
|
490
533
|
const localSeq = this.getNextLocalSeq();
|
|
491
534
|
if (this.isCollaborating && rollback !== true) {
|
|
492
|
-
this.localSeqToSerializedInterval.set(localSeq, serializedInterval);
|
|
493
535
|
this.submitDelta({
|
|
494
536
|
opName: "add",
|
|
495
537
|
value: serializedInterval,
|
|
496
538
|
}, {
|
|
539
|
+
type: "add",
|
|
497
540
|
localSeq,
|
|
541
|
+
original: serializedInterval,
|
|
498
542
|
});
|
|
499
543
|
}
|
|
500
544
|
}
|
|
@@ -510,12 +554,14 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
510
554
|
if (interval) {
|
|
511
555
|
// Local ops get submitted to the server. Remote ops have the deserializer run.
|
|
512
556
|
if (local && rollback !== true) {
|
|
557
|
+
const value = interval.serialize();
|
|
513
558
|
this.submitDelta({
|
|
514
559
|
opName: "delete",
|
|
515
|
-
value
|
|
560
|
+
value,
|
|
516
561
|
}, {
|
|
562
|
+
type: "delete",
|
|
517
563
|
localSeq: this.getNextLocalSeq(),
|
|
518
|
-
previous:
|
|
564
|
+
previous: value,
|
|
519
565
|
});
|
|
520
566
|
}
|
|
521
567
|
else {
|
|
@@ -578,15 +624,16 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
578
624
|
// Emit a property bag containing the ID and the other (if any) properties changed
|
|
579
625
|
const serializedInterval = (newInterval ?? interval).serializeDelta({ props, includeEndpoints: changeEndpoints });
|
|
580
626
|
const localSeq = this.getNextLocalSeq();
|
|
581
|
-
|
|
582
|
-
|
|
627
|
+
const metadata = {
|
|
628
|
+
type: "change",
|
|
629
|
+
localSeq,
|
|
630
|
+
previous: interval.serialize(),
|
|
631
|
+
original: serializedInterval,
|
|
632
|
+
};
|
|
583
633
|
this.submitDelta({
|
|
584
634
|
opName: "change",
|
|
585
635
|
value: serializedInterval,
|
|
586
|
-
},
|
|
587
|
-
localSeq,
|
|
588
|
-
previous: interval.serialize(),
|
|
589
|
-
});
|
|
636
|
+
}, metadata);
|
|
590
637
|
}
|
|
591
638
|
if (deltaProps !== undefined) {
|
|
592
639
|
this.emit("propertyChanged", interval, deltaProps, true, undefined);
|
|
@@ -605,66 +652,13 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
605
652
|
get isCollaborating() {
|
|
606
653
|
return this.client?.getCollabWindow().collaborating ?? false;
|
|
607
654
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
return;
|
|
611
|
-
}
|
|
612
|
-
if (serializedInterval.start !== undefined) {
|
|
613
|
-
this.addPendingChangeHelper(id, this.pendingChangesStart, serializedInterval);
|
|
614
|
-
}
|
|
615
|
-
if (serializedInterval.end !== undefined) {
|
|
616
|
-
this.addPendingChangeHelper(id, this.pendingChangesEnd, serializedInterval);
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
addPendingChangeHelper(id, pendingChanges, serializedInterval) {
|
|
620
|
-
let entries = pendingChanges.get(id);
|
|
621
|
-
if (!entries) {
|
|
622
|
-
entries = [];
|
|
623
|
-
pendingChanges.set(id, entries);
|
|
624
|
-
}
|
|
625
|
-
entries.push(serializedInterval);
|
|
626
|
-
}
|
|
627
|
-
removePendingChange(serializedInterval) {
|
|
628
|
-
// Change ops always have an ID.
|
|
629
|
-
const { id } = getSerializedProperties(serializedInterval);
|
|
630
|
-
if (serializedInterval.start !== undefined) {
|
|
631
|
-
this.removePendingChangeHelper(id, this.pendingChangesStart, serializedInterval);
|
|
632
|
-
}
|
|
633
|
-
if (serializedInterval.end !== undefined) {
|
|
634
|
-
this.removePendingChangeHelper(id, this.pendingChangesEnd, serializedInterval);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
removePendingChangeHelper(id, pendingChanges, serializedInterval) {
|
|
638
|
-
const entries = pendingChanges.get(id);
|
|
639
|
-
if (entries) {
|
|
640
|
-
const pendingChange = entries.shift();
|
|
641
|
-
if (entries.length === 0) {
|
|
642
|
-
pendingChanges.delete(id);
|
|
643
|
-
}
|
|
644
|
-
if (pendingChange?.start !== serializedInterval.start ||
|
|
645
|
-
pendingChange?.end !== serializedInterval.end) {
|
|
646
|
-
throw new LoggingError("Mismatch in pending changes");
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
hasPendingChangeStart(id) {
|
|
651
|
-
const entries = this.pendingChangesStart.get(id);
|
|
652
|
-
return entries && entries.length !== 0;
|
|
653
|
-
}
|
|
654
|
-
hasPendingChangeEnd(id) {
|
|
655
|
-
const entries = this.pendingChangesEnd.get(id);
|
|
656
|
-
return entries && entries.length !== 0;
|
|
655
|
+
hasPendingEndpointChanges(id) {
|
|
656
|
+
return this.pending[id]?.endpointChanges?.empty === false;
|
|
657
657
|
}
|
|
658
|
-
ackChange(serializedInterval, local, op
|
|
658
|
+
ackChange(serializedInterval, local, op) {
|
|
659
659
|
if (!this.localCollection) {
|
|
660
660
|
throw new LoggingError("Attach must be called before accessing intervals");
|
|
661
661
|
}
|
|
662
|
-
if (local) {
|
|
663
|
-
assert(localOpMetadata !== undefined, 0x552 /* op metadata should be defined for local op */);
|
|
664
|
-
this.localSeqToSerializedInterval.delete(localOpMetadata?.localSeq);
|
|
665
|
-
// This is an ack from the server. Remove the pending change.
|
|
666
|
-
this.removePendingChange(serializedInterval);
|
|
667
|
-
}
|
|
668
662
|
// Note that the ID is in the property bag only to allow us to find the interval.
|
|
669
663
|
// This API cannot change the ID, and writing to the ID property will result in an exception. So we
|
|
670
664
|
// strip it out of the properties here.
|
|
@@ -685,10 +679,8 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
685
679
|
let start;
|
|
686
680
|
let end;
|
|
687
681
|
// Track pending start/end independently of one another.
|
|
688
|
-
if (!this.
|
|
682
|
+
if (!this.hasPendingEndpointChanges(id)) {
|
|
689
683
|
start = serializedInterval.start;
|
|
690
|
-
}
|
|
691
|
-
if (!this.hasPendingChangeEnd(id)) {
|
|
692
684
|
end = serializedInterval.end;
|
|
693
685
|
}
|
|
694
686
|
let newInterval = interval;
|
|
@@ -733,17 +725,20 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
733
725
|
* to a range that no longer exists, and the interval was unable to slide.
|
|
734
726
|
*
|
|
735
727
|
*/
|
|
736
|
-
rebaseLocalInterval(
|
|
728
|
+
rebaseLocalInterval(localOpMetadata) {
|
|
729
|
+
const original = localOpMetadata.original;
|
|
737
730
|
if (!this.client) {
|
|
738
731
|
// If there's no associated mergeTree client, the originally submitted op is still correct.
|
|
739
|
-
return
|
|
732
|
+
return original;
|
|
740
733
|
}
|
|
741
734
|
if (!this.attached) {
|
|
742
735
|
throw new LoggingError("attachSequence must be called");
|
|
743
736
|
}
|
|
744
|
-
const {
|
|
745
|
-
const {
|
|
746
|
-
const {
|
|
737
|
+
const { localSeq } = localOpMetadata;
|
|
738
|
+
const { intervalType, properties, stickiness, startSide, endSide } = original;
|
|
739
|
+
const { id } = getSerializedProperties(original);
|
|
740
|
+
const { start: startRebased, end: endRebased } = (localOpMetadata.rebased ??=
|
|
741
|
+
this.computeRebasedPositions(localOpMetadata));
|
|
747
742
|
const localInterval = this.localCollection?.idIntervalIndex.getIntervalById(id);
|
|
748
743
|
const rebased = {
|
|
749
744
|
start: startRebased,
|
|
@@ -755,12 +750,6 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
755
750
|
startSide,
|
|
756
751
|
endSide,
|
|
757
752
|
};
|
|
758
|
-
if (opName === "change" &&
|
|
759
|
-
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- ?? is not logically equivalent when .hasPendingChangeStart returns false.
|
|
760
|
-
(this.hasPendingChangeStart(id) || this.hasPendingChangeEnd(id))) {
|
|
761
|
-
this.removePendingChange(serializedInterval);
|
|
762
|
-
this.addPendingChange(id, rebased);
|
|
763
|
-
}
|
|
764
753
|
// if the interval slid off the string, rebase the op to be a noop and delete the interval.
|
|
765
754
|
if (!this.options.mergeTreeReferencesCanSlideToEndpoint &&
|
|
766
755
|
(startRebased === DetachedReferencePosition || endRebased === DetachedReferencePosition)) {
|
|
@@ -780,18 +769,18 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
780
769
|
if (!this.client) {
|
|
781
770
|
throw new LoggingError("client does not exist");
|
|
782
771
|
}
|
|
772
|
+
const segment = lref.getSegment();
|
|
773
|
+
if (segment === undefined) {
|
|
774
|
+
return undefined;
|
|
775
|
+
}
|
|
783
776
|
const segoff = {
|
|
784
|
-
segment
|
|
777
|
+
segment,
|
|
785
778
|
offset: lref.getOffset(),
|
|
786
779
|
};
|
|
787
|
-
if (segoff.segment
|
|
780
|
+
if (segoff.segment.localRefs?.has(lref) !== true) {
|
|
788
781
|
return undefined;
|
|
789
782
|
}
|
|
790
|
-
|
|
791
|
-
const value = segoff.segment === newSegoff.segment && segoff.offset === newSegoff.offset
|
|
792
|
-
? undefined
|
|
793
|
-
: newSegoff;
|
|
794
|
-
return value;
|
|
783
|
+
return getSlideToSegoff(segoff, slidingPreference, undefined, this.options.mergeTreeReferencesCanSlideToEndpoint);
|
|
795
784
|
}
|
|
796
785
|
ackInterval(interval, op) {
|
|
797
786
|
if (!refTypeIncludesFlag(interval.start, ReferenceType.StayOnRemove) &&
|
|
@@ -801,16 +790,13 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
801
790
|
const newStart = this.getSlideToSegment(interval.start, startReferenceSlidingPreference(interval.stickiness));
|
|
802
791
|
const newEnd = this.getSlideToSegment(interval.end, endReferenceSlidingPreference(interval.stickiness));
|
|
803
792
|
const id = interval.getIntervalId();
|
|
804
|
-
const
|
|
805
|
-
|
|
806
|
-
if (!hasPendingStartChange) {
|
|
793
|
+
const hasPendingChange = this.hasPendingEndpointChanges(id);
|
|
794
|
+
if (!hasPendingChange) {
|
|
807
795
|
setSlideOnRemove(interval.start);
|
|
808
|
-
}
|
|
809
|
-
if (!hasPendingEndChange) {
|
|
810
796
|
setSlideOnRemove(interval.end);
|
|
811
797
|
}
|
|
812
|
-
const needsStartUpdate = newStart !==
|
|
813
|
-
const needsEndUpdate = newEnd !==
|
|
798
|
+
const needsStartUpdate = newStart?.segment !== interval.start.getSegment() && !hasPendingChange;
|
|
799
|
+
const needsEndUpdate = newEnd?.segment !== interval.end.getSegment() && !hasPendingChange;
|
|
814
800
|
if (needsStartUpdate || needsEndUpdate) {
|
|
815
801
|
if (!this.localCollection) {
|
|
816
802
|
throw new LoggingError("Attach must be called before accessing intervals");
|
|
@@ -856,7 +842,6 @@ export class IntervalCollection extends TypedEventEmitter {
|
|
|
856
842
|
const { id, properties } = getSerializedProperties(serializedInterval);
|
|
857
843
|
if (local) {
|
|
858
844
|
assert(localOpMetadata !== undefined, 0x553 /* op metadata should be defined for local op */);
|
|
859
|
-
this.localSeqToSerializedInterval.delete(localOpMetadata.localSeq);
|
|
860
845
|
const localInterval = this.getIntervalById(id);
|
|
861
846
|
if (localInterval) {
|
|
862
847
|
this.ackInterval(localInterval, op);
|