@fluidframework/legacy-dds 2.52.0 → 2.53.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.
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { assert } from "@fluidframework/core-utils/internal";
5
+ import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
6
6
  import { FileMode, MessageType, TreeEntry } from "@fluidframework/driver-definitions/internal";
7
7
  import { convertToSummaryTreeWithStats } from "@fluidframework/runtime-utils/internal";
8
8
  import { SharedObject } from "@fluidframework/shared-object-base/internal";
@@ -352,78 +352,25 @@ export class SharedArrayClass extends SharedObject {
352
352
  // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
353
353
  if (message.type === MessageType.Operation) {
354
354
  const op = message.contents;
355
- const opEntry = this.getEntryForId(op.entryId);
356
355
  switch (op.type) {
357
356
  case OperationType.insertEntry: {
358
357
  this.handleInsertOp(op.entryId, op.insertAfterEntryId, local, op.value);
359
358
  break;
360
359
  }
361
360
  case OperationType.deleteEntry: {
362
- if (local) {
363
- // Decrementing local pending counter as op is already applied to local state
364
- opEntry.isLocalPendingDelete -= 1;
365
- }
366
- else {
367
- // If local pending, then ignore else apply the remote op
368
- if (!this.isLocalPending(op.entryId, "isLocalPendingDelete")) {
369
- // last element in skip list is the most recent and live entry, so marking it deleted
370
- this.getLiveEntry(op.entryId).isDeleted = true;
371
- }
372
- }
361
+ this.handleDeleteOp(op, local);
373
362
  break;
374
363
  }
375
364
  case OperationType.moveEntry: {
376
- this.handleInsertOp(op.changedToEntryId, op.insertAfterEntryId, local, opEntry.value);
377
- if (local) {
378
- // decrement the local pending move op as its already applied to local state
379
- opEntry.isLocalPendingMove -= 1;
380
- }
381
- else {
382
- const newElementEntryId = op.changedToEntryId;
383
- const newElement = this.getEntryForId(newElementEntryId);
384
- // If local pending then simply mark the new location dead as finally the local op will win
385
- if (this.isLocalPending(op.entryId, "isLocalPendingDelete") ||
386
- this.isLocalPending(op.entryId, "isLocalPendingMove")) {
387
- this.updateDeadEntry(op.entryId, newElementEntryId);
388
- }
389
- else {
390
- // move the element
391
- const liveEntry = this.getLiveEntry(op.entryId);
392
- const isDeleted = liveEntry.isDeleted;
393
- this.updateLiveEntry(liveEntry.entryId, newElementEntryId);
394
- // mark newly added element as deleted if existing live element was already deleted
395
- if (isDeleted) {
396
- newElement.isDeleted = isDeleted;
397
- }
398
- }
399
- }
365
+ this.handleMoveOp(op, local);
400
366
  break;
401
367
  }
402
368
  case OperationType.toggle: {
403
- if (local) {
404
- // decrement the local pending delete op as its already applied to local state
405
- if (opEntry.isLocalPendingDelete) {
406
- opEntry.isLocalPendingDelete -= 1;
407
- }
408
- }
409
- else {
410
- if (!this.isLocalPending(op.entryId, "isLocalPendingDelete")) {
411
- this.getLiveEntry(op.entryId).isDeleted = op.isDeleted;
412
- }
413
- }
369
+ this.handleToggleOp(op, local);
414
370
  break;
415
371
  }
416
372
  case OperationType.toggleMove: {
417
- if (local) {
418
- // decrement the local pending move op as its already applied to local state
419
- if (opEntry.isLocalPendingMove) {
420
- opEntry.isLocalPendingMove -= 1;
421
- }
422
- }
423
- else if (!this.isLocalPending(op.entryId, "isLocalPendingDelete") &&
424
- !this.isLocalPending(op.entryId, "isLocalPendingMove")) {
425
- this.updateLiveEntry(this.getLiveEntry(op.entryId).entryId, op.entryId);
426
- }
373
+ this.handleToggleMoveOp(op, local);
427
374
  break;
428
375
  }
429
376
  default: {
@@ -435,6 +382,88 @@ export class SharedArrayClass extends SharedObject {
435
382
  }
436
383
  }
437
384
  }
385
+ handleInsertOp(entryId, insertAfterEntryId, local, value) {
386
+ let index = 0;
387
+ if (local) {
388
+ this.getEntryForId(entryId).isAckPending = false;
389
+ }
390
+ else {
391
+ if (insertAfterEntryId !== undefined) {
392
+ index = this.findIndexOfEntryId(insertAfterEntryId) + 1;
393
+ }
394
+ const newEntry = this.createNewEntry(entryId, value);
395
+ newEntry.isAckPending = false;
396
+ this.addEntry(this.getInternalInsertIndexByIgnoringLocalPendingInserts(index), newEntry);
397
+ }
398
+ }
399
+ handleDeleteOp(op, local) {
400
+ const opEntry = this.getEntryForId(op.entryId);
401
+ if (local) {
402
+ // Decrementing local pending counter as op is already applied to local state
403
+ opEntry.isLocalPendingDelete -= 1;
404
+ }
405
+ else {
406
+ // If local pending, then ignore else apply the remote op
407
+ if (!this.isLocalPending(op.entryId, "isLocalPendingDelete")) {
408
+ // last element in skip list is the most recent and live entry, so marking it deleted
409
+ this.getLiveEntry(op.entryId).isDeleted = true;
410
+ }
411
+ }
412
+ }
413
+ handleMoveOp(op, local) {
414
+ const opEntry = this.getEntryForId(op.entryId);
415
+ this.handleInsertOp(op.changedToEntryId, op.insertAfterEntryId, local, opEntry.value);
416
+ if (local) {
417
+ // decrement the local pending move op as its already applied to local state
418
+ opEntry.isLocalPendingMove -= 1;
419
+ }
420
+ else {
421
+ const newElementEntryId = op.changedToEntryId;
422
+ const newElement = this.getEntryForId(newElementEntryId);
423
+ // If local pending then simply mark the new location dead as finally the local op will win
424
+ if (this.isLocalPending(op.entryId, "isLocalPendingDelete") ||
425
+ this.isLocalPending(op.entryId, "isLocalPendingMove")) {
426
+ this.updateDeadEntry(op.entryId, newElementEntryId);
427
+ }
428
+ else {
429
+ // move the element
430
+ const liveEntry = this.getLiveEntry(op.entryId);
431
+ const isDeleted = liveEntry.isDeleted;
432
+ this.updateLiveEntry(liveEntry.entryId, newElementEntryId);
433
+ // mark newly added element as deleted if existing live element was already deleted
434
+ if (isDeleted) {
435
+ newElement.isDeleted = isDeleted;
436
+ }
437
+ }
438
+ }
439
+ }
440
+ handleToggleOp(op, local) {
441
+ const opEntry = this.getEntryForId(op.entryId);
442
+ if (local) {
443
+ // decrement the local pending delete op as its already applied to local state
444
+ if (opEntry.isLocalPendingDelete) {
445
+ opEntry.isLocalPendingDelete -= 1;
446
+ }
447
+ }
448
+ else {
449
+ if (!this.isLocalPending(op.entryId, "isLocalPendingDelete")) {
450
+ this.getLiveEntry(op.entryId).isDeleted = op.isDeleted;
451
+ }
452
+ }
453
+ }
454
+ handleToggleMoveOp(op, local) {
455
+ const opEntry = this.getEntryForId(op.entryId);
456
+ if (local) {
457
+ // decrement the local pending move op as its already applied to local state
458
+ if (opEntry.isLocalPendingMove) {
459
+ opEntry.isLocalPendingMove -= 1;
460
+ }
461
+ }
462
+ else if (!this.isLocalPending(op.entryId, "isLocalPendingDelete") &&
463
+ !this.isLocalPending(op.entryId, "isLocalPendingMove")) {
464
+ this.updateLiveEntry(this.getLiveEntry(op.entryId).entryId, op.entryId);
465
+ }
466
+ }
438
467
  findInternalIndex(countEntries) {
439
468
  if (countEntries < 0) {
440
469
  throw new Error("Input count is zero");
@@ -546,20 +575,6 @@ export class SharedArrayClass extends SharedObject {
546
575
  }
547
576
  return localOpsIterator;
548
577
  }
549
- handleInsertOp(entryId, insertAfterEntryId, local, value) {
550
- let index = 0;
551
- if (local) {
552
- this.getEntryForId(entryId).isAckPending = false;
553
- }
554
- else {
555
- if (insertAfterEntryId !== undefined) {
556
- index = this.findIndexOfEntryId(insertAfterEntryId) + 1;
557
- }
558
- const newEntry = this.createNewEntry(entryId, value);
559
- newEntry.isAckPending = false;
560
- this.addEntry(this.getInternalInsertIndexByIgnoringLocalPendingInserts(index), newEntry);
561
- }
562
- }
563
578
  findIndexOfEntryId(entryId) {
564
579
  for (let index = 0; index < this.sharedArray.length; index = index + 1) {
565
580
  if (this.sharedArray[index]?.entryId === entryId) {
@@ -641,8 +656,35 @@ export class SharedArrayClass extends SharedObject {
641
656
  deadEntry.prevEntryId = existingEntryId;
642
657
  deadEntry.isDeleted = true;
643
658
  }
644
- applyStashedOp(_content) {
645
- throw new Error("Not implemented");
659
+ applyStashedOp(content) {
660
+ const op = content;
661
+ switch (op.type) {
662
+ case OperationType.insertEntry: {
663
+ this.handleInsertOp(op.entryId, op.insertAfterEntryId, false, // treat it as remote op
664
+ op.value);
665
+ break;
666
+ }
667
+ case OperationType.deleteEntry: {
668
+ this.handleDeleteOp(op, false /* local - treat as remote op */);
669
+ break;
670
+ }
671
+ case OperationType.moveEntry: {
672
+ this.handleMoveOp(op, false /* local - treat as remote op */);
673
+ break;
674
+ }
675
+ case OperationType.toggle: {
676
+ this.handleToggleOp(op, false /* local - treat as remote op */);
677
+ break;
678
+ }
679
+ case OperationType.toggleMove: {
680
+ this.handleToggleMoveOp(op, false /* local - treat as remote op */);
681
+ break;
682
+ }
683
+ default: {
684
+ unreachableCase(op);
685
+ }
686
+ }
687
+ this.submitLocalMessage(op);
646
688
  }
647
689
  }
648
690
  //# sourceMappingURL=sharedArray.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sharedArray.js","sourceRoot":"","sources":["../../src/array/sharedArray.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tSerializable,\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelFactory,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport type {\n\tISequencedDocumentMessage,\n\tITree,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { FileMode, MessageType, TreeEntry } from \"@fluidframework/driver-definitions/internal\";\nimport type { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions/internal\";\nimport { convertToSummaryTreeWithStats } from \"@fluidframework/runtime-utils/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport { SharedObject } from \"@fluidframework/shared-object-base/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport type {\n\tISharedArrayEvents,\n\tISharedArray,\n\tISharedArrayRevertible,\n\tSerializableTypeForSharedArray,\n\tSharedArrayEntry,\n\tSnapshotFormat,\n\tSharedArrayEntryCore,\n} from \"./interfaces.js\";\nimport { SharedArrayFactory } from \"./sharedArrayFactory.js\";\nimport type {\n\tISharedArrayOperation,\n\tIDeleteOperation,\n\tIMoveOperation,\n\tIToggleMoveOperation,\n\tIToggleOperation,\n} from \"./sharedArrayOperations.js\";\nimport { OperationType } from \"./sharedArrayOperations.js\";\nimport { SharedArrayRevertible } from \"./sharedArrayRevertible.js\";\n\nconst snapshotFileName = \"header\";\n\n/**\n * Represents a shared array that allows communication between distributed clients.\n *\n * @internal\n */\nexport class SharedArrayClass<T extends SerializableTypeForSharedArray>\n\textends SharedObject<ISharedArrayEvents>\n\timplements ISharedArray<T>, ISharedArrayRevertible\n{\n\t/**\n\t * Stores the data held by this shared array.\n\t */\n\tprivate sharedArray: SharedArrayEntry<T>[];\n\n\t/**\n\t * Stores a map of entryid to entries of the sharedArray. This is meant of search optimizations and\n\t * so shouldn't be snapshotted.\n\t * Note: This map needs to be updated only when the sharedArray is being deserialized and when new entries are\n\t * being added. New entries are added upon insert ops and the second leg of the move op.\n\t * As we don't delete the entries once created, deletion or move to another position needs no special\n\t * handling for this data structure\n\t */\n\tprivate readonly idToEntryMap: Map<string, SharedArrayEntry<T>>;\n\n\t/**\n\t * Create a new shared array\n\t *\n\t * @param runtime - data store runtime the new shared array belongs to\n\t * @param id - optional name of the shared array\n\t * @returns newly create shared array (but not attached yet)\n\t */\n\tpublic static create<T extends SerializableTypeForSharedArray>(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid?: string,\n\t): SharedArrayClass<T> {\n\t\treturn runtime.createChannel(id, SharedArrayFactory.Type) as SharedArrayClass<T>;\n\t}\n\n\t/**\n\t * Get a factory for SharedArray to register with the data store.\n\t *\n\t * @returns a factory that creates and load SharedArray\n\t */\n\tpublic static getFactory<T extends SerializableTypeForSharedArray>(): IChannelFactory {\n\t\treturn new SharedArrayFactory<T>();\n\t}\n\n\t/**\n\t * Constructs a new shared array. If the object is non-local an id and service interfaces will\n\t * be provided\n\t *\n\t * @param id - optional name of the shared array\n\t * @param runtime - data store runtime the shared array belongs to\n\t * @param attributes - represents the attributes of a channel/DDS.\n\t */\n\tpublic constructor(\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t) {\n\t\tsuper(id, runtime, attributes, \"loop_sharedArray_\" /* telemetryContextPrefix */);\n\t\tthis.sharedArray = [];\n\t\tthis.idToEntryMap = new Map<string, SharedArrayEntry<T>>();\n\t}\n\n\t/**\n\t * Method that returns the ordered list of the items held in the DDS at this point in time.\n\t * Note: This is only a snapshot of the array\n\t */\n\tpublic get(): readonly T[] {\n\t\treturn this.sharedArray.filter((item) => !item.isDeleted).map((entry) => entry.value);\n\t}\n\n\tprotected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n\t\t// Deep copy and unset the local flags. Needed when snapshotting is happening for runtime not attached\n\t\tconst dataArrayCopy: SharedArrayEntryCore<T>[] = [];\n\t\tfor (const entry of this.sharedArray) {\n\t\t\tdataArrayCopy.push({\n\t\t\t\tentryId: entry.entryId,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tvalue: JSON.parse(serializer.stringify(entry.value, this.handle)),\n\t\t\t\tisDeleted: entry.isDeleted,\n\t\t\t\tprevEntryId: entry.prevEntryId,\n\t\t\t\tnextEntryId: entry.nextEntryId,\n\t\t\t});\n\t\t}\n\n\t\t// We are snapshotting current client data so autoacking pending local.\n\t\t// Assumption : This should happen only for offline client creating the array. All other scenarios should\n\t\t// get to MSN - where there can be no local pending possible.\n\t\tfor (const entry of this.sharedArray) {\n\t\t\tthis.unsetLocalFlags(entry);\n\t\t}\n\t\tconst contents: SnapshotFormat<SharedArrayEntryCore<T>> = {\n\t\t\tdataArray: dataArrayCopy,\n\t\t};\n\t\tconst tree: ITree = {\n\t\t\tentries: [\n\t\t\t\t{\n\t\t\t\t\tmode: FileMode.File,\n\t\t\t\t\tpath: snapshotFileName,\n\t\t\t\t\ttype: TreeEntry[TreeEntry.Blob],\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tcontents: serializer.stringify(contents, this.handle),\n\t\t\t\t\t\t// eslint-disable-next-line unicorn/text-encoding-identifier-case\n\t\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\t\tconst summaryTreeWithStats = convertToSummaryTreeWithStats(tree);\n\n\t\treturn summaryTreeWithStats;\n\t}\n\n\tpublic insertBulkAfter<TWrite>(\n\t\tref: T | undefined,\n\t\tvalues: (Serializable<TWrite> & T)[],\n\t): void {\n\t\tlet itemIndex: number = 0;\n\n\t\tif (ref !== undefined) {\n\t\t\tfor (itemIndex = this.sharedArray.length - 1; itemIndex > 0; itemIndex -= 1) {\n\t\t\t\tconst item = this.sharedArray[itemIndex];\n\t\t\t\tif (item && !item.isDeleted && item.value === ref) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Add one since we're inserting it after this rowId. If rowId is not found, we will get -1, which after\n\t\t\t// adding one, will be 0, which will place the new rows at the right place too\n\t\t\titemIndex += 1;\n\t\t}\n\n\t\t// Insert new elements\n\t\tfor (const value of values) {\n\t\t\tthis.insertCore(itemIndex, value);\n\t\t\titemIndex += 1;\n\t\t}\n\t}\n\n\tpublic insert<TWrite>(index: number, value: Serializable<TWrite> & T): void {\n\t\tif (index < 0) {\n\t\t\tthrow new Error(\"Invalid input: Insertion index provided is less than 0.\");\n\t\t}\n\t\tthis.insertCore(this.findInternalInsertionIndex(index), value);\n\t}\n\n\tprivate insertCore<TWrite>(indexInternal: number, value: Serializable<TWrite> & T): void {\n\t\tconst insertAfterEntryId =\n\t\t\tindexInternal >= 1 ? this.sharedArray[indexInternal - 1]?.entryId : undefined;\n\t\tconst newEntryId = this.createAddEntry(indexInternal, value);\n\n\t\tconst op = {\n\t\t\ttype: OperationType.insertEntry,\n\t\t\tentryId: newEntryId,\n\t\t\tvalue,\n\t\t\tinsertAfterEntryId,\n\t\t};\n\n\t\tthis.emitValueChangedEvent(op, true /* isLocal */);\n\t\tthis.emitRevertibleEvent(op);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.submitLocalMessage(op);\n\t}\n\n\tpublic delete(index: number): void {\n\t\tif (index < 0) {\n\t\t\tthrow new Error(\"Invalid input: Deletion index provided is less than 0.\");\n\t\t}\n\n\t\tconst indexInternal: number = this.findInternalDeletionIndex(index);\n\n\t\tconst entry = this.sharedArray[indexInternal];\n\t\tassert(entry !== undefined, 0xb90 /* Invalid index */);\n\t\tconst entryId = entry.entryId;\n\t\tthis.deleteCore(indexInternal);\n\n\t\tconst op: IDeleteOperation = {\n\t\t\ttype: OperationType.deleteEntry,\n\t\t\tentryId,\n\t\t};\n\t\tthis.emitValueChangedEvent(op, true /* isLocal */);\n\t\tthis.emitRevertibleEvent(op);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.submitLocalMessage(op);\n\t}\n\n\tpublic rearrangeToFront(values: T[]): void {\n\t\tfor (let toIndex = 0; toIndex < values.length; toIndex += 1) {\n\t\t\tconst value = values[toIndex];\n\t\t\t// Can skip searching first <toIndex> indices, as they contain elements we already moved.\n\t\t\tfor (let fromIndex = toIndex; fromIndex < this.sharedArray.length; fromIndex += 1) {\n\t\t\t\tconst item = this.sharedArray[fromIndex];\n\t\t\t\tassert(item !== undefined, 0xb91 /* Invalid index */);\n\t\t\t\tif (item.value !== value) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\t!item.isDeleted &&\n\t\t\t\t\t// Moving to and from the same index makes no sense, so noOp\n\t\t\t\t\tfromIndex !== toIndex &&\n\t\t\t\t\t// Moving the same entry from current location to its immediate next makes no sense so noOp\n\t\t\t\t\ttoIndex !== fromIndex + 1\n\t\t\t\t) {\n\t\t\t\t\tthis.moveCore(fromIndex, toIndex);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Moves the DDS entry from one index to another\n\t *\n\t * @param fromIndex - User index of the element to be moved\n\t * @param toIndex - User index to which the element should move to\n\t */\n\tpublic move(fromIndex: number, toIndex: number): void {\n\t\tif (fromIndex < 0) {\n\t\t\tthrow new Error(\"Invalid input: fromIndex value provided is less than 0\");\n\t\t}\n\n\t\tif (toIndex < 0) {\n\t\t\tthrow new Error(\"Invalid input: toIndex value provided is less than 0\");\n\t\t}\n\n\t\tif (\n\t\t\t// Moving to and from the same index makes no sense, so noOp\n\t\t\tfromIndex === toIndex ||\n\t\t\t// Moving the same entry from current location to its immediate next makes no sense so noOp\n\t\t\ttoIndex === fromIndex + 1\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tconst fromIndexInternal: number = this.findInternalDeletionIndex(fromIndex);\n\t\tconst toIndexInternal: number = this.findInternalInsertionIndex(toIndex);\n\n\t\tthis.moveCore(fromIndexInternal, toIndexInternal);\n\t}\n\n\tprivate moveCore(fromIndexInternal: number, toIndexInternal: number): void {\n\t\tconst insertAfterEntryId =\n\t\t\ttoIndexInternal >= 1 ? this.sharedArray[toIndexInternal - 1]?.entryId : undefined;\n\t\tconst entryId = this.sharedArray[fromIndexInternal]?.entryId;\n\t\tassert(entryId !== undefined, 0xb92 /* Invalid index */);\n\t\tconst changedToEntryId = this.createMoveEntry(fromIndexInternal, toIndexInternal);\n\n\t\tconst op: IMoveOperation = {\n\t\t\ttype: OperationType.moveEntry,\n\t\t\tentryId,\n\t\t\tinsertAfterEntryId,\n\t\t\tchangedToEntryId,\n\t\t};\n\t\tthis.emitValueChangedEvent(op, true /* isLocal */);\n\t\tthis.emitRevertibleEvent(op);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.submitLocalMessage(op);\n\t}\n\n\t/**\n\t * Method used to do undo/redo operation for the given entry id. This method is\n\t * used for undo/redo of only insert and delete operations. Move operation is NOT handled\n\t * by this method\n\t *\n\t * @param entryId - Entry Id for which the the undo/redo operation is to be applied\n\t */\n\tpublic toggle(entryId: string): void {\n\t\tconst liveEntry = this.getLiveEntry(entryId);\n\t\tconst isDeleted = !liveEntry.isDeleted;\n\n\t\t// Adding local pending counter\n\t\tthis.getEntryForId(entryId).isLocalPendingDelete += 1;\n\n\t\t// Toggling the isDeleted flag to undo the last operation for the skip list payload/value\n\t\tliveEntry.isDeleted = isDeleted;\n\n\t\tconst op: IToggleOperation = {\n\t\t\ttype: OperationType.toggle,\n\t\t\tentryId,\n\t\t\tisDeleted,\n\t\t};\n\t\tthis.emitValueChangedEvent(op, true /* isLocal */);\n\t\tthis.emitRevertibleEvent(op);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.submitLocalMessage(op);\n\t}\n\n\t/**\n\t * Method to do undo/redo of move operation. All entries of the same payload/value are stored\n\t * in the same doubly linked skip list. This skip list is updated upon every move by adding the\n\t * new location as a new entry in the skip list and update the isDeleted flag to indicate the new\n\t * entry is the cuurent live location for the user.\n\t *\n\t * @param oldEntryId - EntryId of the last live entry\n\t * @param newEntryId - EntryId of the to be live entry\n\t */\n\tpublic toggleMove(oldEntryId: string, newEntryId: string): void {\n\t\tif (this.getEntryForId(newEntryId).isDeleted) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Adding local pending counter\n\t\tthis.getEntryForId(oldEntryId).isLocalPendingMove += 1;\n\n\t\tthis.updateLiveEntry(newEntryId, oldEntryId);\n\n\t\tconst op: IToggleMoveOperation = {\n\t\t\ttype: OperationType.toggleMove,\n\t\t\tentryId: oldEntryId,\n\t\t\tchangedToEntryId: newEntryId,\n\t\t};\n\t\tthis.emitValueChangedEvent(op, true /* isLocal */);\n\t\tthis.emitRevertibleEvent(op);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.submitLocalMessage(op);\n\t}\n\n\t/**\n\t * Load share array from snapshot\n\t *\n\t * @param storage - the storage to get the snapshot from\n\t * @returns - promise that resolved when the load is completed\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst header = await storage.readBlob(snapshotFileName);\n\t\t// eslint-disable-next-line unicorn/text-encoding-identifier-case\n\t\tconst utf8 = new TextDecoder(\"utf-8\").decode(header);\n\t\t// Note: IFluidSerializer.parse() doesn't guarantee any typing; the explicit typing here is based on this code's\n\t\t// knowledge of what it is deserializing.\n\t\tconst deserializedSharedArray = this.serializer.parse(utf8) as {\n\t\t\tdataArray: SharedArrayEntry<T>[];\n\t\t};\n\t\tthis.sharedArray = deserializedSharedArray.dataArray;\n\t\t// Initializing the idToEntryMap optimizer data set\n\t\tfor (const entry of this.sharedArray) {\n\t\t\tthis.idToEntryMap.set(entry.entryId, entry);\n\t\t\tthis.unsetLocalFlags(entry);\n\t\t}\n\t}\n\n\t/**\n\t * Callback on disconnect\n\t */\n\tprotected onDisconnect(): void {}\n\n\t/**\n\t * Tracks the doubly linked skip list for the given entry to identify local pending counter attribute.\n\t * It signifies if a local pending operation exists for the payload/value being tracked in the skip list\n\t *\n\t * returns true if counterAttribute's count \\> 0\n\t * @param entryId - id for which counter attribute is to be tracked in chian.\n\t * @param counterAttribute - flag or property name from SharedArrayEntry whose counter is to be tracked.\n\t */\n\tprivate isLocalPending(\n\t\tentryId: string,\n\t\tcounterAttribute: keyof SharedArrayEntry<T>,\n\t): boolean {\n\t\tconst getCounterAttributeValue = (\n\t\t\tentry: SharedArrayEntry<T>,\n\t\t\tcounterAttr: keyof SharedArrayEntry<T>,\n\t\t): number => {\n\t\t\treturn entry[counterAttr] as number;\n\t\t};\n\n\t\tconst inputEntry = this.getEntryForId(entryId);\n\t\tlet prevEntryId = inputEntry.prevEntryId;\n\t\tlet nextEntryId = inputEntry.nextEntryId;\n\t\tif (getCounterAttributeValue(inputEntry, counterAttribute) > 0) {\n\t\t\treturn true;\n\t\t}\n\t\t// track back in chain\n\t\twhile (prevEntryId !== undefined && prevEntryId) {\n\t\t\tconst prevEntry = this.getEntryForId(prevEntryId);\n\t\t\tif (getCounterAttributeValue(prevEntry, counterAttribute)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tprevEntryId = prevEntry.prevEntryId;\n\t\t}\n\n\t\t// track forward in the chain\n\t\twhile (nextEntryId !== undefined && nextEntryId) {\n\t\t\tconst nextEntry = this.getEntryForId(nextEntryId);\n\t\t\tif (getCounterAttributeValue(nextEntry, counterAttribute)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tnextEntryId = nextEntry.nextEntryId;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate getEntryForId(entryId: string): SharedArrayEntry<T> {\n\t\treturn this.idToEntryMap.get(entryId) as SharedArrayEntry<T>;\n\t}\n\n\t/**\n\t * Process a shared array operation\n\t *\n\t * @param message - the message to prepare\n\t * @param local - whether the message was sent by the local client\n\t * @param _localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be undefined.\n\t */\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\t_localOpMetadata: unknown,\n\t): void {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison\n\t\tif (message.type === MessageType.Operation) {\n\t\t\tconst op = message.contents as ISharedArrayOperation<T>;\n\t\t\tconst opEntry = this.getEntryForId(op.entryId);\n\n\t\t\tswitch (op.type) {\n\t\t\t\tcase OperationType.insertEntry: {\n\t\t\t\t\tthis.handleInsertOp<SerializableTypeForSharedArray>(\n\t\t\t\t\t\top.entryId,\n\t\t\t\t\t\top.insertAfterEntryId,\n\t\t\t\t\t\tlocal,\n\t\t\t\t\t\top.value,\n\t\t\t\t\t);\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase OperationType.deleteEntry: {\n\t\t\t\t\tif (local) {\n\t\t\t\t\t\t// Decrementing local pending counter as op is already applied to local state\n\t\t\t\t\t\topEntry.isLocalPendingDelete -= 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If local pending, then ignore else apply the remote op\n\t\t\t\t\t\tif (!this.isLocalPending(op.entryId, \"isLocalPendingDelete\")) {\n\t\t\t\t\t\t\t// last element in skip list is the most recent and live entry, so marking it deleted\n\t\t\t\t\t\t\tthis.getLiveEntry(op.entryId).isDeleted = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase OperationType.moveEntry: {\n\t\t\t\t\tthis.handleInsertOp<SerializableTypeForSharedArray>(\n\t\t\t\t\t\top.changedToEntryId,\n\t\t\t\t\t\top.insertAfterEntryId,\n\t\t\t\t\t\tlocal,\n\t\t\t\t\t\topEntry.value,\n\t\t\t\t\t);\n\t\t\t\t\tif (local) {\n\t\t\t\t\t\t// decrement the local pending move op as its already applied to local state\n\t\t\t\t\t\topEntry.isLocalPendingMove -= 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst newElementEntryId = op.changedToEntryId;\n\t\t\t\t\t\tconst newElement = this.getEntryForId(newElementEntryId);\n\t\t\t\t\t\t// If local pending then simply mark the new location dead as finally the local op will win\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.isLocalPending(op.entryId, \"isLocalPendingDelete\") ||\n\t\t\t\t\t\t\tthis.isLocalPending(op.entryId, \"isLocalPendingMove\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.updateDeadEntry(op.entryId, newElementEntryId);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// move the element\n\t\t\t\t\t\t\tconst liveEntry = this.getLiveEntry(op.entryId);\n\t\t\t\t\t\t\tconst isDeleted = liveEntry.isDeleted;\n\t\t\t\t\t\t\tthis.updateLiveEntry(liveEntry.entryId, newElementEntryId);\n\t\t\t\t\t\t\t// mark newly added element as deleted if existing live element was already deleted\n\t\t\t\t\t\t\tif (isDeleted) {\n\t\t\t\t\t\t\t\tnewElement.isDeleted = isDeleted;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase OperationType.toggle: {\n\t\t\t\t\tif (local) {\n\t\t\t\t\t\t// decrement the local pending delete op as its already applied to local state\n\t\t\t\t\t\tif (opEntry.isLocalPendingDelete) {\n\t\t\t\t\t\t\topEntry.isLocalPendingDelete -= 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!this.isLocalPending(op.entryId, \"isLocalPendingDelete\")) {\n\t\t\t\t\t\t\tthis.getLiveEntry(op.entryId).isDeleted = op.isDeleted;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tcase OperationType.toggleMove: {\n\t\t\t\t\tif (local) {\n\t\t\t\t\t\t// decrement the local pending move op as its already applied to local state\n\t\t\t\t\t\tif (opEntry.isLocalPendingMove) {\n\t\t\t\t\t\t\topEntry.isLocalPendingMove -= 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (\n\t\t\t\t\t\t!this.isLocalPending(op.entryId, \"isLocalPendingDelete\") &&\n\t\t\t\t\t\t!this.isLocalPending(op.entryId, \"isLocalPendingMove\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.updateLiveEntry(this.getLiveEntry(op.entryId).entryId, op.entryId);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault: {\n\t\t\t\t\tthrow new Error(\"Unknown operation\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!local) {\n\t\t\t\tthis.emitValueChangedEvent(op, local);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate findInternalIndex(countEntries: number): number {\n\t\tif (countEntries < 0) {\n\t\t\tthrow new Error(\"Input count is zero\");\n\t\t}\n\n\t\tlet countDown = countEntries;\n\t\tlet entriesIterator = 0;\n\t\tfor (; entriesIterator < this.sharedArray.length; entriesIterator = entriesIterator + 1) {\n\t\t\tconst entry = this.sharedArray[entriesIterator];\n\t\t\tassert(entry !== undefined, 0xb93 /* Invalid index */);\n\t\t\tif (entry.isDeleted === false) {\n\t\t\t\tif (countDown === 0) {\n\t\t\t\t\treturn entriesIterator;\n\t\t\t\t}\n\t\t\t\tcountDown = countDown - 1;\n\t\t\t}\n\t\t}\n\t\tthrow new Error(`Count of live entries is less than required`);\n\t}\n\n\tprivate findInternalInsertionIndex(index: number): number {\n\t\treturn index === 0 ? index : this.findInternalIndex(index - 1) + 1;\n\t}\n\n\tprivate findInternalDeletionIndex(index: number): number {\n\t\treturn this.findInternalIndex(index);\n\t}\n\n\tprivate createAddEntry<TWrite>(index: number, value: Serializable<TWrite> & T): string {\n\t\tconst newEntry = this.createNewEntry(uuid(), value);\n\t\tthis.addEntry(index, newEntry);\n\t\treturn newEntry.entryId;\n\t}\n\n\tprivate addEntry(insertIndex: number, newEntry: SharedArrayEntry<T>): void {\n\t\t// in scenario where we populate 100K rows, we insert them all at the end of array.\n\t\t// slicing array is way slower than pushing elements.\n\t\tif (insertIndex === this.sharedArray.length) {\n\t\t\tthis.sharedArray.push(newEntry);\n\t\t} else {\n\t\t\tthis.sharedArray.splice(insertIndex, 0 /* deleteCount */, newEntry);\n\t\t}\n\n\t\t// Updating the idToEntryMap optimizer data set as new entry has been added\n\t\tthis.idToEntryMap.set(newEntry.entryId, newEntry);\n\t}\n\n\tprivate emitValueChangedEvent(op: ISharedArrayOperation, isLocal: boolean): void {\n\t\tthis.emit(\"valueChanged\", op, isLocal, this);\n\t}\n\n\tprivate emitRevertibleEvent(op: ISharedArrayOperation): void {\n\t\tconst revertible = new SharedArrayRevertible(this, op);\n\t\tthis.emit(\"revertible\", revertible);\n\t}\n\n\tprivate deleteCore(index: number): void {\n\t\tconst entry = this.sharedArray[index];\n\t\tassert(entry !== undefined, 0xb94 /* Invalid index */);\n\n\t\tif (entry.isDeleted) {\n\t\t\tthrow new Error(\"Entry already deleted.\");\n\t\t}\n\t\tentry.isDeleted = true;\n\n\t\t// Adding local pending counter\n\t\tentry.isLocalPendingDelete += 1;\n\t}\n\n\tprivate createMoveEntry(oldIndex: number, newIndex: number): string {\n\t\tconst oldEntry = this.sharedArray[oldIndex];\n\t\tassert(oldEntry !== undefined, 0xb95 /* Invalid index */);\n\t\tconst newEntry = this.createNewEntry<SerializableTypeForSharedArray>(\n\t\t\tuuid(),\n\t\t\toldEntry.value,\n\t\t\toldEntry.entryId,\n\t\t);\n\n\t\toldEntry.isDeleted = true;\n\t\toldEntry.nextEntryId = newEntry.entryId;\n\n\t\t// Adding local pending counter\n\t\toldEntry.isLocalPendingMove += 1;\n\n\t\tthis.addEntry(newIndex /* insertIndex */, newEntry);\n\n\t\treturn newEntry.entryId;\n\t}\n\n\t/**\n\t * Creates new entry of type SharedArrayEntry interface.\n\t * @param entryId - id for which new entry is created\n\t * @param value - value for the new entry\n\t * @param prevEntryId - prevEntryId if exists to update the previous pointer of double ended linked list\n\t */\n\tprivate createNewEntry<TWrite>(\n\t\tentryId: string,\n\t\tvalue: Serializable<TWrite> & T,\n\t\tprevEntryId?: string,\n\t): SharedArrayEntry<T> {\n\t\treturn {\n\t\t\tentryId,\n\t\t\tvalue,\n\t\t\tisAckPending: true,\n\t\t\tisDeleted: false,\n\t\t\tprevEntryId,\n\t\t\tnextEntryId: undefined,\n\t\t\tisLocalPendingDelete: 0,\n\t\t\tisLocalPendingMove: 0,\n\t\t};\n\t}\n\n\t/**\n\t * Unsets all local flags used by the DDS. This method can be used after reading from snapshott to ensure\n\t * local flags are initialized for use by the DDS.\n\t * @param entry - Entry for which the local flags have to be cleaned up\n\t */\n\tprivate unsetLocalFlags(entry: SharedArrayEntry<T>): void {\n\t\tentry.isAckPending = false;\n\t\tentry.isLocalPendingDelete = 0;\n\t\tentry.isLocalPendingMove = 0;\n\t}\n\n\t/**\n\t * Returns the index of the first entry starting with startIndex that does not have the isAckPending flag\n\t */\n\tprivate getInternalInsertIndexByIgnoringLocalPendingInserts(startIndex: number): number {\n\t\tlet localOpsIterator = startIndex;\n\t\tfor (\n\t\t\t;\n\t\t\tlocalOpsIterator < this.sharedArray.length;\n\t\t\tlocalOpsIterator = localOpsIterator + 1\n\t\t) {\n\t\t\tconst entry = this.sharedArray[localOpsIterator];\n\t\t\tassert(entry !== undefined, 0xb96 /* Invalid index */);\n\t\t\tif (!entry.isAckPending) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn localOpsIterator;\n\t}\n\n\tprivate handleInsertOp<TWrite>(\n\t\tentryId: string,\n\t\tinsertAfterEntryId: string | undefined,\n\t\tlocal: boolean,\n\t\tvalue: Serializable<TWrite> & T,\n\t): void {\n\t\tlet index = 0;\n\t\tif (local) {\n\t\t\tthis.getEntryForId(entryId).isAckPending = false;\n\t\t} else {\n\t\t\tif (insertAfterEntryId !== undefined) {\n\t\t\t\tindex = this.findIndexOfEntryId(insertAfterEntryId) + 1;\n\t\t\t}\n\t\t\tconst newEntry = this.createNewEntry(entryId, value);\n\t\t\tnewEntry.isAckPending = false;\n\t\t\tthis.addEntry(this.getInternalInsertIndexByIgnoringLocalPendingInserts(index), newEntry);\n\t\t}\n\t}\n\n\tprivate findIndexOfEntryId(entryId: string | undefined): number {\n\t\tfor (let index = 0; index < this.sharedArray.length; index = index + 1) {\n\t\t\tif (this.sharedArray[index]?.entryId === entryId) {\n\t\t\t\treturn index;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\n\tprivate prepareToMakeEntryIdLive(entry: SharedArrayEntry<T>): void {\n\t\tconst prevIndex = this.findIndexOfEntryId(entry.prevEntryId);\n\t\tconst nextIndex = this.findIndexOfEntryId(entry.nextEntryId);\n\t\tif (prevIndex !== -1) {\n\t\t\tconst prevEntry = this.sharedArray[prevIndex];\n\t\t\tassert(prevEntry !== undefined, 0xb97 /* Invalid index */);\n\t\t\tprevEntry.nextEntryId = entry.nextEntryId;\n\t\t}\n\t\tif (nextIndex !== -1) {\n\t\t\tconst nextEntry = this.sharedArray[nextIndex];\n\t\t\tassert(nextEntry !== undefined, 0xb98 /* Invalid index */);\n\t\t\tnextEntry.prevEntryId = entry.prevEntryId;\n\t\t}\n\t\tentry.prevEntryId = undefined;\n\t\tentry.nextEntryId = undefined;\n\t}\n\n\t/**\n\t * Method that returns the live entry.\n\t * The shared array internally can store a skip list of all related entries which got created\n\t * due to move operations for the same payload/value. However, all elements except for one element\n\t * can have isDeleted flag as false indicating this is the live entry for the value.\n\t * Current implementation ensures that the last element in the skip list of entries is the liveEntry/\n\t * last live entry\n\t *\n\t * @param entryId - Entry id of any node in the skip list for the same payload/value\n\t */\n\tprivate getLiveEntry(entryId: string): SharedArrayEntry<T> {\n\t\tlet liveEntry = this.getEntryForId(entryId);\n\t\twhile (liveEntry.nextEntryId !== undefined && liveEntry.nextEntryId) {\n\t\t\tliveEntry = this.getEntryForId(liveEntry.nextEntryId);\n\t\t}\n\t\treturn liveEntry;\n\t}\n\n\t/**\n\t * We track sequence of moves for a entry in the shared array using doubly linked skip list.\n\t * This utility function helps us keep track of the current position of an entry.value by marking the entry\n\t * at previous position deleted and appending the entry at the new position at the end of the double linked\n\t * list for that entry.value.\n\t */\n\tprivate updateLiveEntry(oldLiveEntryEntryId: string, newLiveEntryEntryId: string): void {\n\t\tconst oldLiveEntry = this.getEntryForId(oldLiveEntryEntryId);\n\t\tconst newLiveEntry = this.getEntryForId(newLiveEntryEntryId);\n\t\tif (oldLiveEntryEntryId === newLiveEntryEntryId) {\n\t\t\toldLiveEntry.isDeleted = false;\n\t\t} else {\n\t\t\tthis.prepareToMakeEntryIdLive(newLiveEntry);\n\t\t\t// Make entryId live\n\t\t\toldLiveEntry.nextEntryId = newLiveEntryEntryId;\n\t\t\tnewLiveEntry.prevEntryId = oldLiveEntryEntryId;\n\t\t\tnewLiveEntry.isDeleted = false;\n\t\t\toldLiveEntry.isDeleted = true;\n\t\t}\n\t}\n\n\t/**\n\t * We track sequence of moves for a entry in the shared array using doubly linked skip list.\n\t * This utility function helps to insert the new entry as dead entry and reconnecting the double linked list with\n\t * existingEntry -\\> deadeEntry(appended) -\\> existing chain(if any).\n\t */\n\tprivate updateDeadEntry(existingEntryId: string, deadEntryId: string): void {\n\t\tconst existingEntry = this.getEntryForId(existingEntryId);\n\t\tconst deadEntry = this.getEntryForId(deadEntryId);\n\n\t\t// update dead entry's next to existingEntry's next, if existingEntry's next entry exists.\n\t\t// It can be undefined if the exiting element is the last element (or only element) of chain.\n\t\tif (existingEntry.nextEntryId !== undefined) {\n\t\t\tdeadEntry.nextEntryId = existingEntry.nextEntryId;\n\t\t\tthis.getEntryForId(existingEntry.nextEntryId).prevEntryId = deadEntryId;\n\t\t}\n\n\t\t// update current entry's next pointer to dead entry and vice versa.\n\t\texistingEntry.nextEntryId = deadEntryId;\n\t\tdeadEntry.prevEntryId = existingEntryId;\n\t\tdeadEntry.isDeleted = true;\n\t}\n\n\tprotected applyStashedOp(_content: unknown): void {\n\t\tthrow new Error(\"Not implemented\");\n\t}\n}\n"]}
1
+ {"version":3,"file":"sharedArray.js","sourceRoot":"","sources":["../../src/array/sharedArray.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tSerializable,\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelFactory,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport type {\n\tISequencedDocumentMessage,\n\tITree,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { FileMode, MessageType, TreeEntry } from \"@fluidframework/driver-definitions/internal\";\nimport type { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions/internal\";\nimport { convertToSummaryTreeWithStats } from \"@fluidframework/runtime-utils/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport { SharedObject } from \"@fluidframework/shared-object-base/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport type {\n\tISharedArrayEvents,\n\tISharedArray,\n\tISharedArrayRevertible,\n\tSerializableTypeForSharedArray,\n\tSharedArrayEntry,\n\tSnapshotFormat,\n\tSharedArrayEntryCore,\n} from \"./interfaces.js\";\nimport { SharedArrayFactory } from \"./sharedArrayFactory.js\";\nimport type {\n\tISharedArrayOperation,\n\tIDeleteOperation,\n\tIMoveOperation,\n\tIToggleMoveOperation,\n\tIToggleOperation,\n} from \"./sharedArrayOperations.js\";\nimport { OperationType } from \"./sharedArrayOperations.js\";\nimport { SharedArrayRevertible } from \"./sharedArrayRevertible.js\";\n\nconst snapshotFileName = \"header\";\n\n/**\n * Represents a shared array that allows communication between distributed clients.\n *\n * @internal\n */\nexport class SharedArrayClass<T extends SerializableTypeForSharedArray>\n\textends SharedObject<ISharedArrayEvents>\n\timplements ISharedArray<T>, ISharedArrayRevertible\n{\n\t/**\n\t * Stores the data held by this shared array.\n\t */\n\tprivate sharedArray: SharedArrayEntry<T>[];\n\n\t/**\n\t * Stores a map of entryid to entries of the sharedArray. This is meant of search optimizations and\n\t * so shouldn't be snapshotted.\n\t * Note: This map needs to be updated only when the sharedArray is being deserialized and when new entries are\n\t * being added. New entries are added upon insert ops and the second leg of the move op.\n\t * As we don't delete the entries once created, deletion or move to another position needs no special\n\t * handling for this data structure\n\t */\n\tprivate readonly idToEntryMap: Map<string, SharedArrayEntry<T>>;\n\n\t/**\n\t * Create a new shared array\n\t *\n\t * @param runtime - data store runtime the new shared array belongs to\n\t * @param id - optional name of the shared array\n\t * @returns newly create shared array (but not attached yet)\n\t */\n\tpublic static create<T extends SerializableTypeForSharedArray>(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid?: string,\n\t): SharedArrayClass<T> {\n\t\treturn runtime.createChannel(id, SharedArrayFactory.Type) as SharedArrayClass<T>;\n\t}\n\n\t/**\n\t * Get a factory for SharedArray to register with the data store.\n\t *\n\t * @returns a factory that creates and load SharedArray\n\t */\n\tpublic static getFactory<T extends SerializableTypeForSharedArray>(): IChannelFactory {\n\t\treturn new SharedArrayFactory<T>();\n\t}\n\n\t/**\n\t * Constructs a new shared array. If the object is non-local an id and service interfaces will\n\t * be provided\n\t *\n\t * @param id - optional name of the shared array\n\t * @param runtime - data store runtime the shared array belongs to\n\t * @param attributes - represents the attributes of a channel/DDS.\n\t */\n\tpublic constructor(\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t) {\n\t\tsuper(id, runtime, attributes, \"loop_sharedArray_\" /* telemetryContextPrefix */);\n\t\tthis.sharedArray = [];\n\t\tthis.idToEntryMap = new Map<string, SharedArrayEntry<T>>();\n\t}\n\n\t/**\n\t * Method that returns the ordered list of the items held in the DDS at this point in time.\n\t * Note: This is only a snapshot of the array\n\t */\n\tpublic get(): readonly T[] {\n\t\treturn this.sharedArray.filter((item) => !item.isDeleted).map((entry) => entry.value);\n\t}\n\n\tprotected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n\t\t// Deep copy and unset the local flags. Needed when snapshotting is happening for runtime not attached\n\t\tconst dataArrayCopy: SharedArrayEntryCore<T>[] = [];\n\t\tfor (const entry of this.sharedArray) {\n\t\t\tdataArrayCopy.push({\n\t\t\t\tentryId: entry.entryId,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tvalue: JSON.parse(serializer.stringify(entry.value, this.handle)),\n\t\t\t\tisDeleted: entry.isDeleted,\n\t\t\t\tprevEntryId: entry.prevEntryId,\n\t\t\t\tnextEntryId: entry.nextEntryId,\n\t\t\t});\n\t\t}\n\n\t\t// We are snapshotting current client data so autoacking pending local.\n\t\t// Assumption : This should happen only for offline client creating the array. All other scenarios should\n\t\t// get to MSN - where there can be no local pending possible.\n\t\tfor (const entry of this.sharedArray) {\n\t\t\tthis.unsetLocalFlags(entry);\n\t\t}\n\t\tconst contents: SnapshotFormat<SharedArrayEntryCore<T>> = {\n\t\t\tdataArray: dataArrayCopy,\n\t\t};\n\t\tconst tree: ITree = {\n\t\t\tentries: [\n\t\t\t\t{\n\t\t\t\t\tmode: FileMode.File,\n\t\t\t\t\tpath: snapshotFileName,\n\t\t\t\t\ttype: TreeEntry[TreeEntry.Blob],\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tcontents: serializer.stringify(contents, this.handle),\n\t\t\t\t\t\t// eslint-disable-next-line unicorn/text-encoding-identifier-case\n\t\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\t\tconst summaryTreeWithStats = convertToSummaryTreeWithStats(tree);\n\n\t\treturn summaryTreeWithStats;\n\t}\n\n\tpublic insertBulkAfter<TWrite>(\n\t\tref: T | undefined,\n\t\tvalues: (Serializable<TWrite> & T)[],\n\t): void {\n\t\tlet itemIndex: number = 0;\n\n\t\tif (ref !== undefined) {\n\t\t\tfor (itemIndex = this.sharedArray.length - 1; itemIndex > 0; itemIndex -= 1) {\n\t\t\t\tconst item = this.sharedArray[itemIndex];\n\t\t\t\tif (item && !item.isDeleted && item.value === ref) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Add one since we're inserting it after this rowId. If rowId is not found, we will get -1, which after\n\t\t\t// adding one, will be 0, which will place the new rows at the right place too\n\t\t\titemIndex += 1;\n\t\t}\n\n\t\t// Insert new elements\n\t\tfor (const value of values) {\n\t\t\tthis.insertCore(itemIndex, value);\n\t\t\titemIndex += 1;\n\t\t}\n\t}\n\n\tpublic insert<TWrite>(index: number, value: Serializable<TWrite> & T): void {\n\t\tif (index < 0) {\n\t\t\tthrow new Error(\"Invalid input: Insertion index provided is less than 0.\");\n\t\t}\n\t\tthis.insertCore(this.findInternalInsertionIndex(index), value);\n\t}\n\n\tprivate insertCore<TWrite>(indexInternal: number, value: Serializable<TWrite> & T): void {\n\t\tconst insertAfterEntryId =\n\t\t\tindexInternal >= 1 ? this.sharedArray[indexInternal - 1]?.entryId : undefined;\n\t\tconst newEntryId = this.createAddEntry(indexInternal, value);\n\n\t\tconst op = {\n\t\t\ttype: OperationType.insertEntry,\n\t\t\tentryId: newEntryId,\n\t\t\tvalue,\n\t\t\tinsertAfterEntryId,\n\t\t};\n\n\t\tthis.emitValueChangedEvent(op, true /* isLocal */);\n\t\tthis.emitRevertibleEvent(op);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.submitLocalMessage(op);\n\t}\n\n\tpublic delete(index: number): void {\n\t\tif (index < 0) {\n\t\t\tthrow new Error(\"Invalid input: Deletion index provided is less than 0.\");\n\t\t}\n\n\t\tconst indexInternal: number = this.findInternalDeletionIndex(index);\n\n\t\tconst entry = this.sharedArray[indexInternal];\n\t\tassert(entry !== undefined, 0xb90 /* Invalid index */);\n\t\tconst entryId = entry.entryId;\n\t\tthis.deleteCore(indexInternal);\n\n\t\tconst op: IDeleteOperation = {\n\t\t\ttype: OperationType.deleteEntry,\n\t\t\tentryId,\n\t\t};\n\t\tthis.emitValueChangedEvent(op, true /* isLocal */);\n\t\tthis.emitRevertibleEvent(op);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.submitLocalMessage(op);\n\t}\n\n\tpublic rearrangeToFront(values: T[]): void {\n\t\tfor (let toIndex = 0; toIndex < values.length; toIndex += 1) {\n\t\t\tconst value = values[toIndex];\n\t\t\t// Can skip searching first <toIndex> indices, as they contain elements we already moved.\n\t\t\tfor (let fromIndex = toIndex; fromIndex < this.sharedArray.length; fromIndex += 1) {\n\t\t\t\tconst item = this.sharedArray[fromIndex];\n\t\t\t\tassert(item !== undefined, 0xb91 /* Invalid index */);\n\t\t\t\tif (item.value !== value) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\t!item.isDeleted &&\n\t\t\t\t\t// Moving to and from the same index makes no sense, so noOp\n\t\t\t\t\tfromIndex !== toIndex &&\n\t\t\t\t\t// Moving the same entry from current location to its immediate next makes no sense so noOp\n\t\t\t\t\ttoIndex !== fromIndex + 1\n\t\t\t\t) {\n\t\t\t\t\tthis.moveCore(fromIndex, toIndex);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Moves the DDS entry from one index to another\n\t *\n\t * @param fromIndex - User index of the element to be moved\n\t * @param toIndex - User index to which the element should move to\n\t */\n\tpublic move(fromIndex: number, toIndex: number): void {\n\t\tif (fromIndex < 0) {\n\t\t\tthrow new Error(\"Invalid input: fromIndex value provided is less than 0\");\n\t\t}\n\n\t\tif (toIndex < 0) {\n\t\t\tthrow new Error(\"Invalid input: toIndex value provided is less than 0\");\n\t\t}\n\n\t\tif (\n\t\t\t// Moving to and from the same index makes no sense, so noOp\n\t\t\tfromIndex === toIndex ||\n\t\t\t// Moving the same entry from current location to its immediate next makes no sense so noOp\n\t\t\ttoIndex === fromIndex + 1\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t\tconst fromIndexInternal: number = this.findInternalDeletionIndex(fromIndex);\n\t\tconst toIndexInternal: number = this.findInternalInsertionIndex(toIndex);\n\n\t\tthis.moveCore(fromIndexInternal, toIndexInternal);\n\t}\n\n\tprivate moveCore(fromIndexInternal: number, toIndexInternal: number): void {\n\t\tconst insertAfterEntryId =\n\t\t\ttoIndexInternal >= 1 ? this.sharedArray[toIndexInternal - 1]?.entryId : undefined;\n\t\tconst entryId = this.sharedArray[fromIndexInternal]?.entryId;\n\t\tassert(entryId !== undefined, 0xb92 /* Invalid index */);\n\t\tconst changedToEntryId = this.createMoveEntry(fromIndexInternal, toIndexInternal);\n\n\t\tconst op: IMoveOperation = {\n\t\t\ttype: OperationType.moveEntry,\n\t\t\tentryId,\n\t\t\tinsertAfterEntryId,\n\t\t\tchangedToEntryId,\n\t\t};\n\t\tthis.emitValueChangedEvent(op, true /* isLocal */);\n\t\tthis.emitRevertibleEvent(op);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.submitLocalMessage(op);\n\t}\n\n\t/**\n\t * Method used to do undo/redo operation for the given entry id. This method is\n\t * used for undo/redo of only insert and delete operations. Move operation is NOT handled\n\t * by this method\n\t *\n\t * @param entryId - Entry Id for which the the undo/redo operation is to be applied\n\t */\n\tpublic toggle(entryId: string): void {\n\t\tconst liveEntry = this.getLiveEntry(entryId);\n\t\tconst isDeleted = !liveEntry.isDeleted;\n\n\t\t// Adding local pending counter\n\t\tthis.getEntryForId(entryId).isLocalPendingDelete += 1;\n\n\t\t// Toggling the isDeleted flag to undo the last operation for the skip list payload/value\n\t\tliveEntry.isDeleted = isDeleted;\n\n\t\tconst op: IToggleOperation = {\n\t\t\ttype: OperationType.toggle,\n\t\t\tentryId,\n\t\t\tisDeleted,\n\t\t};\n\t\tthis.emitValueChangedEvent(op, true /* isLocal */);\n\t\tthis.emitRevertibleEvent(op);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.submitLocalMessage(op);\n\t}\n\n\t/**\n\t * Method to do undo/redo of move operation. All entries of the same payload/value are stored\n\t * in the same doubly linked skip list. This skip list is updated upon every move by adding the\n\t * new location as a new entry in the skip list and update the isDeleted flag to indicate the new\n\t * entry is the cuurent live location for the user.\n\t *\n\t * @param oldEntryId - EntryId of the last live entry\n\t * @param newEntryId - EntryId of the to be live entry\n\t */\n\tpublic toggleMove(oldEntryId: string, newEntryId: string): void {\n\t\tif (this.getEntryForId(newEntryId).isDeleted) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Adding local pending counter\n\t\tthis.getEntryForId(oldEntryId).isLocalPendingMove += 1;\n\n\t\tthis.updateLiveEntry(newEntryId, oldEntryId);\n\n\t\tconst op: IToggleMoveOperation = {\n\t\t\ttype: OperationType.toggleMove,\n\t\t\tentryId: oldEntryId,\n\t\t\tchangedToEntryId: newEntryId,\n\t\t};\n\t\tthis.emitValueChangedEvent(op, true /* isLocal */);\n\t\tthis.emitRevertibleEvent(op);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.submitLocalMessage(op);\n\t}\n\n\t/**\n\t * Load share array from snapshot\n\t *\n\t * @param storage - the storage to get the snapshot from\n\t * @returns - promise that resolved when the load is completed\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst header = await storage.readBlob(snapshotFileName);\n\t\t// eslint-disable-next-line unicorn/text-encoding-identifier-case\n\t\tconst utf8 = new TextDecoder(\"utf-8\").decode(header);\n\t\t// Note: IFluidSerializer.parse() doesn't guarantee any typing; the explicit typing here is based on this code's\n\t\t// knowledge of what it is deserializing.\n\t\tconst deserializedSharedArray = this.serializer.parse(utf8) as {\n\t\t\tdataArray: SharedArrayEntry<T>[];\n\t\t};\n\t\tthis.sharedArray = deserializedSharedArray.dataArray;\n\t\t// Initializing the idToEntryMap optimizer data set\n\t\tfor (const entry of this.sharedArray) {\n\t\t\tthis.idToEntryMap.set(entry.entryId, entry);\n\t\t\tthis.unsetLocalFlags(entry);\n\t\t}\n\t}\n\n\t/**\n\t * Callback on disconnect\n\t */\n\tprotected onDisconnect(): void {}\n\n\t/**\n\t * Tracks the doubly linked skip list for the given entry to identify local pending counter attribute.\n\t * It signifies if a local pending operation exists for the payload/value being tracked in the skip list\n\t *\n\t * returns true if counterAttribute's count \\> 0\n\t * @param entryId - id for which counter attribute is to be tracked in chian.\n\t * @param counterAttribute - flag or property name from SharedArrayEntry whose counter is to be tracked.\n\t */\n\tprivate isLocalPending(\n\t\tentryId: string,\n\t\tcounterAttribute: keyof SharedArrayEntry<T>,\n\t): boolean {\n\t\tconst getCounterAttributeValue = (\n\t\t\tentry: SharedArrayEntry<T>,\n\t\t\tcounterAttr: keyof SharedArrayEntry<T>,\n\t\t): number => {\n\t\t\treturn entry[counterAttr] as number;\n\t\t};\n\n\t\tconst inputEntry = this.getEntryForId(entryId);\n\t\tlet prevEntryId = inputEntry.prevEntryId;\n\t\tlet nextEntryId = inputEntry.nextEntryId;\n\t\tif (getCounterAttributeValue(inputEntry, counterAttribute) > 0) {\n\t\t\treturn true;\n\t\t}\n\t\t// track back in chain\n\t\twhile (prevEntryId !== undefined && prevEntryId) {\n\t\t\tconst prevEntry = this.getEntryForId(prevEntryId);\n\t\t\tif (getCounterAttributeValue(prevEntry, counterAttribute)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tprevEntryId = prevEntry.prevEntryId;\n\t\t}\n\n\t\t// track forward in the chain\n\t\twhile (nextEntryId !== undefined && nextEntryId) {\n\t\t\tconst nextEntry = this.getEntryForId(nextEntryId);\n\t\t\tif (getCounterAttributeValue(nextEntry, counterAttribute)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tnextEntryId = nextEntry.nextEntryId;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate getEntryForId(entryId: string): SharedArrayEntry<T> {\n\t\treturn this.idToEntryMap.get(entryId) as SharedArrayEntry<T>;\n\t}\n\n\t/**\n\t * Process a shared array operation\n\t *\n\t * @param message - the message to prepare\n\t * @param local - whether the message was sent by the local client\n\t * @param _localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be undefined.\n\t */\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\t_localOpMetadata: unknown,\n\t): void {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison\n\t\tif (message.type === MessageType.Operation) {\n\t\t\tconst op = message.contents as ISharedArrayOperation<T>;\n\t\t\tswitch (op.type) {\n\t\t\t\tcase OperationType.insertEntry: {\n\t\t\t\t\tthis.handleInsertOp<SerializableTypeForSharedArray>(\n\t\t\t\t\t\top.entryId,\n\t\t\t\t\t\top.insertAfterEntryId,\n\t\t\t\t\t\tlocal,\n\t\t\t\t\t\top.value,\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase OperationType.deleteEntry: {\n\t\t\t\t\tthis.handleDeleteOp(op, local);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase OperationType.moveEntry: {\n\t\t\t\t\tthis.handleMoveOp(op, local);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase OperationType.toggle: {\n\t\t\t\t\tthis.handleToggleOp(op, local);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase OperationType.toggleMove: {\n\t\t\t\t\tthis.handleToggleMoveOp(op, local);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdefault: {\n\t\t\t\t\tthrow new Error(\"Unknown operation\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!local) {\n\t\t\t\tthis.emitValueChangedEvent(op, local);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleInsertOp<TWrite>(\n\t\tentryId: string,\n\t\tinsertAfterEntryId: string | undefined,\n\t\tlocal: boolean,\n\t\tvalue: Serializable<TWrite> & T,\n\t): void {\n\t\tlet index = 0;\n\t\tif (local) {\n\t\t\tthis.getEntryForId(entryId).isAckPending = false;\n\t\t} else {\n\t\t\tif (insertAfterEntryId !== undefined) {\n\t\t\t\tindex = this.findIndexOfEntryId(insertAfterEntryId) + 1;\n\t\t\t}\n\t\t\tconst newEntry = this.createNewEntry(entryId, value);\n\t\t\tnewEntry.isAckPending = false;\n\t\t\tthis.addEntry(this.getInternalInsertIndexByIgnoringLocalPendingInserts(index), newEntry);\n\t\t}\n\t}\n\n\tprivate handleDeleteOp(op: IDeleteOperation, local: boolean): void {\n\t\tconst opEntry = this.getEntryForId(op.entryId);\n\t\tif (local) {\n\t\t\t// Decrementing local pending counter as op is already applied to local state\n\t\t\topEntry.isLocalPendingDelete -= 1;\n\t\t} else {\n\t\t\t// If local pending, then ignore else apply the remote op\n\t\t\tif (!this.isLocalPending(op.entryId, \"isLocalPendingDelete\")) {\n\t\t\t\t// last element in skip list is the most recent and live entry, so marking it deleted\n\t\t\t\tthis.getLiveEntry(op.entryId).isDeleted = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleMoveOp(op: IMoveOperation, local: boolean): void {\n\t\tconst opEntry = this.getEntryForId(op.entryId);\n\t\tthis.handleInsertOp<SerializableTypeForSharedArray>(\n\t\t\top.changedToEntryId,\n\t\t\top.insertAfterEntryId,\n\t\t\tlocal,\n\t\t\topEntry.value,\n\t\t);\n\t\tif (local) {\n\t\t\t// decrement the local pending move op as its already applied to local state\n\t\t\topEntry.isLocalPendingMove -= 1;\n\t\t} else {\n\t\t\tconst newElementEntryId = op.changedToEntryId;\n\t\t\tconst newElement = this.getEntryForId(newElementEntryId);\n\t\t\t// If local pending then simply mark the new location dead as finally the local op will win\n\t\t\tif (\n\t\t\t\tthis.isLocalPending(op.entryId, \"isLocalPendingDelete\") ||\n\t\t\t\tthis.isLocalPending(op.entryId, \"isLocalPendingMove\")\n\t\t\t) {\n\t\t\t\tthis.updateDeadEntry(op.entryId, newElementEntryId);\n\t\t\t} else {\n\t\t\t\t// move the element\n\t\t\t\tconst liveEntry = this.getLiveEntry(op.entryId);\n\t\t\t\tconst isDeleted = liveEntry.isDeleted;\n\t\t\t\tthis.updateLiveEntry(liveEntry.entryId, newElementEntryId);\n\t\t\t\t// mark newly added element as deleted if existing live element was already deleted\n\t\t\t\tif (isDeleted) {\n\t\t\t\t\tnewElement.isDeleted = isDeleted;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleToggleOp(op: IToggleOperation, local: boolean): void {\n\t\tconst opEntry = this.getEntryForId(op.entryId);\n\t\tif (local) {\n\t\t\t// decrement the local pending delete op as its already applied to local state\n\t\t\tif (opEntry.isLocalPendingDelete) {\n\t\t\t\topEntry.isLocalPendingDelete -= 1;\n\t\t\t}\n\t\t} else {\n\t\t\tif (!this.isLocalPending(op.entryId, \"isLocalPendingDelete\")) {\n\t\t\t\tthis.getLiveEntry(op.entryId).isDeleted = op.isDeleted;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleToggleMoveOp(op: IToggleMoveOperation, local: boolean): void {\n\t\tconst opEntry = this.getEntryForId(op.entryId);\n\t\tif (local) {\n\t\t\t// decrement the local pending move op as its already applied to local state\n\t\t\tif (opEntry.isLocalPendingMove) {\n\t\t\t\topEntry.isLocalPendingMove -= 1;\n\t\t\t}\n\t\t} else if (\n\t\t\t!this.isLocalPending(op.entryId, \"isLocalPendingDelete\") &&\n\t\t\t!this.isLocalPending(op.entryId, \"isLocalPendingMove\")\n\t\t) {\n\t\t\tthis.updateLiveEntry(this.getLiveEntry(op.entryId).entryId, op.entryId);\n\t\t}\n\t}\n\n\tprivate findInternalIndex(countEntries: number): number {\n\t\tif (countEntries < 0) {\n\t\t\tthrow new Error(\"Input count is zero\");\n\t\t}\n\n\t\tlet countDown = countEntries;\n\t\tlet entriesIterator = 0;\n\t\tfor (; entriesIterator < this.sharedArray.length; entriesIterator = entriesIterator + 1) {\n\t\t\tconst entry = this.sharedArray[entriesIterator];\n\t\t\tassert(entry !== undefined, 0xb93 /* Invalid index */);\n\t\t\tif (entry.isDeleted === false) {\n\t\t\t\tif (countDown === 0) {\n\t\t\t\t\treturn entriesIterator;\n\t\t\t\t}\n\t\t\t\tcountDown = countDown - 1;\n\t\t\t}\n\t\t}\n\t\tthrow new Error(`Count of live entries is less than required`);\n\t}\n\n\tprivate findInternalInsertionIndex(index: number): number {\n\t\treturn index === 0 ? index : this.findInternalIndex(index - 1) + 1;\n\t}\n\n\tprivate findInternalDeletionIndex(index: number): number {\n\t\treturn this.findInternalIndex(index);\n\t}\n\n\tprivate createAddEntry<TWrite>(index: number, value: Serializable<TWrite> & T): string {\n\t\tconst newEntry = this.createNewEntry(uuid(), value);\n\t\tthis.addEntry(index, newEntry);\n\t\treturn newEntry.entryId;\n\t}\n\n\tprivate addEntry(insertIndex: number, newEntry: SharedArrayEntry<T>): void {\n\t\t// in scenario where we populate 100K rows, we insert them all at the end of array.\n\t\t// slicing array is way slower than pushing elements.\n\t\tif (insertIndex === this.sharedArray.length) {\n\t\t\tthis.sharedArray.push(newEntry);\n\t\t} else {\n\t\t\tthis.sharedArray.splice(insertIndex, 0 /* deleteCount */, newEntry);\n\t\t}\n\n\t\t// Updating the idToEntryMap optimizer data set as new entry has been added\n\t\tthis.idToEntryMap.set(newEntry.entryId, newEntry);\n\t}\n\n\tprivate emitValueChangedEvent(op: ISharedArrayOperation, isLocal: boolean): void {\n\t\tthis.emit(\"valueChanged\", op, isLocal, this);\n\t}\n\n\tprivate emitRevertibleEvent(op: ISharedArrayOperation): void {\n\t\tconst revertible = new SharedArrayRevertible(this, op);\n\t\tthis.emit(\"revertible\", revertible);\n\t}\n\n\tprivate deleteCore(index: number): void {\n\t\tconst entry = this.sharedArray[index];\n\t\tassert(entry !== undefined, 0xb94 /* Invalid index */);\n\n\t\tif (entry.isDeleted) {\n\t\t\tthrow new Error(\"Entry already deleted.\");\n\t\t}\n\t\tentry.isDeleted = true;\n\n\t\t// Adding local pending counter\n\t\tentry.isLocalPendingDelete += 1;\n\t}\n\n\tprivate createMoveEntry(oldIndex: number, newIndex: number): string {\n\t\tconst oldEntry = this.sharedArray[oldIndex];\n\t\tassert(oldEntry !== undefined, 0xb95 /* Invalid index */);\n\t\tconst newEntry = this.createNewEntry<SerializableTypeForSharedArray>(\n\t\t\tuuid(),\n\t\t\toldEntry.value,\n\t\t\toldEntry.entryId,\n\t\t);\n\n\t\toldEntry.isDeleted = true;\n\t\toldEntry.nextEntryId = newEntry.entryId;\n\n\t\t// Adding local pending counter\n\t\toldEntry.isLocalPendingMove += 1;\n\n\t\tthis.addEntry(newIndex /* insertIndex */, newEntry);\n\n\t\treturn newEntry.entryId;\n\t}\n\n\t/**\n\t * Creates new entry of type SharedArrayEntry interface.\n\t * @param entryId - id for which new entry is created\n\t * @param value - value for the new entry\n\t * @param prevEntryId - prevEntryId if exists to update the previous pointer of double ended linked list\n\t */\n\tprivate createNewEntry<TWrite>(\n\t\tentryId: string,\n\t\tvalue: Serializable<TWrite> & T,\n\t\tprevEntryId?: string,\n\t): SharedArrayEntry<T> {\n\t\treturn {\n\t\t\tentryId,\n\t\t\tvalue,\n\t\t\tisAckPending: true,\n\t\t\tisDeleted: false,\n\t\t\tprevEntryId,\n\t\t\tnextEntryId: undefined,\n\t\t\tisLocalPendingDelete: 0,\n\t\t\tisLocalPendingMove: 0,\n\t\t};\n\t}\n\n\t/**\n\t * Unsets all local flags used by the DDS. This method can be used after reading from snapshott to ensure\n\t * local flags are initialized for use by the DDS.\n\t * @param entry - Entry for which the local flags have to be cleaned up\n\t */\n\tprivate unsetLocalFlags(entry: SharedArrayEntry<T>): void {\n\t\tentry.isAckPending = false;\n\t\tentry.isLocalPendingDelete = 0;\n\t\tentry.isLocalPendingMove = 0;\n\t}\n\n\t/**\n\t * Returns the index of the first entry starting with startIndex that does not have the isAckPending flag\n\t */\n\tprivate getInternalInsertIndexByIgnoringLocalPendingInserts(startIndex: number): number {\n\t\tlet localOpsIterator = startIndex;\n\t\tfor (\n\t\t\t;\n\t\t\tlocalOpsIterator < this.sharedArray.length;\n\t\t\tlocalOpsIterator = localOpsIterator + 1\n\t\t) {\n\t\t\tconst entry = this.sharedArray[localOpsIterator];\n\t\t\tassert(entry !== undefined, 0xb96 /* Invalid index */);\n\t\t\tif (!entry.isAckPending) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn localOpsIterator;\n\t}\n\n\tprivate findIndexOfEntryId(entryId: string | undefined): number {\n\t\tfor (let index = 0; index < this.sharedArray.length; index = index + 1) {\n\t\t\tif (this.sharedArray[index]?.entryId === entryId) {\n\t\t\t\treturn index;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\n\tprivate prepareToMakeEntryIdLive(entry: SharedArrayEntry<T>): void {\n\t\tconst prevIndex = this.findIndexOfEntryId(entry.prevEntryId);\n\t\tconst nextIndex = this.findIndexOfEntryId(entry.nextEntryId);\n\t\tif (prevIndex !== -1) {\n\t\t\tconst prevEntry = this.sharedArray[prevIndex];\n\t\t\tassert(prevEntry !== undefined, 0xb97 /* Invalid index */);\n\t\t\tprevEntry.nextEntryId = entry.nextEntryId;\n\t\t}\n\t\tif (nextIndex !== -1) {\n\t\t\tconst nextEntry = this.sharedArray[nextIndex];\n\t\t\tassert(nextEntry !== undefined, 0xb98 /* Invalid index */);\n\t\t\tnextEntry.prevEntryId = entry.prevEntryId;\n\t\t}\n\t\tentry.prevEntryId = undefined;\n\t\tentry.nextEntryId = undefined;\n\t}\n\n\t/**\n\t * Method that returns the live entry.\n\t * The shared array internally can store a skip list of all related entries which got created\n\t * due to move operations for the same payload/value. However, all elements except for one element\n\t * can have isDeleted flag as false indicating this is the live entry for the value.\n\t * Current implementation ensures that the last element in the skip list of entries is the liveEntry/\n\t * last live entry\n\t *\n\t * @param entryId - Entry id of any node in the skip list for the same payload/value\n\t */\n\tprivate getLiveEntry(entryId: string): SharedArrayEntry<T> {\n\t\tlet liveEntry = this.getEntryForId(entryId);\n\t\twhile (liveEntry.nextEntryId !== undefined && liveEntry.nextEntryId) {\n\t\t\tliveEntry = this.getEntryForId(liveEntry.nextEntryId);\n\t\t}\n\t\treturn liveEntry;\n\t}\n\n\t/**\n\t * We track sequence of moves for a entry in the shared array using doubly linked skip list.\n\t * This utility function helps us keep track of the current position of an entry.value by marking the entry\n\t * at previous position deleted and appending the entry at the new position at the end of the double linked\n\t * list for that entry.value.\n\t */\n\tprivate updateLiveEntry(oldLiveEntryEntryId: string, newLiveEntryEntryId: string): void {\n\t\tconst oldLiveEntry = this.getEntryForId(oldLiveEntryEntryId);\n\t\tconst newLiveEntry = this.getEntryForId(newLiveEntryEntryId);\n\t\tif (oldLiveEntryEntryId === newLiveEntryEntryId) {\n\t\t\toldLiveEntry.isDeleted = false;\n\t\t} else {\n\t\t\tthis.prepareToMakeEntryIdLive(newLiveEntry);\n\t\t\t// Make entryId live\n\t\t\toldLiveEntry.nextEntryId = newLiveEntryEntryId;\n\t\t\tnewLiveEntry.prevEntryId = oldLiveEntryEntryId;\n\t\t\tnewLiveEntry.isDeleted = false;\n\t\t\toldLiveEntry.isDeleted = true;\n\t\t}\n\t}\n\n\t/**\n\t * We track sequence of moves for a entry in the shared array using doubly linked skip list.\n\t * This utility function helps to insert the new entry as dead entry and reconnecting the double linked list with\n\t * existingEntry -\\> deadeEntry(appended) -\\> existing chain(if any).\n\t */\n\tprivate updateDeadEntry(existingEntryId: string, deadEntryId: string): void {\n\t\tconst existingEntry = this.getEntryForId(existingEntryId);\n\t\tconst deadEntry = this.getEntryForId(deadEntryId);\n\n\t\t// update dead entry's next to existingEntry's next, if existingEntry's next entry exists.\n\t\t// It can be undefined if the exiting element is the last element (or only element) of chain.\n\t\tif (existingEntry.nextEntryId !== undefined) {\n\t\t\tdeadEntry.nextEntryId = existingEntry.nextEntryId;\n\t\t\tthis.getEntryForId(existingEntry.nextEntryId).prevEntryId = deadEntryId;\n\t\t}\n\n\t\t// update current entry's next pointer to dead entry and vice versa.\n\t\texistingEntry.nextEntryId = deadEntryId;\n\t\tdeadEntry.prevEntryId = existingEntryId;\n\t\tdeadEntry.isDeleted = true;\n\t}\n\n\tprotected applyStashedOp(content: unknown): void {\n\t\tconst op = content as ISharedArrayOperation<T>;\n\n\t\tswitch (op.type) {\n\t\t\tcase OperationType.insertEntry: {\n\t\t\t\tthis.handleInsertOp<SerializableTypeForSharedArray>(\n\t\t\t\t\top.entryId,\n\t\t\t\t\top.insertAfterEntryId,\n\t\t\t\t\tfalse, // treat it as remote op\n\t\t\t\t\top.value,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase OperationType.deleteEntry: {\n\t\t\t\tthis.handleDeleteOp(op, false /* local - treat as remote op */);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase OperationType.moveEntry: {\n\t\t\t\tthis.handleMoveOp(op, false /* local - treat as remote op */);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase OperationType.toggle: {\n\t\t\t\tthis.handleToggleOp(op, false /* local - treat as remote op */);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase OperationType.toggleMove: {\n\t\t\t\tthis.handleToggleMoveOp(op, false /* local - treat as remote op */);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(op);\n\t\t\t}\n\t\t}\n\t\tthis.submitLocalMessage(op);\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/legacy-dds";
8
- export declare const pkgVersion = "2.52.0";
8
+ export declare const pkgVersion = "2.53.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/legacy-dds";
8
- export const pkgVersion = "2.52.0";
8
+ export const pkgVersion = "2.53.0";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,4BAA4B,CAAC;AACpD,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/legacy-dds\";\nexport const pkgVersion = \"2.52.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,4BAA4B,CAAC;AACpD,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/legacy-dds\";\nexport const pkgVersion = \"2.53.0\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/legacy-dds",
3
- "version": "2.52.0",
3
+ "version": "2.53.0",
4
4
  "description": "Legacy DDSs for the Fluid Framework. These are not intended for use in new code.",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -81,28 +81,29 @@
81
81
  "temp-directory": "nyc/.nyc_output"
82
82
  },
83
83
  "dependencies": {
84
- "@fluidframework/core-interfaces": "~2.52.0",
85
- "@fluidframework/core-utils": "~2.52.0",
86
- "@fluidframework/datastore-definitions": "~2.52.0",
87
- "@fluidframework/driver-definitions": "~2.52.0",
88
- "@fluidframework/driver-utils": "~2.52.0",
89
- "@fluidframework/runtime-definitions": "~2.52.0",
90
- "@fluidframework/runtime-utils": "~2.52.0",
91
- "@fluidframework/shared-object-base": "~2.52.0",
84
+ "@fluid-internal/client-utils": "~2.53.0",
85
+ "@fluidframework/core-interfaces": "~2.53.0",
86
+ "@fluidframework/core-utils": "~2.53.0",
87
+ "@fluidframework/datastore-definitions": "~2.53.0",
88
+ "@fluidframework/driver-definitions": "~2.53.0",
89
+ "@fluidframework/driver-utils": "~2.53.0",
90
+ "@fluidframework/runtime-definitions": "~2.53.0",
91
+ "@fluidframework/runtime-utils": "~2.53.0",
92
+ "@fluidframework/shared-object-base": "~2.53.0",
92
93
  "uuid": "^11.1.0"
93
94
  },
94
95
  "devDependencies": {
95
96
  "@arethetypeswrong/cli": "^0.17.1",
96
97
  "@biomejs/biome": "~1.9.3",
97
- "@fluid-internal/mocha-test-setup": "~2.52.0",
98
- "@fluid-private/stochastic-test-utils": "~2.52.0",
99
- "@fluid-private/test-dds-utils": "~2.52.0",
98
+ "@fluid-internal/mocha-test-setup": "~2.53.0",
99
+ "@fluid-private/stochastic-test-utils": "~2.53.0",
100
+ "@fluid-private/test-dds-utils": "~2.53.0",
100
101
  "@fluid-tools/build-cli": "^0.57.0",
101
102
  "@fluidframework/build-common": "^2.0.3",
102
103
  "@fluidframework/build-tools": "^0.57.0",
103
- "@fluidframework/container-definitions": "~2.52.0",
104
+ "@fluidframework/container-definitions": "~2.53.0",
104
105
  "@fluidframework/eslint-config-fluid": "^5.7.4",
105
- "@fluidframework/test-runtime-utils": "~2.52.0",
106
+ "@fluidframework/test-runtime-utils": "~2.53.0",
106
107
  "@microsoft/api-extractor": "7.52.8",
107
108
  "@types/jest": "29.5.3",
108
109
  "@types/mocha": "^10.0.10",