@fluidframework/merge-tree 2.20.0 → 2.22.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.
Files changed (183) hide show
  1. package/.eslintrc.cjs +0 -1
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +1 -0
  4. package/dist/attributionCollection.js +5 -7
  5. package/dist/attributionCollection.js.map +1 -1
  6. package/dist/localReference.js +6 -8
  7. package/dist/localReference.js.map +1 -1
  8. package/dist/mergeTree.d.ts.map +1 -1
  9. package/dist/mergeTree.js +69 -34
  10. package/dist/mergeTree.js.map +1 -1
  11. package/dist/mergeTreeNodes.d.ts +15 -4
  12. package/dist/mergeTreeNodes.d.ts.map +1 -1
  13. package/dist/mergeTreeNodes.js +1 -1
  14. package/dist/mergeTreeNodes.js.map +1 -1
  15. package/dist/partialLengths.d.ts +114 -144
  16. package/dist/partialLengths.d.ts.map +1 -1
  17. package/dist/partialLengths.js +431 -525
  18. package/dist/partialLengths.js.map +1 -1
  19. package/dist/perspective.d.ts +10 -1
  20. package/dist/perspective.d.ts.map +1 -1
  21. package/dist/perspective.js +10 -1
  22. package/dist/perspective.js.map +1 -1
  23. package/dist/properties.d.ts.map +1 -1
  24. package/dist/properties.js +2 -3
  25. package/dist/properties.js.map +1 -1
  26. package/dist/revertibles.js +3 -3
  27. package/dist/revertibles.js.map +1 -1
  28. package/dist/segmentInfos.d.ts +3 -0
  29. package/dist/segmentInfos.d.ts.map +1 -1
  30. package/dist/segmentInfos.js.map +1 -1
  31. package/dist/segmentPropertiesManager.js +3 -3
  32. package/dist/segmentPropertiesManager.js.map +1 -1
  33. package/dist/snapshotLoader.js +2 -2
  34. package/dist/snapshotLoader.js.map +1 -1
  35. package/dist/sortedSegmentSet.d.ts +5 -3
  36. package/dist/sortedSegmentSet.d.ts.map +1 -1
  37. package/dist/sortedSegmentSet.js +33 -41
  38. package/dist/sortedSegmentSet.js.map +1 -1
  39. package/dist/sortedSet.d.ts +20 -3
  40. package/dist/sortedSet.d.ts.map +1 -1
  41. package/dist/sortedSet.js +23 -14
  42. package/dist/sortedSet.js.map +1 -1
  43. package/dist/test/Snapshot.perf.spec.js +1 -1
  44. package/dist/test/Snapshot.perf.spec.js.map +1 -1
  45. package/dist/test/client.applyMsg.spec.js +20 -0
  46. package/dist/test/client.applyMsg.spec.js.map +1 -1
  47. package/dist/test/client.applyStashedOpFarm.spec.js +1 -1
  48. package/dist/test/client.applyStashedOpFarm.spec.js.map +1 -1
  49. package/dist/test/client.attributionFarm.spec.js +1 -1
  50. package/dist/test/client.attributionFarm.spec.js.map +1 -1
  51. package/dist/test/client.localReference.spec.js +48 -0
  52. package/dist/test/client.localReference.spec.js.map +1 -1
  53. package/dist/test/client.obliterateFarm.spec.d.ts +12 -0
  54. package/dist/test/client.obliterateFarm.spec.d.ts.map +1 -0
  55. package/dist/test/client.obliterateFarm.spec.js +89 -0
  56. package/dist/test/client.obliterateFarm.spec.js.map +1 -0
  57. package/dist/test/client.reconnectFarm.spec.js +1 -1
  58. package/dist/test/client.reconnectFarm.spec.js.map +1 -1
  59. package/dist/test/client.searchForMarker.spec.js +2 -2
  60. package/dist/test/client.searchForMarker.spec.js.map +1 -1
  61. package/dist/test/mergeTreeOperationRunner.d.ts +7 -2
  62. package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
  63. package/dist/test/mergeTreeOperationRunner.js +31 -14
  64. package/dist/test/mergeTreeOperationRunner.js.map +1 -1
  65. package/dist/test/obliterate.concurrent.spec.js +45 -1
  66. package/dist/test/obliterate.concurrent.spec.js.map +1 -1
  67. package/dist/test/obliterate.rangeExpansion.spec.js +81 -5
  68. package/dist/test/obliterate.rangeExpansion.spec.js.map +1 -1
  69. package/dist/test/obliterate.spec.js +3 -3
  70. package/dist/test/obliterate.spec.js.map +1 -1
  71. package/dist/test/obliterateOperations.d.ts +15 -0
  72. package/dist/test/obliterateOperations.d.ts.map +1 -0
  73. package/dist/test/obliterateOperations.js +132 -0
  74. package/dist/test/obliterateOperations.js.map +1 -0
  75. package/dist/test/partialSyncHelper.d.ts +42 -0
  76. package/dist/test/partialSyncHelper.d.ts.map +1 -0
  77. package/dist/test/partialSyncHelper.js +96 -0
  78. package/dist/test/partialSyncHelper.js.map +1 -0
  79. package/dist/test/revertibles.spec.js +3 -3
  80. package/dist/test/revertibles.spec.js.map +1 -1
  81. package/dist/test/sortedSegmentSet.spec.js +21 -0
  82. package/dist/test/sortedSegmentSet.spec.js.map +1 -1
  83. package/dist/test/testClient.d.ts +1 -1
  84. package/dist/test/testClient.d.ts.map +1 -1
  85. package/dist/test/testClient.js +1 -0
  86. package/dist/test/testClient.js.map +1 -1
  87. package/dist/test/testUtils.js +2 -2
  88. package/dist/test/testUtils.js.map +1 -1
  89. package/lib/attributionCollection.js +5 -7
  90. package/lib/attributionCollection.js.map +1 -1
  91. package/lib/localReference.js +6 -8
  92. package/lib/localReference.js.map +1 -1
  93. package/lib/mergeTree.d.ts.map +1 -1
  94. package/lib/mergeTree.js +69 -34
  95. package/lib/mergeTree.js.map +1 -1
  96. package/lib/mergeTreeNodes.d.ts +15 -4
  97. package/lib/mergeTreeNodes.d.ts.map +1 -1
  98. package/lib/mergeTreeNodes.js +1 -1
  99. package/lib/mergeTreeNodes.js.map +1 -1
  100. package/lib/partialLengths.d.ts +114 -144
  101. package/lib/partialLengths.d.ts.map +1 -1
  102. package/lib/partialLengths.js +432 -525
  103. package/lib/partialLengths.js.map +1 -1
  104. package/lib/perspective.d.ts +10 -1
  105. package/lib/perspective.d.ts.map +1 -1
  106. package/lib/perspective.js +10 -1
  107. package/lib/perspective.js.map +1 -1
  108. package/lib/properties.d.ts.map +1 -1
  109. package/lib/properties.js +2 -3
  110. package/lib/properties.js.map +1 -1
  111. package/lib/revertibles.js +3 -3
  112. package/lib/revertibles.js.map +1 -1
  113. package/lib/segmentInfos.d.ts +3 -0
  114. package/lib/segmentInfos.d.ts.map +1 -1
  115. package/lib/segmentInfos.js.map +1 -1
  116. package/lib/segmentPropertiesManager.js +3 -3
  117. package/lib/segmentPropertiesManager.js.map +1 -1
  118. package/lib/snapshotLoader.js +2 -2
  119. package/lib/snapshotLoader.js.map +1 -1
  120. package/lib/sortedSegmentSet.d.ts +5 -3
  121. package/lib/sortedSegmentSet.d.ts.map +1 -1
  122. package/lib/sortedSegmentSet.js +33 -41
  123. package/lib/sortedSegmentSet.js.map +1 -1
  124. package/lib/sortedSet.d.ts +20 -3
  125. package/lib/sortedSet.d.ts.map +1 -1
  126. package/lib/sortedSet.js +23 -14
  127. package/lib/sortedSet.js.map +1 -1
  128. package/lib/test/Snapshot.perf.spec.js +1 -1
  129. package/lib/test/Snapshot.perf.spec.js.map +1 -1
  130. package/lib/test/client.applyMsg.spec.js +20 -0
  131. package/lib/test/client.applyMsg.spec.js.map +1 -1
  132. package/lib/test/client.applyStashedOpFarm.spec.js +1 -1
  133. package/lib/test/client.applyStashedOpFarm.spec.js.map +1 -1
  134. package/lib/test/client.attributionFarm.spec.js +1 -1
  135. package/lib/test/client.attributionFarm.spec.js.map +1 -1
  136. package/lib/test/client.localReference.spec.js +48 -0
  137. package/lib/test/client.localReference.spec.js.map +1 -1
  138. package/lib/test/client.obliterateFarm.spec.d.ts +12 -0
  139. package/lib/test/client.obliterateFarm.spec.d.ts.map +1 -0
  140. package/lib/test/client.obliterateFarm.spec.js +88 -0
  141. package/lib/test/client.obliterateFarm.spec.js.map +1 -0
  142. package/lib/test/client.reconnectFarm.spec.js +1 -1
  143. package/lib/test/client.reconnectFarm.spec.js.map +1 -1
  144. package/lib/test/client.searchForMarker.spec.js +2 -2
  145. package/lib/test/client.searchForMarker.spec.js.map +1 -1
  146. package/lib/test/mergeTreeOperationRunner.d.ts +7 -2
  147. package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
  148. package/lib/test/mergeTreeOperationRunner.js +31 -14
  149. package/lib/test/mergeTreeOperationRunner.js.map +1 -1
  150. package/lib/test/obliterate.concurrent.spec.js +45 -1
  151. package/lib/test/obliterate.concurrent.spec.js.map +1 -1
  152. package/lib/test/obliterate.rangeExpansion.spec.js +81 -5
  153. package/lib/test/obliterate.rangeExpansion.spec.js.map +1 -1
  154. package/lib/test/obliterate.spec.js +3 -3
  155. package/lib/test/obliterate.spec.js.map +1 -1
  156. package/lib/test/obliterateOperations.d.ts +15 -0
  157. package/lib/test/obliterateOperations.d.ts.map +1 -0
  158. package/lib/test/obliterateOperations.js +123 -0
  159. package/lib/test/obliterateOperations.js.map +1 -0
  160. package/lib/test/partialSyncHelper.d.ts +42 -0
  161. package/lib/test/partialSyncHelper.d.ts.map +1 -0
  162. package/lib/test/partialSyncHelper.js +92 -0
  163. package/lib/test/partialSyncHelper.js.map +1 -0
  164. package/lib/test/revertibles.spec.js +3 -3
  165. package/lib/test/revertibles.spec.js.map +1 -1
  166. package/lib/test/sortedSegmentSet.spec.js +21 -0
  167. package/lib/test/sortedSegmentSet.spec.js.map +1 -1
  168. package/lib/test/testClient.d.ts +1 -1
  169. package/lib/test/testClient.d.ts.map +1 -1
  170. package/lib/test/testClient.js +1 -0
  171. package/lib/test/testClient.js.map +1 -1
  172. package/lib/test/testUtils.js +2 -2
  173. package/lib/test/testUtils.js.map +1 -1
  174. package/package.json +21 -79
  175. package/src/mergeTree.ts +80 -28
  176. package/src/mergeTreeNodes.ts +15 -4
  177. package/src/partialLengths.ts +559 -776
  178. package/src/perspective.ts +10 -1
  179. package/src/properties.ts +2 -3
  180. package/src/segmentInfos.ts +3 -0
  181. package/src/snapshotLoader.ts +1 -1
  182. package/src/sortedSegmentSet.ts +41 -50
  183. package/src/sortedSet.ts +32 -16
@@ -194,11 +194,11 @@ function revertLocalRemove(driver, mergeTreeWithRevert, revertible) {
194
194
  }
195
195
  if (localSlideFilter(lref)) {
196
196
  if (forward) {
197
- const before = (insertRef.before ?? (insertRef.before = new DoublyLinkedList()));
197
+ const before = (insertRef.before ??= new DoublyLinkedList());
198
198
  before.push(lref);
199
199
  }
200
200
  else {
201
- const after = (insertRef.after ?? (insertRef.after = new DoublyLinkedList()));
201
+ const after = (insertRef.after ??= new DoublyLinkedList());
202
202
  after.unshift(lref);
203
203
  }
204
204
  }
@@ -257,7 +257,7 @@ export function revertMergeTreeDeltaRevertibles(driver, revertibles) {
257
257
  const r = revertibles.pop();
258
258
  const operation = r.operation;
259
259
  if (r.trackingGroup.size > 0) {
260
- mergeTreeWithRevert ?? (mergeTreeWithRevert = findMergeTreeWithRevert(r.trackingGroup.tracked[0]));
260
+ mergeTreeWithRevert ??= findMergeTreeWithRevert(r.trackingGroup.tracked[0]);
261
261
  switch (operation) {
262
262
  case MergeTreeDeltaType.INSERT: {
263
263
  revertLocalInsert(driver, mergeTreeWithRevert, r);
@@ -1 +1 @@
1
- {"version":3,"file":"revertibles.js","sourceRoot":"","sources":["../src/revertibles.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 { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { DoublyLinkedList } from \"./collections/index.js\";\nimport { EndOfTreeSegment } from \"./endOfTreeSegment.js\";\nimport { LocalReferenceCollection, LocalReferencePosition } from \"./localReference.js\";\nimport { MergeTree, findRootMergeBlock } from \"./mergeTree.js\";\nimport { IMergeTreeDeltaCallbackArgs } from \"./mergeTreeDeltaCallback.js\";\nimport { depthFirstNodeWalk } from \"./mergeTreeNodeWalk.js\";\nimport {\n\tassertSegmentLeaf,\n\tisSegmentLeaf,\n\ttoSegmentLeaf,\n\ttype ISegmentLeaf,\n\ttype ISegmentPrivate,\n} from \"./mergeTreeNodes.js\";\nimport { ITrackingGroup, Trackable, UnorderedTrackingGroup } from \"./mergeTreeTracking.js\";\nimport { IJSONSegment, MergeTreeDeltaType, ReferenceType } from \"./ops.js\";\nimport { PropertySet, matchProperties } from \"./properties.js\";\nimport { DetachedReferencePosition } from \"./referencePositions.js\";\nimport { toRemovalInfo } from \"./segmentInfos.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport type MergeTreeDeltaRevertible =\n\t| {\n\t\t\toperation: typeof MergeTreeDeltaType.INSERT;\n\t\t\ttrackingGroup: ITrackingGroup;\n\t }\n\t| {\n\t\t\toperation: typeof MergeTreeDeltaType.REMOVE;\n\t\t\ttrackingGroup: ITrackingGroup;\n\t }\n\t| {\n\t\t\toperation: typeof MergeTreeDeltaType.ANNOTATE;\n\t\t\ttrackingGroup: ITrackingGroup;\n\t\t\tpropertyDeltas: PropertySet;\n\t };\n\n/**\n * Tests whether x is a MergeTreeDeltaRevertible\n * @internal\n */\nexport function isMergeTreeDeltaRevertible(x: unknown): x is MergeTreeDeltaRevertible {\n\treturn !!x && typeof x === \"object\" && \"operation\" in x && \"trackingGroup\" in x;\n}\n\ntype TypedRevertible<T extends MergeTreeDeltaRevertible[\"operation\"]> =\n\tMergeTreeDeltaRevertible & {\n\t\toperation: T;\n\t};\n\ninterface RemoveSegmentRefProperties {\n\t/**\n\t * the serialized form of the segment, so it can be re-inserted\n\t */\n\tsegSpec: IJSONSegment;\n\t/**\n\t * a tag so the reference can be identified as being created for revert\n\t */\n\treferenceSpace: \"mergeTreeDeltaRevertible\";\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface MergeTreeRevertibleDriver {\n\tinsertFromSpec(pos: number, spec: IJSONSegment): void;\n\tremoveRange(start: number, end: number): void;\n\tannotateRange(start: number, end: number, props: PropertySet): void;\n}\n\n/**\n * exported for test only. should not be exported out the the package\n * @internal\n */\nexport interface MergeTreeWithRevert extends MergeTree {\n\t__mergeTreeRevertible: {\n\t\tdetachedReferences: EndOfTreeSegment;\n\t\trefCallbacks: LocalReferencePosition[\"callbacks\"];\n\t};\n}\n\nexport type PickPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\nfunction findMergeTreeWithRevert(trackable: Trackable): MergeTreeWithRevert {\n\tconst segmentOrNode = trackable.isLeaf() ? trackable : trackable.getSegment();\n\tconst maybeRoot = findRootMergeBlock(toSegmentLeaf(segmentOrNode));\n\tassert(\n\t\tmaybeRoot?.mergeTree !== undefined,\n\t\t0x5c2 /* trackable is invalid as it is not in a rooted merge tree. */,\n\t);\n\tconst mergeTree: PickPartial<MergeTreeWithRevert, \"__mergeTreeRevertible\"> =\n\t\tmaybeRoot.mergeTree;\n\n\tif (mergeTree.__mergeTreeRevertible === undefined) {\n\t\tconst detachedReferences = new EndOfTreeSegment(maybeRoot.mergeTree);\n\t\tconst refCallbacks: MergeTreeWithRevert[\"__mergeTreeRevertible\"][\"refCallbacks\"] = {\n\t\t\tafterSlide: (r: LocalReferencePosition) => {\n\t\t\t\tif (mergeTree.referencePositionToLocalPosition(r) === DetachedReferencePosition) {\n\t\t\t\t\tconst refs = LocalReferenceCollection.setOrGet(detachedReferences);\n\t\t\t\t\trefs.addAfterTombstones([r]);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t\tmergeTree.__mergeTreeRevertible = {\n\t\t\trefCallbacks,\n\t\t\tdetachedReferences,\n\t\t};\n\t}\n\treturn mergeTree as MergeTreeWithRevert;\n}\n\nfunction appendLocalInsertToRevertibles(\n\tdeltaArgs: IMergeTreeDeltaCallbackArgs,\n\trevertibles: MergeTreeDeltaRevertible[],\n): MergeTreeDeltaRevertible[] {\n\tif (revertibles[revertibles.length - 1]?.operation !== MergeTreeDeltaType.INSERT) {\n\t\trevertibles.push({\n\t\t\toperation: MergeTreeDeltaType.INSERT,\n\t\t\ttrackingGroup: new UnorderedTrackingGroup(),\n\t\t});\n\t}\n\tconst last = revertibles[revertibles.length - 1];\n\tfor (const t of deltaArgs.deltaSegments) last.trackingGroup.link(t.segment);\n\n\treturn revertibles;\n}\n\nfunction appendLocalRemoveToRevertibles(\n\tdeltaArgs: IMergeTreeDeltaCallbackArgs,\n\trevertibles: MergeTreeDeltaRevertible[],\n): MergeTreeDeltaRevertible[] {\n\tif (revertibles[revertibles.length - 1]?.operation !== MergeTreeDeltaType.REMOVE) {\n\t\trevertibles.push({\n\t\t\toperation: MergeTreeDeltaType.REMOVE,\n\t\t\ttrackingGroup: new UnorderedTrackingGroup(),\n\t\t});\n\t}\n\tconst last = revertibles[revertibles.length - 1];\n\n\tconst mergeTreeWithRevert = findMergeTreeWithRevert(deltaArgs.deltaSegments[0].segment);\n\n\tfor (const t of deltaArgs.deltaSegments) {\n\t\tconst props: RemoveSegmentRefProperties = {\n\t\t\tsegSpec: t.segment.toJSONObject() as IJSONSegment,\n\t\t\treferenceSpace: \"mergeTreeDeltaRevertible\",\n\t\t};\n\t\tconst ref = mergeTreeWithRevert.createLocalReferencePosition(\n\t\t\tt.segment,\n\t\t\t0,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tprops,\n\t\t);\n\t\tref.callbacks = mergeTreeWithRevert.__mergeTreeRevertible.refCallbacks;\n\t\tfor (const tg of t.segment.trackingCollection.trackingGroups) {\n\t\t\ttg.link(ref);\n\t\t\ttg.unlink(t.segment);\n\t\t}\n\n\t\tlast.trackingGroup.link(ref);\n\t}\n\treturn revertibles;\n}\n\nfunction appendLocalAnnotateToRevertibles(\n\tdeltaArgs: IMergeTreeDeltaCallbackArgs,\n\trevertibles: MergeTreeDeltaRevertible[],\n): MergeTreeDeltaRevertible[] {\n\tlet last = revertibles[revertibles.length - 1];\n\tfor (const ds of deltaArgs.deltaSegments) {\n\t\tconst propertyDeltas = ds.propertyDeltas;\n\t\tif (propertyDeltas) {\n\t\t\tif (\n\t\t\t\tlast?.operation === MergeTreeDeltaType.ANNOTATE &&\n\t\t\t\tmatchProperties(last?.propertyDeltas, propertyDeltas)\n\t\t\t) {\n\t\t\t\tlast.trackingGroup.link(ds.segment);\n\t\t\t} else {\n\t\t\t\tlast = {\n\t\t\t\t\toperation: MergeTreeDeltaType.ANNOTATE,\n\t\t\t\t\tpropertyDeltas,\n\t\t\t\t\ttrackingGroup: new UnorderedTrackingGroup(),\n\t\t\t\t};\n\t\t\t\tlast.trackingGroup.link(ds.segment);\n\t\t\t\trevertibles.push(last);\n\t\t\t}\n\t\t}\n\t}\n\treturn revertibles;\n}\n\n/**\n * Appends a merge tree delta to the list of revertibles.\n *\n * @legacy\n * @alpha\n */\nexport function appendToMergeTreeDeltaRevertibles(\n\tdeltaArgs: IMergeTreeDeltaCallbackArgs,\n\trevertibles: MergeTreeDeltaRevertible[],\n): void {\n\tif (deltaArgs.deltaSegments.length === 0) {\n\t\treturn;\n\t}\n\tswitch (deltaArgs.operation) {\n\t\tcase MergeTreeDeltaType.INSERT: {\n\t\t\tappendLocalInsertToRevertibles(deltaArgs, revertibles);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase MergeTreeDeltaType.REMOVE: {\n\t\t\tappendLocalRemoveToRevertibles(deltaArgs, revertibles);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase MergeTreeDeltaType.ANNOTATE: {\n\t\t\tappendLocalAnnotateToRevertibles(deltaArgs, revertibles);\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault: {\n\t\t\tthrow new UsageError(\"Unsupported event delta type\", {\n\t\t\t\toperation: deltaArgs.operation,\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Removes all revertibles from the list of revertibles.\n *\n * @legacy\n * @alpha\n */\nexport function discardMergeTreeDeltaRevertible(\n\trevertibles: MergeTreeDeltaRevertible[],\n): void {\n\tfor (const r of revertibles) {\n\t\tfor (const t of r.trackingGroup.tracked) {\n\t\t\tt.trackingCollection.unlink(r.trackingGroup);\n\t\t\t// remove untracked local references\n\t\t\tif (t.trackingCollection.empty && !t.isLeaf()) {\n\t\t\t\tconst segment: ISegmentPrivate | undefined = t.getSegment();\n\t\t\t\tsegment?.localRefs?.removeLocalRef(t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction revertLocalInsert(\n\tdriver: MergeTreeRevertibleDriver,\n\tmergeTreeWithRevert: MergeTreeWithRevert,\n\trevertible: TypedRevertible<typeof MergeTreeDeltaType.INSERT>,\n): void {\n\twhile (revertible.trackingGroup.size > 0) {\n\t\tconst tracked = revertible.trackingGroup.tracked[0];\n\t\tassert(\n\t\t\ttracked.trackingCollection.unlink(revertible.trackingGroup),\n\t\t\t0x3f1 /* tracking group removed */,\n\t\t);\n\t\tassert(isSegmentLeaf(tracked), 0x3f2 /* inserts must track segments */);\n\t\tif (toRemovalInfo(tracked) === undefined) {\n\t\t\tconst start = getPosition(mergeTreeWithRevert, tracked);\n\t\t\tdriver.removeRange(start, start + tracked.cachedLength);\n\t\t}\n\t}\n}\n\nfunction revertLocalRemove(\n\tdriver: MergeTreeRevertibleDriver,\n\tmergeTreeWithRevert: MergeTreeWithRevert,\n\trevertible: TypedRevertible<typeof MergeTreeDeltaType.REMOVE>,\n): void {\n\twhile (revertible.trackingGroup.size > 0) {\n\t\tconst tracked = revertible.trackingGroup.tracked[0];\n\n\t\tassert(\n\t\t\ttracked.trackingCollection.unlink(revertible.trackingGroup),\n\t\t\t0x3f3 /* tracking group removed */,\n\t\t);\n\n\t\tassert(!tracked.isLeaf(), 0x3f4 /* removes must track local refs */);\n\n\t\tconst refSeg = tracked.getSegment();\n\t\tlet realPos = mergeTreeWithRevert.referencePositionToLocalPosition(tracked);\n\n\t\t// References which are on EndOfStringSegment don't return detached for pos,\n\t\t// they will return the length of the merge-tree. this case just catches\n\t\t// random references, likely not created in the revertible flow,\n\t\t// that are tying to be reverted for some reason.\n\t\tif (realPos === DetachedReferencePosition || !isSegmentLeaf(refSeg)) {\n\t\t\tthrow new UsageError(\"Cannot insert at detached references position\");\n\t\t}\n\n\t\tif (toRemovalInfo(refSeg) === undefined && refSeg.localRefs?.isAfterTombstone(tracked)) {\n\t\t\trealPos++;\n\t\t}\n\n\t\tconst props = tracked.properties as RemoveSegmentRefProperties;\n\t\tdriver.insertFromSpec(realPos, props.segSpec);\n\t\tconst insertSegment = mergeTreeWithRevert.getContainingSegment(\n\t\t\trealPos,\n\t\t\tmergeTreeWithRevert.collabWindow.currentSeq,\n\t\t\tmergeTreeWithRevert.collabWindow.clientId,\n\t\t).segment;\n\t\tassertSegmentLeaf(insertSegment);\n\n\t\tconst localSlideFilter = (lref: LocalReferencePosition): boolean =>\n\t\t\t(lref.properties as Partial<RemoveSegmentRefProperties>)?.referenceSpace ===\n\t\t\t\"mergeTreeDeltaRevertible\";\n\n\t\tconst insertRef: Partial<\n\t\t\tRecord<\"before\" | \"after\", DoublyLinkedList<LocalReferencePosition>>\n\t\t> = {};\n\t\tconst forward = insertSegment.ordinal < refSeg.ordinal;\n\t\tconst refHandler = (lref: LocalReferencePosition): false | undefined => {\n\t\t\t// once we reach it keep the original reference where it is\n\t\t\t// we'll move tracking groups, and remove it as a last step.\n\t\t\tif (tracked === lref) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (localSlideFilter(lref)) {\n\t\t\t\tif (forward) {\n\t\t\t\t\tconst before = (insertRef.before ??= new DoublyLinkedList());\n\t\t\t\t\tbefore.push(lref);\n\t\t\t\t} else {\n\t\t\t\t\tconst after = (insertRef.after ??= new DoublyLinkedList());\n\t\t\t\t\tafter.unshift(lref);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tdepthFirstNodeWalk(\n\t\t\tinsertSegment.parent,\n\t\t\tinsertSegment,\n\t\t\tundefined,\n\t\t\t(seg: ISegmentPrivate) => {\n\t\t\t\tif (seg.localRefs?.empty === false) {\n\t\t\t\t\treturn seg.localRefs.walkReferences(refHandler, undefined, forward);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\tundefined,\n\t\t\tforward,\n\t\t);\n\t\tif (\n\t\t\tmergeTreeWithRevert?.__mergeTreeRevertible?.detachedReferences?.localRefs?.has(tracked)\n\t\t) {\n\t\t\tassert(forward, 0x3f6 /* forward should always be true when detached */);\n\t\t\tmergeTreeWithRevert?.__mergeTreeRevertible.detachedReferences.localRefs.walkReferences(\n\t\t\t\trefHandler,\n\t\t\t);\n\t\t}\n\n\t\tif (insertRef !== undefined) {\n\t\t\tconst localRefs = LocalReferenceCollection.setOrGet(insertSegment);\n\t\t\tif (insertRef.before?.empty === false) {\n\t\t\t\tlocalRefs.addBeforeTombstones(insertRef.before.map((n) => n.data));\n\t\t\t}\n\t\t\tif (insertRef.after?.empty === false) {\n\t\t\t\tlocalRefs.addAfterTombstones(insertRef.after.map((n) => n.data));\n\t\t\t}\n\t\t}\n\n\t\tfor (const tg of tracked.trackingCollection.trackingGroups) {\n\t\t\ttg.link(insertSegment);\n\t\t\ttg.unlink(tracked);\n\t\t}\n\t\tconst segment: ISegmentPrivate | undefined = tracked.getSegment();\n\t\tsegment?.localRefs?.removeLocalRef(tracked);\n\t}\n}\n\nfunction revertLocalAnnotate(\n\tdriver: MergeTreeRevertibleDriver,\n\tmergeTreeWithRevert: MergeTreeWithRevert,\n\trevertible: TypedRevertible<typeof MergeTreeDeltaType.ANNOTATE>,\n): void {\n\twhile (revertible.trackingGroup.size > 0) {\n\t\tconst tracked = revertible.trackingGroup.tracked[0];\n\t\tconst unlinked = tracked.trackingCollection.unlink(revertible.trackingGroup);\n\t\tassert(unlinked && isSegmentLeaf(tracked), 0x3f7 /* annotates must track segments */);\n\t\tif (toRemovalInfo(tracked) === undefined) {\n\t\t\tconst start = getPosition(mergeTreeWithRevert, tracked);\n\t\t\tdriver.annotateRange(start, start + tracked.cachedLength, revertible.propertyDeltas);\n\t\t}\n\t}\n}\n\nfunction getPosition(mergeTreeWithRevert: MergeTreeWithRevert, segment: ISegmentLeaf): number {\n\treturn mergeTreeWithRevert.getPosition(\n\t\tsegment,\n\t\tmergeTreeWithRevert.collabWindow.currentSeq,\n\t\tmergeTreeWithRevert.collabWindow.clientId,\n\t);\n}\n\n/**\n * Reverts all operations in the list of revertibles.\n *\n * @legacy\n * @alpha\n */\nexport function revertMergeTreeDeltaRevertibles(\n\tdriver: MergeTreeRevertibleDriver,\n\trevertibles: MergeTreeDeltaRevertible[],\n): void {\n\tlet mergeTreeWithRevert: MergeTreeWithRevert | undefined;\n\n\twhile (revertibles.length > 0) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst r = revertibles.pop()!;\n\t\tconst operation = r.operation;\n\t\tif (r.trackingGroup.size > 0) {\n\t\t\tmergeTreeWithRevert ??= findMergeTreeWithRevert(r.trackingGroup.tracked[0]);\n\t\t\tswitch (operation) {\n\t\t\t\tcase MergeTreeDeltaType.INSERT: {\n\t\t\t\t\trevertLocalInsert(driver, mergeTreeWithRevert, r);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase MergeTreeDeltaType.REMOVE: {\n\t\t\t\t\trevertLocalRemove(driver, mergeTreeWithRevert, r);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase MergeTreeDeltaType.ANNOTATE: {\n\t\t\t\t\trevertLocalAnnotate(driver, mergeTreeWithRevert, r);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tunreachableCase(operation);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"revertibles.js","sourceRoot":"","sources":["../src/revertibles.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 { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { DoublyLinkedList } from \"./collections/index.js\";\nimport { EndOfTreeSegment } from \"./endOfTreeSegment.js\";\nimport { LocalReferenceCollection, LocalReferencePosition } from \"./localReference.js\";\nimport { MergeTree, findRootMergeBlock } from \"./mergeTree.js\";\nimport { IMergeTreeDeltaCallbackArgs } from \"./mergeTreeDeltaCallback.js\";\nimport { depthFirstNodeWalk } from \"./mergeTreeNodeWalk.js\";\nimport {\n\tassertSegmentLeaf,\n\tisSegmentLeaf,\n\ttoSegmentLeaf,\n\ttype ISegmentLeaf,\n\ttype ISegmentPrivate,\n} from \"./mergeTreeNodes.js\";\nimport { ITrackingGroup, Trackable, UnorderedTrackingGroup } from \"./mergeTreeTracking.js\";\nimport { IJSONSegment, MergeTreeDeltaType, ReferenceType } from \"./ops.js\";\nimport { PropertySet, matchProperties } from \"./properties.js\";\nimport { DetachedReferencePosition } from \"./referencePositions.js\";\nimport { toRemovalInfo } from \"./segmentInfos.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport type MergeTreeDeltaRevertible =\n\t| {\n\t\t\toperation: typeof MergeTreeDeltaType.INSERT;\n\t\t\ttrackingGroup: ITrackingGroup;\n\t }\n\t| {\n\t\t\toperation: typeof MergeTreeDeltaType.REMOVE;\n\t\t\ttrackingGroup: ITrackingGroup;\n\t }\n\t| {\n\t\t\toperation: typeof MergeTreeDeltaType.ANNOTATE;\n\t\t\ttrackingGroup: ITrackingGroup;\n\t\t\tpropertyDeltas: PropertySet;\n\t };\n\n/**\n * Tests whether x is a MergeTreeDeltaRevertible\n * @internal\n */\nexport function isMergeTreeDeltaRevertible(x: unknown): x is MergeTreeDeltaRevertible {\n\treturn !!x && typeof x === \"object\" && \"operation\" in x && \"trackingGroup\" in x;\n}\n\ntype TypedRevertible<T extends MergeTreeDeltaRevertible[\"operation\"]> =\n\tMergeTreeDeltaRevertible & {\n\t\toperation: T;\n\t};\n\ninterface RemoveSegmentRefProperties {\n\t/**\n\t * the serialized form of the segment, so it can be re-inserted\n\t */\n\tsegSpec: IJSONSegment;\n\t/**\n\t * a tag so the reference can be identified as being created for revert\n\t */\n\treferenceSpace: \"mergeTreeDeltaRevertible\";\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface MergeTreeRevertibleDriver {\n\tinsertFromSpec(pos: number, spec: IJSONSegment): void;\n\tremoveRange(start: number, end: number): void;\n\tannotateRange(start: number, end: number, props: PropertySet): void;\n}\n\n/**\n * exported for test only. should not be exported out the the package\n * @internal\n */\nexport interface MergeTreeWithRevert extends MergeTree {\n\t__mergeTreeRevertible: {\n\t\tdetachedReferences: EndOfTreeSegment;\n\t\trefCallbacks: LocalReferencePosition[\"callbacks\"];\n\t};\n}\n\nexport type PickPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\nfunction findMergeTreeWithRevert(trackable: Trackable): MergeTreeWithRevert {\n\tconst segmentOrNode = trackable.isLeaf() ? trackable : trackable.getSegment();\n\tconst maybeRoot = findRootMergeBlock(toSegmentLeaf(segmentOrNode));\n\tassert(\n\t\tmaybeRoot?.mergeTree !== undefined,\n\t\t0x5c2 /* trackable is invalid as it is not in a rooted merge tree. */,\n\t);\n\tconst mergeTree: PickPartial<MergeTreeWithRevert, \"__mergeTreeRevertible\"> =\n\t\tmaybeRoot.mergeTree;\n\n\tif (mergeTree.__mergeTreeRevertible === undefined) {\n\t\tconst detachedReferences = new EndOfTreeSegment(maybeRoot.mergeTree);\n\t\tconst refCallbacks: MergeTreeWithRevert[\"__mergeTreeRevertible\"][\"refCallbacks\"] = {\n\t\t\tafterSlide: (r: LocalReferencePosition) => {\n\t\t\t\tif (mergeTree.referencePositionToLocalPosition(r) === DetachedReferencePosition) {\n\t\t\t\t\tconst refs = LocalReferenceCollection.setOrGet(detachedReferences);\n\t\t\t\t\trefs.addAfterTombstones([r]);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t\tmergeTree.__mergeTreeRevertible = {\n\t\t\trefCallbacks,\n\t\t\tdetachedReferences,\n\t\t};\n\t}\n\treturn mergeTree as MergeTreeWithRevert;\n}\n\nfunction appendLocalInsertToRevertibles(\n\tdeltaArgs: IMergeTreeDeltaCallbackArgs,\n\trevertibles: MergeTreeDeltaRevertible[],\n): MergeTreeDeltaRevertible[] {\n\tif (revertibles[revertibles.length - 1]?.operation !== MergeTreeDeltaType.INSERT) {\n\t\trevertibles.push({\n\t\t\toperation: MergeTreeDeltaType.INSERT,\n\t\t\ttrackingGroup: new UnorderedTrackingGroup(),\n\t\t});\n\t}\n\tconst last = revertibles[revertibles.length - 1];\n\tfor (const t of deltaArgs.deltaSegments) last.trackingGroup.link(t.segment);\n\n\treturn revertibles;\n}\n\nfunction appendLocalRemoveToRevertibles(\n\tdeltaArgs: IMergeTreeDeltaCallbackArgs,\n\trevertibles: MergeTreeDeltaRevertible[],\n): MergeTreeDeltaRevertible[] {\n\tif (revertibles[revertibles.length - 1]?.operation !== MergeTreeDeltaType.REMOVE) {\n\t\trevertibles.push({\n\t\t\toperation: MergeTreeDeltaType.REMOVE,\n\t\t\ttrackingGroup: new UnorderedTrackingGroup(),\n\t\t});\n\t}\n\tconst last = revertibles[revertibles.length - 1];\n\n\tconst mergeTreeWithRevert = findMergeTreeWithRevert(deltaArgs.deltaSegments[0].segment);\n\n\tfor (const t of deltaArgs.deltaSegments) {\n\t\tconst props: RemoveSegmentRefProperties = {\n\t\t\tsegSpec: t.segment.toJSONObject() as IJSONSegment,\n\t\t\treferenceSpace: \"mergeTreeDeltaRevertible\",\n\t\t};\n\t\tconst ref = mergeTreeWithRevert.createLocalReferencePosition(\n\t\t\tt.segment,\n\t\t\t0,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tprops,\n\t\t);\n\t\tref.callbacks = mergeTreeWithRevert.__mergeTreeRevertible.refCallbacks;\n\t\tfor (const tg of t.segment.trackingCollection.trackingGroups) {\n\t\t\ttg.link(ref);\n\t\t\ttg.unlink(t.segment);\n\t\t}\n\n\t\tlast.trackingGroup.link(ref);\n\t}\n\treturn revertibles;\n}\n\nfunction appendLocalAnnotateToRevertibles(\n\tdeltaArgs: IMergeTreeDeltaCallbackArgs,\n\trevertibles: MergeTreeDeltaRevertible[],\n): MergeTreeDeltaRevertible[] {\n\tlet last = revertibles[revertibles.length - 1];\n\tfor (const ds of deltaArgs.deltaSegments) {\n\t\tconst propertyDeltas = ds.propertyDeltas;\n\t\tif (propertyDeltas) {\n\t\t\tif (\n\t\t\t\tlast?.operation === MergeTreeDeltaType.ANNOTATE &&\n\t\t\t\tmatchProperties(last?.propertyDeltas, propertyDeltas)\n\t\t\t) {\n\t\t\t\tlast.trackingGroup.link(ds.segment);\n\t\t\t} else {\n\t\t\t\tlast = {\n\t\t\t\t\toperation: MergeTreeDeltaType.ANNOTATE,\n\t\t\t\t\tpropertyDeltas,\n\t\t\t\t\ttrackingGroup: new UnorderedTrackingGroup(),\n\t\t\t\t};\n\t\t\t\tlast.trackingGroup.link(ds.segment);\n\t\t\t\trevertibles.push(last);\n\t\t\t}\n\t\t}\n\t}\n\treturn revertibles;\n}\n\n/**\n * Appends a merge tree delta to the list of revertibles.\n *\n * @legacy\n * @alpha\n */\nexport function appendToMergeTreeDeltaRevertibles(\n\tdeltaArgs: IMergeTreeDeltaCallbackArgs,\n\trevertibles: MergeTreeDeltaRevertible[],\n): void {\n\tif (deltaArgs.deltaSegments.length === 0) {\n\t\treturn;\n\t}\n\tswitch (deltaArgs.operation) {\n\t\tcase MergeTreeDeltaType.INSERT: {\n\t\t\tappendLocalInsertToRevertibles(deltaArgs, revertibles);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase MergeTreeDeltaType.REMOVE: {\n\t\t\tappendLocalRemoveToRevertibles(deltaArgs, revertibles);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase MergeTreeDeltaType.ANNOTATE: {\n\t\t\tappendLocalAnnotateToRevertibles(deltaArgs, revertibles);\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault: {\n\t\t\tthrow new UsageError(\"Unsupported event delta type\", {\n\t\t\t\toperation: deltaArgs.operation,\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Removes all revertibles from the list of revertibles.\n *\n * @legacy\n * @alpha\n */\nexport function discardMergeTreeDeltaRevertible(\n\trevertibles: MergeTreeDeltaRevertible[],\n): void {\n\tfor (const r of revertibles) {\n\t\tfor (const t of r.trackingGroup.tracked) {\n\t\t\tt.trackingCollection.unlink(r.trackingGroup);\n\t\t\t// remove untracked local references\n\t\t\tif (t.trackingCollection.empty && !t.isLeaf()) {\n\t\t\t\tconst segment: ISegmentPrivate | undefined = t.getSegment();\n\t\t\t\tsegment?.localRefs?.removeLocalRef(t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction revertLocalInsert(\n\tdriver: MergeTreeRevertibleDriver,\n\tmergeTreeWithRevert: MergeTreeWithRevert,\n\trevertible: TypedRevertible<typeof MergeTreeDeltaType.INSERT>,\n): void {\n\twhile (revertible.trackingGroup.size > 0) {\n\t\tconst tracked = revertible.trackingGroup.tracked[0];\n\t\tassert(\n\t\t\ttracked.trackingCollection.unlink(revertible.trackingGroup),\n\t\t\t0x3f1 /* tracking group removed */,\n\t\t);\n\t\tassert(isSegmentLeaf(tracked), 0x3f2 /* inserts must track segments */);\n\t\tif (toRemovalInfo(tracked) === undefined) {\n\t\t\tconst start = getPosition(mergeTreeWithRevert, tracked);\n\t\t\tdriver.removeRange(start, start + tracked.cachedLength);\n\t\t}\n\t}\n}\n\nfunction revertLocalRemove(\n\tdriver: MergeTreeRevertibleDriver,\n\tmergeTreeWithRevert: MergeTreeWithRevert,\n\trevertible: TypedRevertible<typeof MergeTreeDeltaType.REMOVE>,\n): void {\n\twhile (revertible.trackingGroup.size > 0) {\n\t\tconst tracked = revertible.trackingGroup.tracked[0];\n\n\t\tassert(\n\t\t\ttracked.trackingCollection.unlink(revertible.trackingGroup),\n\t\t\t0x3f3 /* tracking group removed */,\n\t\t);\n\n\t\tassert(!tracked.isLeaf(), 0x3f4 /* removes must track local refs */);\n\n\t\tconst refSeg = tracked.getSegment();\n\t\tlet realPos = mergeTreeWithRevert.referencePositionToLocalPosition(tracked);\n\n\t\t// References which are on EndOfStringSegment don't return detached for pos,\n\t\t// they will return the length of the merge-tree. this case just catches\n\t\t// random references, likely not created in the revertible flow,\n\t\t// that are tying to be reverted for some reason.\n\t\tif (realPos === DetachedReferencePosition || !isSegmentLeaf(refSeg)) {\n\t\t\tthrow new UsageError(\"Cannot insert at detached references position\");\n\t\t}\n\n\t\tif (toRemovalInfo(refSeg) === undefined && refSeg.localRefs?.isAfterTombstone(tracked)) {\n\t\t\trealPos++;\n\t\t}\n\n\t\tconst props = tracked.properties as RemoveSegmentRefProperties;\n\t\tdriver.insertFromSpec(realPos, props.segSpec);\n\t\tconst insertSegment = mergeTreeWithRevert.getContainingSegment(\n\t\t\trealPos,\n\t\t\tmergeTreeWithRevert.collabWindow.currentSeq,\n\t\t\tmergeTreeWithRevert.collabWindow.clientId,\n\t\t).segment;\n\t\tassertSegmentLeaf(insertSegment);\n\n\t\tconst localSlideFilter = (lref: LocalReferencePosition): boolean =>\n\t\t\t(lref.properties as Partial<RemoveSegmentRefProperties>)?.referenceSpace ===\n\t\t\t\"mergeTreeDeltaRevertible\";\n\n\t\tconst insertRef: Partial<\n\t\t\tRecord<\"before\" | \"after\", DoublyLinkedList<LocalReferencePosition>>\n\t\t> = {};\n\t\tconst forward = insertSegment.ordinal < refSeg.ordinal;\n\t\tconst refHandler = (lref: LocalReferencePosition): false | undefined => {\n\t\t\t// once we reach it keep the original reference where it is\n\t\t\t// we'll move tracking groups, and remove it as a last step.\n\t\t\tif (tracked === lref) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (localSlideFilter(lref)) {\n\t\t\t\tif (forward) {\n\t\t\t\t\tconst before = (insertRef.before ??= new DoublyLinkedList());\n\t\t\t\t\tbefore.push(lref);\n\t\t\t\t} else {\n\t\t\t\t\tconst after = (insertRef.after ??= new DoublyLinkedList());\n\t\t\t\t\tafter.unshift(lref);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tdepthFirstNodeWalk(\n\t\t\tinsertSegment.parent,\n\t\t\tinsertSegment,\n\t\t\tundefined,\n\t\t\t(seg: ISegmentPrivate) => {\n\t\t\t\tif (seg.localRefs?.empty === false) {\n\t\t\t\t\treturn seg.localRefs.walkReferences(refHandler, undefined, forward);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\tundefined,\n\t\t\tforward,\n\t\t);\n\t\tif (\n\t\t\tmergeTreeWithRevert?.__mergeTreeRevertible?.detachedReferences?.localRefs?.has(tracked)\n\t\t) {\n\t\t\tassert(forward, 0x3f6 /* forward should always be true when detached */);\n\t\t\tmergeTreeWithRevert?.__mergeTreeRevertible.detachedReferences.localRefs.walkReferences(\n\t\t\t\trefHandler,\n\t\t\t);\n\t\t}\n\n\t\tif (insertRef !== undefined) {\n\t\t\tconst localRefs = LocalReferenceCollection.setOrGet(insertSegment);\n\t\t\tif (insertRef.before?.empty === false) {\n\t\t\t\tlocalRefs.addBeforeTombstones(insertRef.before.map((n) => n.data));\n\t\t\t}\n\t\t\tif (insertRef.after?.empty === false) {\n\t\t\t\tlocalRefs.addAfterTombstones(insertRef.after.map((n) => n.data));\n\t\t\t}\n\t\t}\n\n\t\tfor (const tg of tracked.trackingCollection.trackingGroups) {\n\t\t\ttg.link(insertSegment);\n\t\t\ttg.unlink(tracked);\n\t\t}\n\t\tconst segment: ISegmentPrivate | undefined = tracked.getSegment();\n\t\tsegment?.localRefs?.removeLocalRef(tracked);\n\t}\n}\n\nfunction revertLocalAnnotate(\n\tdriver: MergeTreeRevertibleDriver,\n\tmergeTreeWithRevert: MergeTreeWithRevert,\n\trevertible: TypedRevertible<typeof MergeTreeDeltaType.ANNOTATE>,\n): void {\n\twhile (revertible.trackingGroup.size > 0) {\n\t\tconst tracked = revertible.trackingGroup.tracked[0];\n\t\tconst unlinked = tracked.trackingCollection.unlink(revertible.trackingGroup);\n\t\tassert(unlinked && isSegmentLeaf(tracked), 0x3f7 /* annotates must track segments */);\n\t\tif (toRemovalInfo(tracked) === undefined) {\n\t\t\tconst start = getPosition(mergeTreeWithRevert, tracked);\n\t\t\tdriver.annotateRange(start, start + tracked.cachedLength, revertible.propertyDeltas);\n\t\t}\n\t}\n}\n\nfunction getPosition(mergeTreeWithRevert: MergeTreeWithRevert, segment: ISegmentLeaf): number {\n\treturn mergeTreeWithRevert.getPosition(\n\t\tsegment,\n\t\tmergeTreeWithRevert.collabWindow.currentSeq,\n\t\tmergeTreeWithRevert.collabWindow.clientId,\n\t);\n}\n\n/**\n * Reverts all operations in the list of revertibles.\n *\n * @legacy\n * @alpha\n */\nexport function revertMergeTreeDeltaRevertibles(\n\tdriver: MergeTreeRevertibleDriver,\n\trevertibles: MergeTreeDeltaRevertible[],\n): void {\n\tlet mergeTreeWithRevert: MergeTreeWithRevert | undefined;\n\n\twhile (revertibles.length > 0) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst r = revertibles.pop()!;\n\t\tconst operation = r.operation;\n\t\tif (r.trackingGroup.size > 0) {\n\t\t\tmergeTreeWithRevert ??= findMergeTreeWithRevert(r.trackingGroup.tracked[0]);\n\t\t\tswitch (operation) {\n\t\t\t\tcase MergeTreeDeltaType.INSERT: {\n\t\t\t\t\trevertLocalInsert(driver, mergeTreeWithRevert, r);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase MergeTreeDeltaType.REMOVE: {\n\t\t\t\t\trevertLocalRemove(driver, mergeTreeWithRevert, r);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase MergeTreeDeltaType.ANNOTATE: {\n\t\t\t\t\trevertLocalAnnotate(driver, mergeTreeWithRevert, r);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tunreachableCase(operation);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -213,6 +213,9 @@ export interface IMoveInfo {
213
213
  * If a segment is moved on insertion, its length is only ever visible to
214
214
  * the client that inserted the segment. This is relevant in partial length
215
215
  * calculations
216
+ *
217
+ * @privateRemarks
218
+ * TODO:AB#29553: This property is not persisted in the summary, but it should be.
216
219
  */
217
220
  wasMovedOnInsert: boolean;
218
221
  }
@@ -1 +1 @@
1
- {"version":3,"file":"segmentInfos.d.ts","sourceRoot":"","sources":["../src/segmentInfos.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"segmentInfos.d.ts","sourceRoot":"","sources":["../src/segmentInfos.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"segmentInfos.js","sourceRoot":"","sources":["../src/segmentInfos.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAEvE,OAAO,EAAqC,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAWpF,MAAM,UAAU,UAAU,CACzB,KAAc,EACd,IAAO;IAEP,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,OAAO,CACtB,KAAc,EACd,IAAO,EACP,IAAO;IAEP,OAAO,CACN,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC;QACvB,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAC7E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAC7B,KAAc,EACd,IAAO,EACP,IAA+B;IAE/B,OAAO,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC;AAC/D,CAAC;AA0BD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,WAAoB,EAA8B,EAAE,CACnF,OAAO,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,IAAI,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC;IAClF,CAAC,CAAC,WAAW;IACb,CAAC,CAAC,SAAS,CAAC;AAEd;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,WAAoB,EAAiC,EAAE,CACjF,eAAe,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAEwD,CAClF,WAAW,EACV,EAAE,CACH,MAAM,CACL,WAAW,KAAK,SAAS,IAAI,UAAU,CAAC,WAAW,CAAC,EACpD,KAAK,CAAC,2BAA2B,CACjC,CAAC;AAuBH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAAiB,EAA8B,EAAE,CAChF,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC;IAC9C,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;IACtC,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;IACnC,CAAC,CAAC,QAAQ;IACV,CAAC,CAAC,SAAS,CAAC;AAEd;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAAiB,EAA8B,EAAE,CAChF,eAAe,CAAC,QAAQ,CAAC,KAAK,SAAS,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAEoD,CAC/E,WAAW,EACV,EAAE,CACH,MAAM,CACL,WAAW,KAAK,SAAS,IAAI,eAAe,CAAC,WAAW,CAAC,EACzD,KAAK,CAAC,2BAA2B,CACjC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAA4D,CAC3F,QAAQ,EACP,EAAE,CACH,MAAM,CAAC,MAAM,CAA0D,QAAQ,EAAE;IAChF,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,SAAS;IAChB,OAAO,EAAE,SAAS;CAClB,CAAC,CAAC;AAuBJ;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,WAAoB,EAA4B,EAAE,CAC/E,OAAO,CAAC,WAAW,EAAE,kBAAkB,EAAE,OAAO,CAAC;IACjD,OAAO,CAAC,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAC;IAC3C,CAAC,CAAC,WAAW;IACb,CAAC,CAAC,SAAS,CAAC;AAEd;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,WAAoB,EAA+B,EAAE,CAC9E,aAAa,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAEqD,CAAC,WAAW,EAAE,EAAE,CAC9F,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,SAAS,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC;AAE9F;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA0D,CACvF,QAAQ,EACP,EAAE,CACH,MAAM,CAAC,MAAM,CAAsD,QAAQ,EAAE;IAC5E,eAAe,EAAE,SAAS;IAC1B,gBAAgB,EAAE,SAAS;IAC3B,UAAU,EAAE,SAAS;CACrB,CAAC,CAAC;AAkEJ,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,WAAoB,EAAyB,EAAE,CACzE,OAAO,CAAC,WAAW,EAAE,gBAAgB,EAAE,OAAO,CAAC;IAC/C,OAAO,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC;IAC1C,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC;IAC1C,OAAO,CAAC,WAAW,EAAE,kBAAkB,EAAE,SAAS,CAAC;IAClD,CAAC,CAAC,WAAW;IACb,CAAC,CAAC,SAAS,CAAC;AAEd;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,WAAoB,EAA4B,EAAE,CACzE,UAAU,CAAC,WAAW,CAAC,KAAK,SAAS,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAEiD,CAAC,WAAW,EAAE,EAAE,CACxF,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAC;AAezF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAI5B,WAAc,EACd,IAAO,EACiB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, isObject } from \"@fluidframework/core-utils/internal\";\n\nimport { ISegmentInternal, ISegmentPrivate, MergeBlock } from \"./mergeTreeNodes.js\";\nimport type { ReferencePosition } from \"./referencePositions.js\";\n\nexport interface StringToType {\n\t\"string\": string;\n\t\"number\": number;\n\t\"object\": object;\n\t\"array\": [];\n\t\"boolean\": boolean;\n}\n\nexport function propExists<P extends string>(\n\tthing: unknown,\n\tprop: P,\n): thing is Record<P, unknown> {\n\treturn isObject(thing) && prop in thing;\n}\n\nexport function hasProp<P extends string, T extends keyof StringToType>(\n\tthing: unknown,\n\tprop: P,\n\ttype: T,\n): thing is Record<P, StringToType[typeof type]> {\n\treturn (\n\t\tpropExists(thing, prop) &&\n\t\t(type === \"array\" ? Array.isArray(thing[prop]) : typeof thing[prop] === type)\n\t);\n}\n\nexport function propInstanceOf<P extends string, T>(\n\tthing: unknown,\n\tprop: P,\n\ttype: new (...args: any[]) => T,\n): thing is Record<P, T> {\n\treturn propExists(thing, prop) && thing[prop] instanceof type;\n}\n\n/**\n * Contains insertion information associated to an {@link ISegment}.\n */\nexport interface IInsertionInfo {\n\t/**\n\t * Short clientId for the client that inserted this segment.\n\t */\n\tclientId: number;\n\t/**\n\t * Local seq at which this segment was inserted.\n\t * This is defined if and only if the insertion of the segment is pending ack, i.e. `seq` is UnassignedSequenceNumber.\n\t * Once the segment is acked, this field is cleared.\n\t *\n\t * @privateRemarks\n\t * See {@link CollaborationWindow.localSeq} for more information on the semantics of localSeq.\n\t */\n\tlocalSeq?: number;\n\t/**\n\t * Seq at which this segment was inserted.\n\t * If undefined, it is assumed the segment was inserted prior to the collab window's minimum sequence number.\n\t */\n\tseq: number;\n}\n\n/**\n * Converts a segment-like object to an insertion info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The insertion info object if the conversion is possible, otherwise undefined.\n */\nexport const toInsertionInfo = (segmentLike: unknown): IInsertionInfo | undefined =>\n\thasProp(segmentLike, \"clientId\", \"number\") && hasProp(segmentLike, \"seq\", \"number\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has insertion info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has insertion info, otherwise false.\n */\nexport const isInserted = (segmentLike: unknown): segmentLike is IInsertionInfo =>\n\ttoInsertionInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has insertion info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have insertion info.\n */\nexport const assertInserted: <T extends Partial<IInsertionInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IInsertionInfo> | T,\n) => asserts segmentLike is IInsertionInfo | Exclude<T, Partial<IInsertionInfo>> = (\n\tsegmentLike,\n) =>\n\tassert(\n\t\tsegmentLike === undefined || isInserted(segmentLike),\n\t\t0xaa0 /* must be insertionInfo */,\n\t);\n\n/**\n * Common properties for a node in a merge tree.\n */\nexport interface IMergeNodeInfo {\n\t/**\n\t * The parent merge block if the node is parented\n\t */\n\tparent: MergeBlock;\n\n\t/**\n\t * The index of this node in its parent's list of children.\n\t */\n\tindex: number;\n\n\t/**\n\t * A string that can be used for comparing the location of this node to other `MergeNode`s in the same tree.\n\t * `a.ordinal < b.ordinal` if and only if `a` comes before `b` in a pre-order traversal of the tree.\n\t */\n\tordinal: string;\n}\n\n/**\n * Converts a segment-like object to a merge node info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The merge node info object if the conversion is possible, otherwise undefined.\n */\nexport const toMergeNodeInfo = (nodeLike: unknown): IMergeNodeInfo | undefined =>\n\tpropInstanceOf(nodeLike, \"parent\", MergeBlock) &&\n\thasProp(nodeLike, \"ordinal\", \"string\") &&\n\thasProp(nodeLike, \"index\", \"number\")\n\t\t? nodeLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has merge node info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param nodeLike - The segment-like object to check.\n * @returns True if the segment has merge node info, otherwise false.\n */\nexport const isMergeNodeInfo = (nodeLike: unknown): nodeLike is IMergeNodeInfo =>\n\ttoMergeNodeInfo(nodeLike) !== undefined;\n\n/**\n * Asserts that the segment has merge node info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have merge node info.\n */\nexport const assertMergeNode: <T extends Partial<IMergeNodeInfo> | undefined>(\n\tnodeLike: ISegmentInternal | ISegmentPrivate | Partial<IMergeNodeInfo> | T,\n) => asserts nodeLike is IMergeNodeInfo | Exclude<T, Partial<IMergeNodeInfo>> = (\n\tsegmentLike,\n) =>\n\tassert(\n\t\tsegmentLike === undefined || isMergeNodeInfo(segmentLike),\n\t\t0xaa1 /* must be MergeNodeInfo */,\n\t);\n\n/**\n * Removes the merge node info. This is used to remove nodes from the merge-tree.\n * @param segmentLike - The segment-like object to check.\n * @returns This function will change the type of the provided node like to never via an assertion. This\n * ensures no further usage of the removed merge node info is allowed. if continued use is required other\n * type coercion methods should be used to correctly re-type the variable.\n */\nexport const removeMergeNodeInfo: (nodeLike: IMergeNodeInfo) => asserts nodeLike is never = (\n\tnodeLike,\n) =>\n\tObject.assign<IMergeNodeInfo, Record<keyof IMergeNodeInfo, undefined>>(nodeLike, {\n\t\tparent: undefined,\n\t\tindex: undefined,\n\t\tordinal: undefined,\n\t});\n\n/**\n * Contains removal information associated to an {@link ISegment}.\n */\nexport interface IRemovalInfo {\n\t/**\n\t * Local seq at which this segment was removed, if the removal is yet-to-be acked.\n\t */\n\tlocalRemovedSeq?: number;\n\t/**\n\t * Seq at which this segment was removed.\n\t */\n\tremovedSeq: number;\n\t/**\n\t * List of client IDs that have removed this segment.\n\t * The client that actually removed the segment (i.e. whose removal op was sequenced first) is stored as the first\n\t * client in this list. Other clients in the list have all issued concurrent ops to remove the segment.\n\t * @remarks When this list has length \\> 1, this is referred to as the \"overlapping remove\" case.\n\t */\n\tremovedClientIds: number[];\n}\n\n/**\n * Converts a segment-like object to a removal info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The removal info object if the conversion is possible, otherwise undefined.\n */\nexport const toRemovalInfo = (segmentLike: unknown): IRemovalInfo | undefined =>\n\thasProp(segmentLike, \"removedClientIds\", \"array\") &&\n\thasProp(segmentLike, \"removedSeq\", \"number\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has removal info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has removal info, otherwise false.\n */\nexport const isRemoved = (segmentLike: unknown): segmentLike is IRemovalInfo =>\n\ttoRemovalInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has removal info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have removal info.\n */\nexport const assertRemoved: <T extends Partial<IRemovalInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IRemovalInfo> | T,\n) => asserts segmentLike is IRemovalInfo | Exclude<T, Partial<IRemovalInfo>> = (segmentLike) =>\n\tassert(segmentLike === undefined || isRemoved(segmentLike), 0xaa2 /* must be removalInfo */);\n\n/**\n * Removes the removal info. This is used in rollback.\n * @param segmentLike - The segment-like object to check.\n * @returns This function will change the type of the provided node like to never via an assertion. This\n * ensures no further usage of the removed removal info is allowed. if continued use is required other\n * type coercion methods should be use to correctly re-type the variable.\n */\nexport const removeRemovalInfo: (nodeLike: IRemovalInfo) => asserts nodeLike is never = (\n\tnodeLike,\n) =>\n\tObject.assign<IRemovalInfo, Record<keyof IRemovalInfo, undefined>>(nodeLike, {\n\t\tlocalRemovedSeq: undefined,\n\t\tremovedClientIds: undefined,\n\t\tremovedSeq: undefined,\n\t});\n\n/**\n * Tracks information about when and where this segment was moved to.\n *\n * Note that merge-tree does not currently support moving and only supports\n * obliterate. The fields below include \"move\" in their names to avoid renaming\n * in the future, when moves _are_ supported.\n */\nexport interface IMoveInfo {\n\t/**\n\t * Local seq at which this segment was moved if the move is yet-to-be\n\t * acked.\n\t */\n\tlocalMovedSeq?: number;\n\n\t/**\n\t * The first seq at which this segment was moved.\n\t */\n\tmovedSeq: number;\n\n\t/**\n\t * All seqs at which this segment was moved. In the case of overlapping,\n\t * concurrent moves this array will contain multiple seqs.\n\t *\n\t * The seq at `movedSeqs[i]` corresponds to the client id at `movedClientIds[i]`.\n\t *\n\t * The first element corresponds to the seq of the first move\n\t */\n\tmovedSeqs: number[];\n\n\t/**\n\t * A reference to the inserted destination segment corresponding to this\n\t * segment's move.\n\t *\n\t * If undefined, the move was an obliterate.\n\t *\n\t * Currently this field is unused, as we only support obliterate operations\n\t */\n\tmoveDst?: ReferencePosition;\n\n\t/**\n\t * List of client IDs that have moved this segment.\n\t *\n\t * The client that actually moved the segment (i.e. whose move op was sequenced\n\t * first) is stored as the first client in this list. Other clients in the\n\t * list have all issued concurrent ops to move the segment.\n\t */\n\tmovedClientIds: number[];\n\n\t/**\n\t * If this segment was inserted into a concurrently moved range and\n\t * the move op was sequenced before the insertion op. In this case,\n\t * the segment is visible only to the inserting client\n\t *\n\t * `wasMovedOnInsert` only applies for acked obliterates. That is, if\n\t * a segment inserted by a remote client is moved on insertion by a local\n\t * and unacked obliterate, we do not consider it as having been moved\n\t * on insert\n\t *\n\t * If a segment is moved on insertion, its length is only ever visible to\n\t * the client that inserted the segment. This is relevant in partial length\n\t * calculations\n\t */\n\twasMovedOnInsert: boolean;\n}\nexport const toMoveInfo = (segmentLike: unknown): IMoveInfo | undefined =>\n\thasProp(segmentLike, \"movedClientIds\", \"array\") &&\n\thasProp(segmentLike, \"movedSeq\", \"number\") &&\n\thasProp(segmentLike, \"movedSeqs\", \"array\") &&\n\thasProp(segmentLike, \"wasMovedOnInsert\", \"boolean\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has move info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has move info, otherwise false.\n */\nexport const isMoved = (segmentLike: unknown): segmentLike is IMoveInfo =>\n\ttoMoveInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has move info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have move info.\n */\nexport const assertMoved: <T extends Partial<IMoveInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IMoveInfo> | T,\n) => asserts segmentLike is IMoveInfo | Exclude<T, Partial<IMoveInfo>> = (segmentLike) =>\n\tassert(segmentLike === undefined || isMoved(segmentLike), 0xaa3 /* must be moveInfo */);\n\n/**\n * A union type representing any segment info.\n */\nexport type SegmentInfo = IMergeNodeInfo | IInsertionInfo | IMoveInfo | IRemovalInfo;\n\n/**\n * A type representing a segment with additional info.\n */\nexport type SegmentWithInfo<\n\tT extends SegmentInfo,\n\tS extends ISegmentPrivate = ISegmentPrivate,\n> = S & T;\n\n/**\n * Overwrites the segment info on a segment-like object.\n *\n * @param segmentLike - The segment-like object to set the info on.\n * @param info - The segment info to overwrite.\n * @returns The segment-like object with the info set.\n */\nexport const overwriteInfo = <\n\tT extends SegmentInfo,\n\tS extends ISegmentPrivate = ISegmentPrivate,\n>(\n\tsegmentLike: S,\n\tinfo: T,\n): SegmentWithInfo<T, S> => Object.assign(segmentLike, info);\n"]}
1
+ {"version":3,"file":"segmentInfos.js","sourceRoot":"","sources":["../src/segmentInfos.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, isObject } from \"@fluidframework/core-utils/internal\";\n\nimport { ISegmentInternal, ISegmentPrivate, MergeBlock } from \"./mergeTreeNodes.js\";\nimport type { ReferencePosition } from \"./referencePositions.js\";\n\nexport interface StringToType {\n\t\"string\": string;\n\t\"number\": number;\n\t\"object\": object;\n\t\"array\": [];\n\t\"boolean\": boolean;\n}\n\nexport function propExists<P extends string>(\n\tthing: unknown,\n\tprop: P,\n): thing is Record<P, unknown> {\n\treturn isObject(thing) && prop in thing;\n}\n\nexport function hasProp<P extends string, T extends keyof StringToType>(\n\tthing: unknown,\n\tprop: P,\n\ttype: T,\n): thing is Record<P, StringToType[typeof type]> {\n\treturn (\n\t\tpropExists(thing, prop) &&\n\t\t(type === \"array\" ? Array.isArray(thing[prop]) : typeof thing[prop] === type)\n\t);\n}\n\nexport function propInstanceOf<P extends string, T>(\n\tthing: unknown,\n\tprop: P,\n\ttype: new (...args: any[]) => T,\n): thing is Record<P, T> {\n\treturn propExists(thing, prop) && thing[prop] instanceof type;\n}\n\n/**\n * Contains insertion information associated to an {@link ISegment}.\n */\nexport interface IInsertionInfo {\n\t/**\n\t * Short clientId for the client that inserted this segment.\n\t */\n\tclientId: number;\n\t/**\n\t * Local seq at which this segment was inserted.\n\t * This is defined if and only if the insertion of the segment is pending ack, i.e. `seq` is UnassignedSequenceNumber.\n\t * Once the segment is acked, this field is cleared.\n\t *\n\t * @privateRemarks\n\t * See {@link CollaborationWindow.localSeq} for more information on the semantics of localSeq.\n\t */\n\tlocalSeq?: number;\n\t/**\n\t * Seq at which this segment was inserted.\n\t * If undefined, it is assumed the segment was inserted prior to the collab window's minimum sequence number.\n\t */\n\tseq: number;\n}\n\n/**\n * Converts a segment-like object to an insertion info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The insertion info object if the conversion is possible, otherwise undefined.\n */\nexport const toInsertionInfo = (segmentLike: unknown): IInsertionInfo | undefined =>\n\thasProp(segmentLike, \"clientId\", \"number\") && hasProp(segmentLike, \"seq\", \"number\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has insertion info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has insertion info, otherwise false.\n */\nexport const isInserted = (segmentLike: unknown): segmentLike is IInsertionInfo =>\n\ttoInsertionInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has insertion info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have insertion info.\n */\nexport const assertInserted: <T extends Partial<IInsertionInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IInsertionInfo> | T,\n) => asserts segmentLike is IInsertionInfo | Exclude<T, Partial<IInsertionInfo>> = (\n\tsegmentLike,\n) =>\n\tassert(\n\t\tsegmentLike === undefined || isInserted(segmentLike),\n\t\t0xaa0 /* must be insertionInfo */,\n\t);\n\n/**\n * Common properties for a node in a merge tree.\n */\nexport interface IMergeNodeInfo {\n\t/**\n\t * The parent merge block if the node is parented\n\t */\n\tparent: MergeBlock;\n\n\t/**\n\t * The index of this node in its parent's list of children.\n\t */\n\tindex: number;\n\n\t/**\n\t * A string that can be used for comparing the location of this node to other `MergeNode`s in the same tree.\n\t * `a.ordinal < b.ordinal` if and only if `a` comes before `b` in a pre-order traversal of the tree.\n\t */\n\tordinal: string;\n}\n\n/**\n * Converts a segment-like object to a merge node info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The merge node info object if the conversion is possible, otherwise undefined.\n */\nexport const toMergeNodeInfo = (nodeLike: unknown): IMergeNodeInfo | undefined =>\n\tpropInstanceOf(nodeLike, \"parent\", MergeBlock) &&\n\thasProp(nodeLike, \"ordinal\", \"string\") &&\n\thasProp(nodeLike, \"index\", \"number\")\n\t\t? nodeLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has merge node info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param nodeLike - The segment-like object to check.\n * @returns True if the segment has merge node info, otherwise false.\n */\nexport const isMergeNodeInfo = (nodeLike: unknown): nodeLike is IMergeNodeInfo =>\n\ttoMergeNodeInfo(nodeLike) !== undefined;\n\n/**\n * Asserts that the segment has merge node info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have merge node info.\n */\nexport const assertMergeNode: <T extends Partial<IMergeNodeInfo> | undefined>(\n\tnodeLike: ISegmentInternal | ISegmentPrivate | Partial<IMergeNodeInfo> | T,\n) => asserts nodeLike is IMergeNodeInfo | Exclude<T, Partial<IMergeNodeInfo>> = (\n\tsegmentLike,\n) =>\n\tassert(\n\t\tsegmentLike === undefined || isMergeNodeInfo(segmentLike),\n\t\t0xaa1 /* must be MergeNodeInfo */,\n\t);\n\n/**\n * Removes the merge node info. This is used to remove nodes from the merge-tree.\n * @param segmentLike - The segment-like object to check.\n * @returns This function will change the type of the provided node like to never via an assertion. This\n * ensures no further usage of the removed merge node info is allowed. if continued use is required other\n * type coercion methods should be used to correctly re-type the variable.\n */\nexport const removeMergeNodeInfo: (nodeLike: IMergeNodeInfo) => asserts nodeLike is never = (\n\tnodeLike,\n) =>\n\tObject.assign<IMergeNodeInfo, Record<keyof IMergeNodeInfo, undefined>>(nodeLike, {\n\t\tparent: undefined,\n\t\tindex: undefined,\n\t\tordinal: undefined,\n\t});\n\n/**\n * Contains removal information associated to an {@link ISegment}.\n */\nexport interface IRemovalInfo {\n\t/**\n\t * Local seq at which this segment was removed, if the removal is yet-to-be acked.\n\t */\n\tlocalRemovedSeq?: number;\n\t/**\n\t * Seq at which this segment was removed.\n\t */\n\tremovedSeq: number;\n\t/**\n\t * List of client IDs that have removed this segment.\n\t * The client that actually removed the segment (i.e. whose removal op was sequenced first) is stored as the first\n\t * client in this list. Other clients in the list have all issued concurrent ops to remove the segment.\n\t * @remarks When this list has length \\> 1, this is referred to as the \"overlapping remove\" case.\n\t */\n\tremovedClientIds: number[];\n}\n\n/**\n * Converts a segment-like object to a removal info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The removal info object if the conversion is possible, otherwise undefined.\n */\nexport const toRemovalInfo = (segmentLike: unknown): IRemovalInfo | undefined =>\n\thasProp(segmentLike, \"removedClientIds\", \"array\") &&\n\thasProp(segmentLike, \"removedSeq\", \"number\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has removal info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has removal info, otherwise false.\n */\nexport const isRemoved = (segmentLike: unknown): segmentLike is IRemovalInfo =>\n\ttoRemovalInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has removal info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have removal info.\n */\nexport const assertRemoved: <T extends Partial<IRemovalInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IRemovalInfo> | T,\n) => asserts segmentLike is IRemovalInfo | Exclude<T, Partial<IRemovalInfo>> = (segmentLike) =>\n\tassert(segmentLike === undefined || isRemoved(segmentLike), 0xaa2 /* must be removalInfo */);\n\n/**\n * Removes the removal info. This is used in rollback.\n * @param segmentLike - The segment-like object to check.\n * @returns This function will change the type of the provided node like to never via an assertion. This\n * ensures no further usage of the removed removal info is allowed. if continued use is required other\n * type coercion methods should be use to correctly re-type the variable.\n */\nexport const removeRemovalInfo: (nodeLike: IRemovalInfo) => asserts nodeLike is never = (\n\tnodeLike,\n) =>\n\tObject.assign<IRemovalInfo, Record<keyof IRemovalInfo, undefined>>(nodeLike, {\n\t\tlocalRemovedSeq: undefined,\n\t\tremovedClientIds: undefined,\n\t\tremovedSeq: undefined,\n\t});\n\n/**\n * Tracks information about when and where this segment was moved to.\n *\n * Note that merge-tree does not currently support moving and only supports\n * obliterate. The fields below include \"move\" in their names to avoid renaming\n * in the future, when moves _are_ supported.\n */\nexport interface IMoveInfo {\n\t/**\n\t * Local seq at which this segment was moved if the move is yet-to-be\n\t * acked.\n\t */\n\tlocalMovedSeq?: number;\n\n\t/**\n\t * The first seq at which this segment was moved.\n\t */\n\tmovedSeq: number;\n\n\t/**\n\t * All seqs at which this segment was moved. In the case of overlapping,\n\t * concurrent moves this array will contain multiple seqs.\n\t *\n\t * The seq at `movedSeqs[i]` corresponds to the client id at `movedClientIds[i]`.\n\t *\n\t * The first element corresponds to the seq of the first move\n\t */\n\tmovedSeqs: number[];\n\n\t/**\n\t * A reference to the inserted destination segment corresponding to this\n\t * segment's move.\n\t *\n\t * If undefined, the move was an obliterate.\n\t *\n\t * Currently this field is unused, as we only support obliterate operations\n\t */\n\tmoveDst?: ReferencePosition;\n\n\t/**\n\t * List of client IDs that have moved this segment.\n\t *\n\t * The client that actually moved the segment (i.e. whose move op was sequenced\n\t * first) is stored as the first client in this list. Other clients in the\n\t * list have all issued concurrent ops to move the segment.\n\t */\n\tmovedClientIds: number[];\n\n\t/**\n\t * If this segment was inserted into a concurrently moved range and\n\t * the move op was sequenced before the insertion op. In this case,\n\t * the segment is visible only to the inserting client\n\t *\n\t * `wasMovedOnInsert` only applies for acked obliterates. That is, if\n\t * a segment inserted by a remote client is moved on insertion by a local\n\t * and unacked obliterate, we do not consider it as having been moved\n\t * on insert\n\t *\n\t * If a segment is moved on insertion, its length is only ever visible to\n\t * the client that inserted the segment. This is relevant in partial length\n\t * calculations\n\t *\n\t * @privateRemarks\n\t * TODO:AB#29553: This property is not persisted in the summary, but it should be.\n\t */\n\twasMovedOnInsert: boolean;\n}\nexport const toMoveInfo = (segmentLike: unknown): IMoveInfo | undefined =>\n\thasProp(segmentLike, \"movedClientIds\", \"array\") &&\n\thasProp(segmentLike, \"movedSeq\", \"number\") &&\n\thasProp(segmentLike, \"movedSeqs\", \"array\") &&\n\thasProp(segmentLike, \"wasMovedOnInsert\", \"boolean\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has move info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has move info, otherwise false.\n */\nexport const isMoved = (segmentLike: unknown): segmentLike is IMoveInfo =>\n\ttoMoveInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has move info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have move info.\n */\nexport const assertMoved: <T extends Partial<IMoveInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IMoveInfo> | T,\n) => asserts segmentLike is IMoveInfo | Exclude<T, Partial<IMoveInfo>> = (segmentLike) =>\n\tassert(segmentLike === undefined || isMoved(segmentLike), 0xaa3 /* must be moveInfo */);\n\n/**\n * A union type representing any segment info.\n */\nexport type SegmentInfo = IMergeNodeInfo | IInsertionInfo | IMoveInfo | IRemovalInfo;\n\n/**\n * A type representing a segment with additional info.\n */\nexport type SegmentWithInfo<\n\tT extends SegmentInfo,\n\tS extends ISegmentPrivate = ISegmentPrivate,\n> = S & T;\n\n/**\n * Overwrites the segment info on a segment-like object.\n *\n * @param segmentLike - The segment-like object to set the info on.\n * @param info - The segment info to overwrite.\n * @returns The segment-like object with the info set.\n */\nexport const overwriteInfo = <\n\tT extends SegmentInfo,\n\tS extends ISegmentPrivate = ISegmentPrivate,\n>(\n\tsegmentLike: S,\n\tinfo: T,\n): SegmentWithInfo<T, S> => Object.assign(segmentLike, info);\n"]}
@@ -30,7 +30,7 @@ export function copyPropertiesAndManager(source, destination) {
30
30
  destination.properties = clone(source.properties);
31
31
  }
32
32
  else {
33
- destination.propertyManager ?? (destination.propertyManager = new PropertiesManager());
33
+ destination.propertyManager ??= new PropertiesManager();
34
34
  source.propertyManager.copyTo(source.properties, destination);
35
35
  }
36
36
  }
@@ -70,7 +70,7 @@ const opToChanges = (op, seq) => [
70
70
  ]),
71
71
  ];
72
72
  function applyChanges(op, seg, seq, run) {
73
- const properties = (seg.properties ?? (seg.properties = createMap()));
73
+ const properties = (seg.properties ??= createMap());
74
74
  const deltas = {};
75
75
  for (const [key, value] of opToChanges(op, seq)) {
76
76
  run(properties, deltas, key, value);
@@ -232,7 +232,7 @@ export class PropertiesManager {
232
232
  * @param dest - The destination object containing properties and property manager.
233
233
  */
234
234
  copyTo(oldProps, dest) {
235
- const newManager = (dest.propertyManager ?? (dest.propertyManager = new PropertiesManager()));
235
+ const newManager = (dest.propertyManager ??= new PropertiesManager());
236
236
  dest.properties = clone(oldProps);
237
237
  for (const [key, { local, remote, msnConsensus }] of this.changes.entries()) {
238
238
  newManager.changes.set(key, {
@@ -1 +1 @@
1
- {"version":3,"file":"segmentPropertiesManager.js","sourceRoot":"","sources":["../src/segmentPropertiesManager.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\";\n\nimport { DoublyLinkedList, iterateListValuesWhile } from \"./collections/index.js\";\nimport { UnassignedSequenceNumber, UniversalSequenceNumber } from \"./constants.js\";\nimport type {\n\tAdjustParams,\n\tIMergeTreeAnnotateAdjustMsg,\n\tIMergeTreeAnnotateMsg,\n} from \"./ops.js\";\nimport { MapLike, PropertySet, clone, createMap } from \"./properties.js\";\n\n/**\n * @internal\n */\nexport enum PropertiesRollback {\n\t/**\n\t * Not in a rollback\n\t */\n\tNone,\n\n\t/**\n\t * Rollback\n\t */\n\tRollback,\n}\n/**\n * Minimally copies properties and the property manager from source to destination.\n * @internal\n */\nexport function copyPropertiesAndManager(\n\tsource: {\n\t\tproperties?: PropertySet;\n\t\tpropertyManager?: PropertiesManager;\n\t},\n\tdestination: {\n\t\tproperties?: PropertySet;\n\t\tpropertyManager?: PropertiesManager;\n\t},\n): void {\n\tif (source.properties) {\n\t\tif (source.propertyManager === undefined) {\n\t\t\tdestination.properties = clone(source.properties);\n\t\t} else {\n\t\t\tdestination.propertyManager ??= new PropertiesManager();\n\t\t\tsource.propertyManager.copyTo(source.properties, destination);\n\t\t}\n\t}\n}\n\ntype PropertyChange = {\n\tseq: number;\n} & ({ adjust: AdjustParams; raw?: undefined } | { raw: unknown; adjust?: undefined });\n\ninterface PropertyChanges {\n\tmsnConsensus: unknown;\n\tremote: DoublyLinkedList<PropertyChange>;\n\tlocal: DoublyLinkedList<PropertyChange>;\n}\n\nfunction computePropertyValue(\n\tconsensus: unknown,\n\t...changes: Iterable<PropertyChange>[]\n): unknown {\n\tlet computedValue: unknown = consensus;\n\tfor (const change of changes) {\n\t\tfor (const op of change) {\n\t\t\tconst { raw, adjust } = op;\n\t\t\tif (adjust === undefined) {\n\t\t\t\tcomputedValue = raw;\n\t\t\t} else {\n\t\t\t\tconst adjusted =\n\t\t\t\t\t(typeof computedValue === \"number\" ? computedValue : 0) + adjust.delta;\n\t\t\t\tif (adjust.max !== undefined && adjusted > adjust.max) {\n\t\t\t\t\tcomputedValue = adjust.max;\n\t\t\t\t} else if (adjust.min !== undefined && adjusted < adjust.min) {\n\t\t\t\t\tcomputedValue = adjust.min;\n\t\t\t\t} else {\n\t\t\t\t\tcomputedValue = adjusted;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn computedValue;\n}\n\n/**\n * @internal\n */\nexport type PropsOrAdjust =\n\t| Pick<IMergeTreeAnnotateAdjustMsg, \"props\" | \"adjust\">\n\t| Pick<IMergeTreeAnnotateMsg, \"props\" | \"adjust\">;\n\nconst opToChanges = (op: PropsOrAdjust, seq: number): [string, PropertyChange][] => [\n\t...Object.entries(op.props ?? {})\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t.map<[string, PropertyChange]>(([k, raw]) => [k, { raw, seq }])\n\t\t.filter(([_, v]) => v.raw !== undefined),\n\t...Object.entries(op.adjust ?? {}).map<[string, PropertyChange]>(([k, adjust]) => [\n\t\tk,\n\t\t{ adjust, seq },\n\t]),\n];\n\nfunction applyChanges(\n\top: PropsOrAdjust,\n\tseg: { properties?: MapLike<unknown> },\n\tseq: number,\n\trun: (\n\t\tproperties: MapLike<unknown>,\n\t\tdeltas: MapLike<unknown>,\n\t\tkey: string,\n\t\tvalue: PropertyChange,\n\t) => void,\n): MapLike<unknown> {\n\tconst properties = (seg.properties ??= createMap<unknown>());\n\tconst deltas: MapLike<unknown> = {};\n\tfor (const [key, value] of opToChanges(op, seq)) {\n\t\trun(properties, deltas, key, value);\n\t\tif (properties[key] === null) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\tdelete properties[key];\n\t\t}\n\t}\n\treturn deltas;\n}\n\n/**\n * The PropertiesManager class handles changes to properties, both remote and local.\n * It manages the lifecycle for local property changes, ensures all property changes are eventually consistent,\n * and provides methods to acknowledge changes, update the minimum sequence number (msn), and copy properties to another manager.\n * This class is essential for maintaining the integrity and consistency of property changes in collaborative environments.\n * @internal\n */\nexport class PropertiesManager {\n\tprivate readonly changes = new Map<string, PropertyChanges>();\n\n\t/**\n\t * Rolls back local property changes.\n\t * This method reverts property changes based on the provided operation and segment.\n\t * If the operation is part of a collaborative session, it ensures that the changes are consistent with the remote state.\n\t *\n\t * @param op - The operation containing property changes. This can be an adjustment or a set of properties.\n\t * @param seg - The segment containing properties. This object may have a properties map that will be modified.\n\t * @param collaborating - Indicates if the operation is part of a collaborative session. Defaults to false.\n\t * @returns The deltas of the rolled-back properties. This is a map-like object representing the changes that were reverted.\n\t */\n\tpublic rollbackProperties(\n\t\top: PropsOrAdjust,\n\t\tseg: { properties?: MapLike<unknown> },\n\t\tcollaborating: boolean = false,\n\t): MapLike<unknown> {\n\t\treturn applyChanges(op, seg, UniversalSequenceNumber, (properties, deltas, key, value) => {\n\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\tconst previousValue = properties[key] ?? null;\n\n\t\t\tconst pending = this.changes.get(key);\n\t\t\tif (collaborating) {\n\t\t\t\tassert(\n\t\t\t\t\tpending !== undefined,\n\t\t\t\t\t0xa6f /* Pending changes must exist for rollback when collaborating */,\n\t\t\t\t);\n\t\t\t\tpending.local.pop();\n\t\t\t\tproperties[key] = computePropertyValue(\n\t\t\t\t\tpending.msnConsensus,\n\t\t\t\t\tpending.remote.map((n) => n.data),\n\t\t\t\t\tpending.local.map((n) => n.data),\n\t\t\t\t);\n\t\t\t\tif (pending.local.empty && pending.remote.empty) {\n\t\t\t\t\tthis.changes.delete(key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tassert(\n\t\t\t\t\tpending === undefined,\n\t\t\t\t\t0xa70 /* Pending changes must not exist when not collaborating */,\n\t\t\t\t);\n\t\t\t\tproperties[key] = computePropertyValue(previousValue, [value]);\n\t\t\t}\n\t\t\tdeltas[key] = previousValue;\n\t\t});\n\t}\n\n\t/**\n\t * Handles property changes.\n\t * This method applies property changes based on the provided operation, segment, sequence number, and collaboration state.\n\t * It also handles rolling back changes if specified.\n\t *\n\t * @param op - The operation containing property changes.\n\t * @param seg - The segment containing properties.\n\t * @param seq - The sequence number for the operation.\n\t * @param msn - The minimum sequence number for the operation.\n\t * @param collaborating - Indicates if the operation is part of a collaborative session. Defaults to false.\n\t * @param rollback - Specifies if the changes should be rolled back. Defaults to PropertiesRollback.None.\n\t * @returns The deltas of the applied or rolled-back properties. This is a map-like object representing the changes.\n\t */\n\tpublic handleProperties(\n\t\top: PropsOrAdjust,\n\t\tseg: { properties?: MapLike<unknown> },\n\t\tseq: number,\n\t\tmsn: number,\n\t\tcollaborating: boolean = false,\n\t\trollback: PropertiesRollback = PropertiesRollback.None,\n\t): MapLike<unknown> {\n\t\tif (rollback === PropertiesRollback.Rollback) {\n\t\t\treturn this.rollbackProperties(op, seg, collaborating);\n\t\t}\n\t\tconst rtn = applyChanges(op, seg, seq, (properties, deltas, key, value) => {\n\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\tconst previousValue = properties[key] ?? null;\n\t\t\tif (collaborating) {\n\t\t\t\tconst pending: PropertyChanges | undefined = this.changes.get(key) ?? {\n\t\t\t\t\tmsnConsensus: previousValue,\n\t\t\t\t\tremote: new DoublyLinkedList(),\n\t\t\t\t\tlocal: new DoublyLinkedList(),\n\t\t\t\t};\n\t\t\t\tthis.changes.set(key, pending);\n\t\t\t\tconst local = seq === UnassignedSequenceNumber;\n\t\t\t\tif (local) {\n\t\t\t\t\tpending.local.push(value);\n\t\t\t\t} else {\n\t\t\t\t\t// we only track remotes if there are adjusts, as only adjusts make application anti-commutative\n\t\t\t\t\t// this will limit the impact of this change to only those using adjusts. Additionally, we only\n\t\t\t\t\t// need to track remotes at all to support emitting the legacy snapshot format, which only sharedstring\n\t\t\t\t\t// uses. when we remove the ability to emit that format, we can remove all remote op tracking\n\t\t\t\t\tif (value.raw !== undefined && pending.remote.empty) {\n\t\t\t\t\t\tpending.msnConsensus = computePropertyValue(pending.msnConsensus, [value]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpending.remote.push(value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tproperties[key] = computePropertyValue(\n\t\t\t\t\tpending.msnConsensus,\n\t\t\t\t\tpending.remote.map((n) => n.data),\n\t\t\t\t\tpending.local.map((n) => n.data),\n\t\t\t\t);\n\t\t\t\tif (local || pending.local.empty || properties[key] !== previousValue) {\n\t\t\t\t\tdeltas[key] = previousValue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tproperties[key] = computePropertyValue(previousValue, [value]);\n\t\t\t\tdeltas[key] = previousValue;\n\t\t\t}\n\t\t});\n\t\tthis.updateMsn(msn);\n\t\treturn rtn;\n\t}\n\n\t/**\n\t * Acknowledges property changes.\n\t * This method acknowledges the property changes based on the provided sequence number and operation.\n\t *\n\t * @param seq - The sequence number for the operation.\n\t * @param msn - The minimum sequence number for the operation.\n\t * @param op - The operation containing property changes.\n\t */\n\tpublic ack(seq: number, msn: number, op: PropsOrAdjust): void {\n\t\tfor (const [key, value] of opToChanges(op, seq)) {\n\t\t\tconst change = this.changes.get(key);\n\t\t\tconst acked = change?.local?.shift();\n\t\t\tassert(\n\t\t\t\tchange !== undefined && acked !== undefined,\n\t\t\t\t0xa71 /* must have local change to ack */,\n\t\t\t);\n\t\t\t// we only track remotes if there are adjusts, as only adjusts make application anti-commutative\n\t\t\t// this will limit the impact of this change to only those using adjusts. Additionally, we only\n\t\t\t// need to track remotes at all to support emitting the legacy snapshot format, which only sharedstring\n\t\t\t// uses. when we remove the ability to emit that format, we can remove all remote op tracking\n\t\t\tif (value.raw !== undefined && change.remote.empty) {\n\t\t\t\tchange.msnConsensus = computePropertyValue(change.msnConsensus, [value]);\n\t\t\t} else {\n\t\t\t\tchange.remote.push(value);\n\t\t\t}\n\t\t}\n\t\tthis.updateMsn(msn);\n\t}\n\n\t/**\n\t * Updates the minimum sequence number (msn).\n\t * This method updates the minimum sequence number and removes any changes that have been acknowledged.\n\t *\n\t * @param msn - The minimum sequence number to update.\n\t */\n\tpublic updateMsn(msn: number): void {\n\t\tfor (const [key, pending] of this.changes) {\n\t\t\tpending.msnConsensus = computePropertyValue(\n\t\t\t\tpending.msnConsensus,\n\t\t\t\titerateListValuesWhile(pending.remote.first, (n) => {\n\t\t\t\t\tif (n.data.seq <= msn) {\n\t\t\t\t\t\tn.list?.remove(n);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t}),\n\t\t\t);\n\t\t\tif (pending.local.empty && pending.remote.empty) {\n\t\t\t\tthis.changes.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Copies properties to another manager.\n\t * This method copies the properties and their changes from the current manager to the destination manager.\n\t *\n\t * @param oldProps - The old properties to be copied.\n\t * @param dest - The destination object containing properties and property manager.\n\t */\n\tpublic copyTo(\n\t\toldProps: PropertySet | undefined,\n\t\tdest: {\n\t\t\tproperties?: PropertySet;\n\t\t\tpropertyManager?: PropertiesManager;\n\t\t},\n\t): void {\n\t\tconst newManager = (dest.propertyManager ??= new PropertiesManager());\n\t\tdest.properties = clone(oldProps);\n\t\tfor (const [key, { local, remote, msnConsensus }] of this.changes.entries()) {\n\t\t\tnewManager.changes.set(key, {\n\t\t\t\tmsnConsensus,\n\t\t\t\tremote: new DoublyLinkedList(remote.empty ? undefined : remote.map((c) => c.data)),\n\t\t\t\tlocal: new DoublyLinkedList(local.empty ? undefined : local.map((c) => c.data)),\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Gets properties at a specific sequence number.\n\t * This method retrieves the properties at the given sequence number.\n\t * This is only needed to support emitting snapshots in the legacy format.\n\t * If we remove the ability to emit the legacy format, we can remove this method, along with the need to track remote changes at all.\n\t *\n\t * @param oldProps - The old properties to be retrieved.\n\t * @param sequenceNumber - The sequence number to get properties at.\n\t * @returns The properties at the given sequence number.\n\t */\n\tpublic getAtSeq(\n\t\toldProps: MapLike<unknown> | undefined,\n\t\tsequenceNumber: number,\n\t): MapLike<unknown> {\n\t\tconst properties: MapLike<unknown> = { ...oldProps };\n\t\tfor (const [key, changes] of this.changes) {\n\t\t\tproperties[key] = computePropertyValue(\n\t\t\t\tchanges.msnConsensus,\n\t\t\t\titerateListValuesWhile(changes.remote.first, (c) => c.data.seq <= sequenceNumber),\n\t\t\t);\n\t\t\tif (properties[key] === null) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete properties[key];\n\t\t\t}\n\t\t}\n\t\treturn properties;\n\t}\n\n\t/**\n\t * Determines if all of the defined properties in a given property set are pending.\n\t *\n\t * @param props - The properties to check.\n\t * @returns True if all the properties are pending, false otherwise.\n\t */\n\tpublic hasPendingProperties(props: PropertySet): boolean {\n\t\tfor (const [key, value] of Object.entries(props)) {\n\t\t\tif (value !== undefined && this.changes.get(key)?.local.empty !== false) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n"]}
1
+ {"version":3,"file":"segmentPropertiesManager.js","sourceRoot":"","sources":["../src/segmentPropertiesManager.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\";\n\nimport { DoublyLinkedList, iterateListValuesWhile } from \"./collections/index.js\";\nimport { UnassignedSequenceNumber, UniversalSequenceNumber } from \"./constants.js\";\nimport type {\n\tAdjustParams,\n\tIMergeTreeAnnotateAdjustMsg,\n\tIMergeTreeAnnotateMsg,\n} from \"./ops.js\";\nimport { MapLike, PropertySet, clone, createMap } from \"./properties.js\";\n\n/**\n * @internal\n */\nexport enum PropertiesRollback {\n\t/**\n\t * Not in a rollback\n\t */\n\tNone,\n\n\t/**\n\t * Rollback\n\t */\n\tRollback,\n}\n/**\n * Minimally copies properties and the property manager from source to destination.\n * @internal\n */\nexport function copyPropertiesAndManager(\n\tsource: {\n\t\tproperties?: PropertySet;\n\t\tpropertyManager?: PropertiesManager;\n\t},\n\tdestination: {\n\t\tproperties?: PropertySet;\n\t\tpropertyManager?: PropertiesManager;\n\t},\n): void {\n\tif (source.properties) {\n\t\tif (source.propertyManager === undefined) {\n\t\t\tdestination.properties = clone(source.properties);\n\t\t} else {\n\t\t\tdestination.propertyManager ??= new PropertiesManager();\n\t\t\tsource.propertyManager.copyTo(source.properties, destination);\n\t\t}\n\t}\n}\n\ntype PropertyChange = {\n\tseq: number;\n} & ({ adjust: AdjustParams; raw?: undefined } | { raw: unknown; adjust?: undefined });\n\ninterface PropertyChanges {\n\tmsnConsensus: unknown;\n\tremote: DoublyLinkedList<PropertyChange>;\n\tlocal: DoublyLinkedList<PropertyChange>;\n}\n\nfunction computePropertyValue(\n\tconsensus: unknown,\n\t...changes: Iterable<PropertyChange>[]\n): unknown {\n\tlet computedValue: unknown = consensus;\n\tfor (const change of changes) {\n\t\tfor (const op of change) {\n\t\t\tconst { raw, adjust } = op;\n\t\t\tif (adjust === undefined) {\n\t\t\t\tcomputedValue = raw;\n\t\t\t} else {\n\t\t\t\tconst adjusted =\n\t\t\t\t\t(typeof computedValue === \"number\" ? computedValue : 0) + adjust.delta;\n\t\t\t\tif (adjust.max !== undefined && adjusted > adjust.max) {\n\t\t\t\t\tcomputedValue = adjust.max;\n\t\t\t\t} else if (adjust.min !== undefined && adjusted < adjust.min) {\n\t\t\t\t\tcomputedValue = adjust.min;\n\t\t\t\t} else {\n\t\t\t\t\tcomputedValue = adjusted;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn computedValue;\n}\n\n/**\n * @internal\n */\nexport type PropsOrAdjust =\n\t| Pick<IMergeTreeAnnotateAdjustMsg, \"props\" | \"adjust\">\n\t| Pick<IMergeTreeAnnotateMsg, \"props\" | \"adjust\">;\n\nconst opToChanges = (op: PropsOrAdjust, seq: number): [string, PropertyChange][] => [\n\t...Object.entries(op.props ?? {})\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t.map<[string, PropertyChange]>(([k, raw]) => [k, { raw, seq }])\n\t\t.filter(([_, v]) => v.raw !== undefined),\n\t...Object.entries(op.adjust ?? {}).map<[string, PropertyChange]>(([k, adjust]) => [\n\t\tk,\n\t\t{ adjust, seq },\n\t]),\n];\n\nfunction applyChanges(\n\top: PropsOrAdjust,\n\tseg: { properties?: MapLike<unknown> },\n\tseq: number,\n\trun: (\n\t\tproperties: MapLike<unknown>,\n\t\tdeltas: MapLike<unknown>,\n\t\tkey: string,\n\t\tvalue: PropertyChange,\n\t) => void,\n): MapLike<unknown> {\n\tconst properties = (seg.properties ??= createMap<unknown>());\n\tconst deltas: MapLike<unknown> = {};\n\tfor (const [key, value] of opToChanges(op, seq)) {\n\t\trun(properties, deltas, key, value);\n\t\tif (properties[key] === null) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\tdelete properties[key];\n\t\t}\n\t}\n\treturn deltas;\n}\n\n/**\n * The PropertiesManager class handles changes to properties, both remote and local.\n * It manages the lifecycle for local property changes, ensures all property changes are eventually consistent,\n * and provides methods to acknowledge changes, update the minimum sequence number (msn), and copy properties to another manager.\n * This class is essential for maintaining the integrity and consistency of property changes in collaborative environments.\n * @internal\n */\nexport class PropertiesManager {\n\tprivate readonly changes = new Map<string, PropertyChanges>();\n\n\t/**\n\t * Rolls back local property changes.\n\t * This method reverts property changes based on the provided operation and segment.\n\t * If the operation is part of a collaborative session, it ensures that the changes are consistent with the remote state.\n\t *\n\t * @param op - The operation containing property changes. This can be an adjustment or a set of properties.\n\t * @param seg - The segment containing properties. This object may have a properties map that will be modified.\n\t * @param collaborating - Indicates if the operation is part of a collaborative session. Defaults to false.\n\t * @returns The deltas of the rolled-back properties. This is a map-like object representing the changes that were reverted.\n\t */\n\tpublic rollbackProperties(\n\t\top: PropsOrAdjust,\n\t\tseg: { properties?: MapLike<unknown> },\n\t\tcollaborating: boolean = false,\n\t): MapLike<unknown> {\n\t\treturn applyChanges(op, seg, UniversalSequenceNumber, (properties, deltas, key, value) => {\n\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\tconst previousValue = properties[key] ?? null;\n\n\t\t\tconst pending = this.changes.get(key);\n\t\t\tif (collaborating) {\n\t\t\t\tassert(\n\t\t\t\t\tpending !== undefined,\n\t\t\t\t\t0xa6f /* Pending changes must exist for rollback when collaborating */,\n\t\t\t\t);\n\t\t\t\tpending.local.pop();\n\t\t\t\tproperties[key] = computePropertyValue(\n\t\t\t\t\tpending.msnConsensus,\n\t\t\t\t\tpending.remote.map((n) => n.data),\n\t\t\t\t\tpending.local.map((n) => n.data),\n\t\t\t\t);\n\t\t\t\tif (pending.local.empty && pending.remote.empty) {\n\t\t\t\t\tthis.changes.delete(key);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tassert(\n\t\t\t\t\tpending === undefined,\n\t\t\t\t\t0xa70 /* Pending changes must not exist when not collaborating */,\n\t\t\t\t);\n\t\t\t\tproperties[key] = computePropertyValue(previousValue, [value]);\n\t\t\t}\n\t\t\tdeltas[key] = previousValue;\n\t\t});\n\t}\n\n\t/**\n\t * Handles property changes.\n\t * This method applies property changes based on the provided operation, segment, sequence number, and collaboration state.\n\t * It also handles rolling back changes if specified.\n\t *\n\t * @param op - The operation containing property changes.\n\t * @param seg - The segment containing properties.\n\t * @param seq - The sequence number for the operation.\n\t * @param msn - The minimum sequence number for the operation.\n\t * @param collaborating - Indicates if the operation is part of a collaborative session. Defaults to false.\n\t * @param rollback - Specifies if the changes should be rolled back. Defaults to PropertiesRollback.None.\n\t * @returns The deltas of the applied or rolled-back properties. This is a map-like object representing the changes.\n\t */\n\tpublic handleProperties(\n\t\top: PropsOrAdjust,\n\t\tseg: { properties?: MapLike<unknown> },\n\t\tseq: number,\n\t\tmsn: number,\n\t\tcollaborating: boolean = false,\n\t\trollback: PropertiesRollback = PropertiesRollback.None,\n\t): MapLike<unknown> {\n\t\tif (rollback === PropertiesRollback.Rollback) {\n\t\t\treturn this.rollbackProperties(op, seg, collaborating);\n\t\t}\n\t\tconst rtn = applyChanges(op, seg, seq, (properties, deltas, key, value) => {\n\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\tconst previousValue = properties[key] ?? null;\n\t\t\tif (collaborating) {\n\t\t\t\tconst pending: PropertyChanges | undefined = this.changes.get(key) ?? {\n\t\t\t\t\tmsnConsensus: previousValue,\n\t\t\t\t\tremote: new DoublyLinkedList(),\n\t\t\t\t\tlocal: new DoublyLinkedList(),\n\t\t\t\t};\n\t\t\t\tthis.changes.set(key, pending);\n\t\t\t\tconst local = seq === UnassignedSequenceNumber;\n\t\t\t\tif (local) {\n\t\t\t\t\tpending.local.push(value);\n\t\t\t\t} else {\n\t\t\t\t\t// we only track remotes if there are adjusts, as only adjusts make application anti-commutative\n\t\t\t\t\t// this will limit the impact of this change to only those using adjusts. Additionally, we only\n\t\t\t\t\t// need to track remotes at all to support emitting the legacy snapshot format, which only sharedstring\n\t\t\t\t\t// uses. when we remove the ability to emit that format, we can remove all remote op tracking\n\t\t\t\t\tif (value.raw !== undefined && pending.remote.empty) {\n\t\t\t\t\t\tpending.msnConsensus = computePropertyValue(pending.msnConsensus, [value]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpending.remote.push(value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tproperties[key] = computePropertyValue(\n\t\t\t\t\tpending.msnConsensus,\n\t\t\t\t\tpending.remote.map((n) => n.data),\n\t\t\t\t\tpending.local.map((n) => n.data),\n\t\t\t\t);\n\t\t\t\tif (local || pending.local.empty || properties[key] !== previousValue) {\n\t\t\t\t\tdeltas[key] = previousValue;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tproperties[key] = computePropertyValue(previousValue, [value]);\n\t\t\t\tdeltas[key] = previousValue;\n\t\t\t}\n\t\t});\n\t\tthis.updateMsn(msn);\n\t\treturn rtn;\n\t}\n\n\t/**\n\t * Acknowledges property changes.\n\t * This method acknowledges the property changes based on the provided sequence number and operation.\n\t *\n\t * @param seq - The sequence number for the operation.\n\t * @param msn - The minimum sequence number for the operation.\n\t * @param op - The operation containing property changes.\n\t */\n\tpublic ack(seq: number, msn: number, op: PropsOrAdjust): void {\n\t\tfor (const [key, value] of opToChanges(op, seq)) {\n\t\t\tconst change = this.changes.get(key);\n\t\t\tconst acked = change?.local?.shift();\n\t\t\tassert(\n\t\t\t\tchange !== undefined && acked !== undefined,\n\t\t\t\t0xa71 /* must have local change to ack */,\n\t\t\t);\n\t\t\t// we only track remotes if there are adjusts, as only adjusts make application anti-commutative\n\t\t\t// this will limit the impact of this change to only those using adjusts. Additionally, we only\n\t\t\t// need to track remotes at all to support emitting the legacy snapshot format, which only sharedstring\n\t\t\t// uses. when we remove the ability to emit that format, we can remove all remote op tracking\n\t\t\tif (value.raw !== undefined && change.remote.empty) {\n\t\t\t\tchange.msnConsensus = computePropertyValue(change.msnConsensus, [value]);\n\t\t\t} else {\n\t\t\t\tchange.remote.push(value);\n\t\t\t}\n\t\t}\n\t\tthis.updateMsn(msn);\n\t}\n\n\t/**\n\t * Updates the minimum sequence number (msn).\n\t * This method updates the minimum sequence number and removes any changes that have been acknowledged.\n\t *\n\t * @param msn - The minimum sequence number to update.\n\t */\n\tpublic updateMsn(msn: number): void {\n\t\tfor (const [key, pending] of this.changes) {\n\t\t\tpending.msnConsensus = computePropertyValue(\n\t\t\t\tpending.msnConsensus,\n\t\t\t\titerateListValuesWhile(pending.remote.first, (n) => {\n\t\t\t\t\tif (n.data.seq <= msn) {\n\t\t\t\t\t\tn.list?.remove(n);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t}),\n\t\t\t);\n\t\t\tif (pending.local.empty && pending.remote.empty) {\n\t\t\t\tthis.changes.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Copies properties to another manager.\n\t * This method copies the properties and their changes from the current manager to the destination manager.\n\t *\n\t * @param oldProps - The old properties to be copied.\n\t * @param dest - The destination object containing properties and property manager.\n\t */\n\tpublic copyTo(\n\t\toldProps: PropertySet | undefined,\n\t\tdest: {\n\t\t\tproperties?: PropertySet;\n\t\t\tpropertyManager?: PropertiesManager;\n\t\t},\n\t): void {\n\t\tconst newManager = (dest.propertyManager ??= new PropertiesManager());\n\t\tdest.properties = clone(oldProps);\n\t\tfor (const [key, { local, remote, msnConsensus }] of this.changes.entries()) {\n\t\t\tnewManager.changes.set(key, {\n\t\t\t\tmsnConsensus,\n\t\t\t\tremote: new DoublyLinkedList(remote.empty ? undefined : remote.map((c) => c.data)),\n\t\t\t\tlocal: new DoublyLinkedList(local.empty ? undefined : local.map((c) => c.data)),\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Gets properties at a specific sequence number.\n\t * This method retrieves the properties at the given sequence number.\n\t * This is only needed to support emitting snapshots in the legacy format.\n\t * If we remove the ability to emit the legacy format, we can remove this method, along with the need to track remote changes at all.\n\t *\n\t * @param oldProps - The old properties to be retrieved.\n\t * @param sequenceNumber - The sequence number to get properties at.\n\t * @returns The properties at the given sequence number.\n\t */\n\tpublic getAtSeq(\n\t\toldProps: MapLike<unknown> | undefined,\n\t\tsequenceNumber: number,\n\t): MapLike<unknown> {\n\t\tconst properties: MapLike<unknown> = { ...oldProps };\n\t\tfor (const [key, changes] of this.changes) {\n\t\t\tproperties[key] = computePropertyValue(\n\t\t\t\tchanges.msnConsensus,\n\t\t\t\titerateListValuesWhile(changes.remote.first, (c) => c.data.seq <= sequenceNumber),\n\t\t\t);\n\t\t\tif (properties[key] === null) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete properties[key];\n\t\t\t}\n\t\t}\n\t\treturn properties;\n\t}\n\n\t/**\n\t * Determines if all of the defined properties in a given property set are pending.\n\t *\n\t * @param props - The properties to check.\n\t * @returns True if all the properties are pending, false otherwise.\n\t */\n\tpublic hasPendingProperties(props: PropertySet): boolean {\n\t\tfor (const [key, value] of Object.entries(props)) {\n\t\t\tif (value !== undefined && this.changes.get(key)?.local.empty !== false) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n}\n"]}
@@ -33,7 +33,7 @@ export class SnapshotLoader {
33
33
  // spanning the snapshot, which should be rare
34
34
  const specAsBuggyFormat = spec;
35
35
  if (specAsBuggyFormat.removedClient !== undefined) {
36
- spec.removedClientIds ?? (spec.removedClientIds = [specAsBuggyFormat.removedClient]);
36
+ spec.removedClientIds ??= [specAsBuggyFormat.removedClient];
37
37
  }
38
38
  assert(spec.removedClientIds !== undefined, 0xaac /* must have removedClient ids */);
39
39
  overwriteInfo(seg, {
@@ -47,7 +47,7 @@ export class SnapshotLoader {
47
47
  movedSeq: spec.movedSeq,
48
48
  movedSeqs: spec.movedSeqs,
49
49
  movedClientIds: spec.movedClientIds.map((id) => this.client.getOrAddShortClientId(id)),
50
- // BUG? This isn't persisted
50
+ // TODO:AB#29553: This property should be derived from segment data, not hard-coded.
51
51
  wasMovedOnInsert: false,
52
52
  });
53
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"snapshotLoader.js","sourceRoot":"","sources":["../src/snapshotLoader.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\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { bufferToString } from \"@fluid-internal/client-utils\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tUsageError,\n\tcreateChildLogger,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { Client } from \"./client.js\";\nimport { NonCollabClient, UniversalSequenceNumber } from \"./constants.js\";\nimport { MergeTree } from \"./mergeTree.js\";\nimport { ISegmentPrivate } from \"./mergeTreeNodes.js\";\nimport { IJSONSegment } from \"./ops.js\";\nimport {\n\tIRemovalInfo,\n\toverwriteInfo,\n\ttype IInsertionInfo,\n\ttype IMoveInfo,\n\ttype SegmentWithInfo,\n} from \"./segmentInfos.js\";\nimport {\n\tIJSONSegmentWithMergeInfo,\n\tMergeTreeChunkV1,\n\thasMergeInfo,\n} from \"./snapshotChunks.js\";\nimport { SnapshotV1 } from \"./snapshotV1.js\";\nimport { SnapshotLegacy } from \"./snapshotlegacy.js\";\n\nexport class SnapshotLoader {\n\tprivate readonly logger: ITelemetryLoggerExt;\n\n\tconstructor(\n\t\tprivate readonly runtime: IFluidDataStoreRuntime,\n\n\t\tprivate readonly client: Client,\n\t\tprivate readonly mergeTree: MergeTree,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tprivate readonly serializer: IFluidSerializer,\n\t) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"SnapshotLoader\" });\n\t}\n\n\tpublic async initialize(\n\t\tservices: IChannelStorageService,\n\t): Promise<{ catchupOpsP: Promise<ISequencedDocumentMessage[]> }> {\n\t\tconst headerLoadedP = services.readBlob(SnapshotLegacy.header).then((header) => {\n\t\t\tassert(!!header, 0x05f /* \"Missing blob header on legacy snapshot!\" */);\n\t\t\treturn this.loadHeader(bufferToString(header, \"utf8\"));\n\t\t});\n\n\t\tconst catchupOpsP = this.loadBodyAndCatchupOps(headerLoadedP, services);\n\n\t\tcatchupOpsP.catch((error) =>\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"CatchupOpsLoadFailure\" }, error),\n\t\t);\n\n\t\tawait headerLoadedP;\n\n\t\treturn { catchupOpsP };\n\t}\n\n\tprivate async loadBodyAndCatchupOps(\n\t\theaderChunkP: Promise<MergeTreeChunkV1>,\n\t\tservices: IChannelStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst blobsP = services.list(\"\");\n\t\tconst headerChunk = await headerChunkP;\n\n\t\t// TODO we shouldn't need to wait on the body being complete to finish initialization.\n\t\t// To fully support this we need to be able to process inbound ops for pending segments.\n\t\tawait this.loadBody(headerChunk, services);\n\n\t\tconst blobs = await blobsP;\n\t\tif (blobs.length === headerChunk.headerMetadata!.orderedChunkMetadata.length + 1) {\n\t\t\tfor (const md of headerChunk.headerMetadata!.orderedChunkMetadata)\n\t\t\t\tblobs.splice(blobs.indexOf(md.id), 1);\n\t\t\tassert(blobs.length === 1, 0x060 /* There should be only one blob with catch up ops */);\n\n\t\t\t// TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.\n\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\n\t\t\treturn this.loadCatchupOps(services.readBlob(blobs[0]), this.serializer);\n\t\t} else if (blobs.length !== headerChunk.headerMetadata!.orderedChunkMetadata.length) {\n\t\t\tthrow new Error(\"Unexpected blobs in snapshot\");\n\t\t}\n\t\treturn [];\n\t}\n\n\tprivate readonly specToSegment = (\n\t\tspec: IJSONSegment | IJSONSegmentWithMergeInfo,\n\t): SegmentWithInfo<IInsertionInfo> => {\n\t\tif (hasMergeInfo(spec)) {\n\t\t\tconst seg = overwriteInfo<IInsertionInfo>(this.client.specToSegment(spec.json), {\n\t\t\t\tclientId:\n\t\t\t\t\tspec.client === undefined\n\t\t\t\t\t\t? NonCollabClient\n\t\t\t\t\t\t: this.client.getOrAddShortClientId(spec.client),\n\t\t\t\tseq: spec.seq ?? UniversalSequenceNumber,\n\t\t\t});\n\n\t\t\tif (spec.removedSeq !== undefined) {\n\t\t\t\t// this format had a bug where it didn't store all the overlap clients\n\t\t\t\t// this is for back compat, so we change the singular id to an array\n\t\t\t\t// this will only cause problems if there is an overlapping delete\n\t\t\t\t// spanning the snapshot, which should be rare\n\t\t\t\tconst specAsBuggyFormat: IJSONSegmentWithMergeInfo & { removedClient?: string } = spec;\n\t\t\t\tif (specAsBuggyFormat.removedClient !== undefined) {\n\t\t\t\t\tspec.removedClientIds ??= [specAsBuggyFormat.removedClient];\n\t\t\t\t}\n\t\t\t\tassert(spec.removedClientIds !== undefined, 0xaac /* must have removedClient ids */);\n\t\t\t\toverwriteInfo<IRemovalInfo>(seg, {\n\t\t\t\t\tremovedSeq: spec.removedSeq,\n\t\t\t\t\tremovedClientIds: spec.removedClientIds.map((id) =>\n\t\t\t\t\t\tthis.client.getOrAddShortClientId(id),\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (spec.movedSeq !== undefined) {\n\t\t\t\tassert(\n\t\t\t\t\tspec.movedClientIds !== undefined && spec.movedSeqs !== undefined,\n\t\t\t\t\t0xaa5 /* must have movedIds ids */,\n\t\t\t\t);\n\t\t\t\toverwriteInfo<IMoveInfo>(seg, {\n\t\t\t\t\tmovedSeq: spec.movedSeq,\n\t\t\t\t\tmovedSeqs: spec.movedSeqs,\n\t\t\t\t\tmovedClientIds: spec.movedClientIds.map((id) =>\n\t\t\t\t\t\tthis.client.getOrAddShortClientId(id),\n\t\t\t\t\t),\n\t\t\t\t\t// BUG? This isn't persisted\n\t\t\t\t\twasMovedOnInsert: false,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn seg;\n\t\t}\n\t\treturn overwriteInfo(this.client.specToSegment(spec), {\n\t\t\tseq: UniversalSequenceNumber,\n\t\t\tclientId: NonCollabClient,\n\t\t});\n\t};\n\n\tprivate loadHeader(header: string): MergeTreeChunkV1 {\n\t\tconst chunk = SnapshotV1.processChunk(\n\t\t\tSnapshotLegacy.header,\n\t\t\theader,\n\t\t\tthis.logger,\n\t\t\tthis.mergeTree.options,\n\t\t\tthis.serializer,\n\t\t);\n\t\tconst segs = chunk.segments.map((element) => this.specToSegment(element));\n\t\tthis.extractAttribution(segs, chunk);\n\n\t\tthis.mergeTree.reloadFromSegments(segs);\n\n\t\tif (chunk.headerMetadata === undefined) {\n\t\t\tthrow new Error(\"header metadata not available\");\n\t\t}\n\t\t// If we load a detached container from snapshot, then we don't supply a default clientId\n\t\t// because we don't want to start collaboration.\n\t\tif (this.runtime.attachState !== AttachState.Detached) {\n\t\t\t// specify a default client id, \"snapshot\" here as we\n\t\t\t// should enter collaboration/op sending mode if we load\n\t\t\t// a snapshot in any case (summary or attach message)\n\t\t\t// once we get a client id this will be called with that\n\t\t\t// clientId in the connected event\n\t\t\tthis.client.startOrUpdateCollaboration(\n\t\t\t\tthis.runtime.clientId ?? \"snapshot\",\n\n\t\t\t\t// TODO: Make 'minSeq' non-optional once the new snapshot format becomes the default?\n\t\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\t\t\t\t/* minSeq: */ chunk.headerMetadata.minSequenceNumber ??\n\t\t\t\t\tchunk.headerMetadata.sequenceNumber,\n\t\t\t\t/* currentSeq: */ chunk.headerMetadata.sequenceNumber,\n\t\t\t);\n\t\t}\n\n\t\treturn chunk;\n\t}\n\n\tprivate async loadBody(\n\t\tchunk1: MergeTreeChunkV1,\n\t\tservices: IChannelStorageService,\n\t): Promise<void> {\n\t\tconst headerMetadata = chunk1.headerMetadata!;\n\t\tassert(chunk1.length <= headerMetadata.totalLength, 0x061 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount <= headerMetadata.totalSegmentCount,\n\t\t\t0x062 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\tif (chunk1.segmentCount === headerMetadata.totalSegmentCount) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet chunksWithAttribution = chunk1.attribution === undefined ? 0 : 1;\n\t\tconst segs: SegmentWithInfo<IInsertionInfo>[] = [];\n\t\tlet lengthSofar = chunk1.length;\n\t\tfor (\n\t\t\tlet chunkIndex = 1;\n\t\t\tchunkIndex < headerMetadata.orderedChunkMetadata.length;\n\t\t\tchunkIndex++\n\t\t) {\n\t\t\tconst chunk = await SnapshotV1.loadChunk(\n\t\t\t\tservices,\n\t\t\t\theaderMetadata.orderedChunkMetadata[chunkIndex].id,\n\t\t\t\tthis.logger,\n\t\t\t\tthis.mergeTree.options,\n\t\t\t\tthis.serializer,\n\t\t\t);\n\t\t\tlengthSofar += chunk.length;\n\t\t\t// Deserialize each chunk segment and append it to the end of the MergeTree.\n\t\t\tconst newSegs = chunk.segments.map((element) => this.specToSegment(element));\n\t\t\tthis.extractAttribution(newSegs, chunk);\n\t\t\tchunksWithAttribution += chunk.attribution === undefined ? 0 : 1;\n\t\t\tsegs.push(...newSegs);\n\t\t}\n\n\t\tassert(\n\t\t\tchunksWithAttribution === 0 ||\n\t\t\t\tchunksWithAttribution === headerMetadata.orderedChunkMetadata.length,\n\t\t\t0x4c0 /* all or no chunks should have attribution information */,\n\t\t);\n\n\t\tassert(lengthSofar === headerMetadata.totalLength, 0x063 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount + segs.length === headerMetadata.totalSegmentCount,\n\t\t\t0x064 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\t// Helper to insert segments at the end of the MergeTree.\n\t\tconst mergeTree = this.mergeTree;\n\t\tconst append = (segments: ISegmentPrivate[], cli: number, seq: number): void => {\n\t\t\tmergeTree.insertSegments(\n\t\t\t\tmergeTree.root.cachedLength ?? 0,\n\t\t\t\tsegments,\n\t\t\t\t/* refSeq: */ UniversalSequenceNumber,\n\t\t\t\tcli,\n\t\t\t\tseq,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t};\n\n\t\t// Helpers to batch-insert segments that are below the min seq\n\t\tconst batch: SegmentWithInfo<IInsertionInfo>[] = [];\n\t\tconst flushBatch = (): void => {\n\t\t\tif (batch.length > 0) {\n\t\t\t\tappend(batch, NonCollabClient, UniversalSequenceNumber);\n\t\t\t}\n\t\t};\n\n\t\tfor (const seg of segs) {\n\t\t\tconst { clientId, seq } = seg;\n\t\t\t// If the segment can be batch inserted, add it to the 'batch' array. Otherwise, flush\n\t\t\t// any batched segments and then insert the current segment individually.\n\t\t\tif (clientId === NonCollabClient && seq === UniversalSequenceNumber) {\n\t\t\t\tbatch.push(seg);\n\t\t\t} else {\n\t\t\t\tflushBatch();\n\t\t\t\tappend([seg], clientId, seq);\n\t\t\t}\n\t\t}\n\n\t\tflushBatch();\n\t}\n\n\tprivate extractAttribution(segments: ISegmentPrivate[], chunk: MergeTreeChunkV1): void {\n\t\tif (chunk.attribution) {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy === undefined) {\n\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\"Attribution policy must be provided when loading a document with attribution information.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { isAttached, attach, serializer } = attributionPolicy;\n\t\t\tif (!isAttached) {\n\t\t\t\tattach(this.client);\n\t\t\t}\n\t\t\tserializer.populateAttributionCollections(segments, chunk.attribution);\n\t\t} else {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy?.isAttached) {\n\t\t\t\tattributionPolicy?.detach();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If loading from a snapshot, get the catchup messages.\n\t * @param rawMessages - The messages in original encoding\n\t * @returns The decoded messages with parsed+hydrated handles. Matches the format that will be passed in\n\t * SharedObject.processCore.\n\t */\n\tprivate async loadCatchupOps(\n\t\trawMessages: Promise<ArrayBufferLike>,\n\t\tserializer: IFluidSerializer,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\treturn serializer.parse(\n\t\t\tbufferToString(await rawMessages, \"utf8\"),\n\t\t) as ISequencedDocumentMessage[];\n\t}\n}\n"]}
1
+ {"version":3,"file":"snapshotLoader.js","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6DAA6D;AAE7D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAO7D,OAAO,EAEN,UAAU,EACV,iBAAiB,GACjB,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAI1E,OAAO,EAEN,aAAa,GAIb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAGN,YAAY,GACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,OAAO,cAAc;IAG1B,YACkB,OAA+B,EAE/B,MAAc,EACd,SAAoB,EACrC,MAA2B,EACV,UAA4B;QAL5B,YAAO,GAAP,OAAO,CAAwB;QAE/B,WAAM,GAAN,MAAM,CAAQ;QACd,cAAS,GAAT,SAAS,CAAW;QAEpB,eAAU,GAAV,UAAU,CAAkB;QAmD7B,kBAAa,GAAG,CAChC,IAA8C,EACZ,EAAE;YACpC,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,GAAG,GAAG,aAAa,CAAiB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;oBAC/E,QAAQ,EACP,IAAI,CAAC,MAAM,KAAK,SAAS;wBACxB,CAAC,CAAC,eAAe;wBACjB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC;oBAClD,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,uBAAuB;iBACxC,CAAC,CAAC;gBAEH,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;oBACnC,sEAAsE;oBACtE,oEAAoE;oBACpE,kEAAkE;oBAClE,8CAA8C;oBAC9C,MAAM,iBAAiB,GAA2D,IAAI,CAAC;oBACvF,IAAI,iBAAiB,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;wBACnD,IAAI,CAAC,gBAAgB,KAAK,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;oBAC7D,CAAC;oBACD,MAAM,CAAC,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE,KAAK,CAAC,iCAAiC,CAAC,CAAC;oBACrF,aAAa,CAAe,GAAG,EAAE;wBAChC,UAAU,EAAE,IAAI,CAAC,UAAU;wBAC3B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAClD,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,CAAC,CACrC;qBACD,CAAC,CAAC;gBACJ,CAAC;gBACD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;oBACjC,MAAM,CACL,IAAI,CAAC,cAAc,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EACjE,KAAK,CAAC,4BAA4B,CAClC,CAAC;oBACF,aAAa,CAAY,GAAG,EAAE;wBAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;wBACvB,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAC9C,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,CAAC,CACrC;wBACD,oFAAoF;wBACpF,gBAAgB,EAAE,KAAK;qBACvB,CAAC,CAAC;gBACJ,CAAC;gBAED,OAAO,GAAG,CAAC;YACZ,CAAC;YACD,OAAO,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE;gBACrD,GAAG,EAAE,uBAAuB;gBAC5B,QAAQ,EAAE,eAAe;aACzB,CAAC,CAAC;QACJ,CAAC,CAAC;QApGD,IAAI,CAAC,MAAM,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC1E,CAAC;IAEM,KAAK,CAAC,UAAU,CACtB,QAAgC;QAEhC,MAAM,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YAC9E,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,+CAA+C,CAAC,CAAC;YACxE,OAAO,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QAExE,WAAW,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAC3B,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,uBAAuB,EAAE,EAAE,KAAK,CAAC,CACzE,CAAC;QAEF,MAAM,aAAa,CAAC;QAEpB,OAAO,EAAE,WAAW,EAAE,CAAC;IACxB,CAAC;IAEO,KAAK,CAAC,qBAAqB,CAClC,YAAuC,EACvC,QAAgC;QAEhC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC;QAEvC,sFAAsF;QACtF,wFAAwF;QACxF,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAE3C,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC;QAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,CAAC,cAAe,CAAC,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClF,KAAK,MAAM,EAAE,IAAI,WAAW,CAAC,cAAe,CAAC,oBAAoB;gBAChE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACvC,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,CAAC,qDAAqD,CAAC,CAAC;YAExF,oFAAoF;YACpF,oEAAoE;YAEpE,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1E,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,CAAC,cAAe,CAAC,oBAAoB,CAAC,MAAM,EAAE,CAAC;YACrF,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;IAuDO,UAAU,CAAC,MAAc;QAChC,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,CACpC,cAAc,CAAC,MAAM,EACrB,MAAM,EACN,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,SAAS,CAAC,OAAO,EACtB,IAAI,CAAC,UAAU,CACf,CAAC;QACF,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAErC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAExC,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAClD,CAAC;QACD,yFAAyF;QACzF,gDAAgD;QAChD,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,WAAW,CAAC,QAAQ,EAAE,CAAC;YACvD,qDAAqD;YACrD,wDAAwD;YACxD,qDAAqD;YACrD,wDAAwD;YACxD,kCAAkC;YAClC,IAAI,CAAC,MAAM,CAAC,0BAA0B,CACrC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,UAAU;YAEnC,qFAAqF;YACrF,oEAAoE;YACpE,aAAa,CAAC,KAAK,CAAC,cAAc,CAAC,iBAAiB;gBACnD,KAAK,CAAC,cAAc,CAAC,cAAc;YACpC,iBAAiB,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CACrD,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,QAAQ,CACrB,MAAwB,EACxB,QAAgC;QAEhC,MAAM,cAAc,GAAG,MAAM,CAAC,cAAe,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAE3F,MAAM,CACL,MAAM,CAAC,YAAY,IAAI,cAAc,CAAC,iBAAiB,EACvD,KAAK,CAAC,qCAAqC,CAC3C,CAAC;QAEF,IAAI,MAAM,CAAC,YAAY,KAAK,cAAc,CAAC,iBAAiB,EAAE,CAAC;YAC9D,OAAO;QACR,CAAC;QAED,IAAI,qBAAqB,GAAG,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,IAAI,GAAsC,EAAE,CAAC;QACnD,IAAI,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;QAChC,KACC,IAAI,UAAU,GAAG,CAAC,EAClB,UAAU,GAAG,cAAc,CAAC,oBAAoB,CAAC,MAAM,EACvD,UAAU,EAAE,EACX,CAAC;YACF,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,SAAS,CACvC,QAAQ,EACR,cAAc,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,EAAE,EAClD,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,SAAS,CAAC,OAAO,EACtB,IAAI,CAAC,UAAU,CACf,CAAC;YACF,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC;YAC5B,4EAA4E;YAC5E,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7E,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACxC,qBAAqB,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACjE,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;QACvB,CAAC;QAED,MAAM,CACL,qBAAqB,KAAK,CAAC;YAC1B,qBAAqB,KAAK,cAAc,CAAC,oBAAoB,CAAC,MAAM,EACrE,KAAK,CAAC,0DAA0D,CAChE,CAAC;QAEF,MAAM,CAAC,WAAW,KAAK,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAE1F,MAAM,CACL,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,KAAK,cAAc,CAAC,iBAAiB,EACtE,KAAK,CAAC,qCAAqC,CAC3C,CAAC;QAEF,yDAAyD;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,MAAM,MAAM,GAAG,CAAC,QAA2B,EAAE,GAAW,EAAE,GAAW,EAAQ,EAAE;YAC9E,SAAS,CAAC,cAAc,CACvB,SAAS,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,EAChC,QAAQ;YACR,aAAa,CAAC,uBAAuB,EACrC,GAAG,EACH,GAAG,EACH,SAAS,CACT,CAAC;QACH,CAAC,CAAC;QAEF,8DAA8D;QAC9D,MAAM,KAAK,GAAsC,EAAE,CAAC;QACpD,MAAM,UAAU,GAAG,GAAS,EAAE;YAC7B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,uBAAuB,CAAC,CAAC;YACzD,CAAC;QACF,CAAC,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;YAC9B,uFAAuF;YACvF,yEAAyE;YACzE,IAAI,QAAQ,KAAK,eAAe,IAAI,GAAG,KAAK,uBAAuB,EAAE,CAAC;gBACrE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACP,UAAU,EAAE,CAAC;gBACb,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;YAC9B,CAAC;QACF,CAAC;QAED,UAAU,EAAE,CAAC;IACd,CAAC;IAEO,kBAAkB,CAAC,QAA2B,EAAE,KAAuB;QAC9E,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;YAC7C,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;gBACrC,MAAM,IAAI,UAAU,CACnB,2FAA2F,CAC3F,CAAC;YACH,CAAC;YAED,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAAC;YAC7D,IAAI,CAAC,UAAU,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrB,CAAC;YACD,UAAU,CAAC,8BAA8B,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACP,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;YAC7C,IAAI,iBAAiB,EAAE,UAAU,EAAE,CAAC;gBACnC,iBAAiB,EAAE,MAAM,EAAE,CAAC;YAC7B,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,cAAc,CAC3B,WAAqC,EACrC,UAA4B;QAE5B,OAAO,UAAU,CAAC,KAAK,CACtB,cAAc,CAAC,MAAM,WAAW,EAAE,MAAM,CAAC,CACV,CAAC;IAClC,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { bufferToString } from \"@fluid-internal/client-utils\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport {\n\tITelemetryLoggerExt,\n\tUsageError,\n\tcreateChildLogger,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { Client } from \"./client.js\";\nimport { NonCollabClient, UniversalSequenceNumber } from \"./constants.js\";\nimport { MergeTree } from \"./mergeTree.js\";\nimport { ISegmentPrivate } from \"./mergeTreeNodes.js\";\nimport { IJSONSegment } from \"./ops.js\";\nimport {\n\tIRemovalInfo,\n\toverwriteInfo,\n\ttype IInsertionInfo,\n\ttype IMoveInfo,\n\ttype SegmentWithInfo,\n} from \"./segmentInfos.js\";\nimport {\n\tIJSONSegmentWithMergeInfo,\n\tMergeTreeChunkV1,\n\thasMergeInfo,\n} from \"./snapshotChunks.js\";\nimport { SnapshotV1 } from \"./snapshotV1.js\";\nimport { SnapshotLegacy } from \"./snapshotlegacy.js\";\n\nexport class SnapshotLoader {\n\tprivate readonly logger: ITelemetryLoggerExt;\n\n\tconstructor(\n\t\tprivate readonly runtime: IFluidDataStoreRuntime,\n\n\t\tprivate readonly client: Client,\n\t\tprivate readonly mergeTree: MergeTree,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tprivate readonly serializer: IFluidSerializer,\n\t) {\n\t\tthis.logger = createChildLogger({ logger, namespace: \"SnapshotLoader\" });\n\t}\n\n\tpublic async initialize(\n\t\tservices: IChannelStorageService,\n\t): Promise<{ catchupOpsP: Promise<ISequencedDocumentMessage[]> }> {\n\t\tconst headerLoadedP = services.readBlob(SnapshotLegacy.header).then((header) => {\n\t\t\tassert(!!header, 0x05f /* \"Missing blob header on legacy snapshot!\" */);\n\t\t\treturn this.loadHeader(bufferToString(header, \"utf8\"));\n\t\t});\n\n\t\tconst catchupOpsP = this.loadBodyAndCatchupOps(headerLoadedP, services);\n\n\t\tcatchupOpsP.catch((error) =>\n\t\t\tthis.logger.sendErrorEvent({ eventName: \"CatchupOpsLoadFailure\" }, error),\n\t\t);\n\n\t\tawait headerLoadedP;\n\n\t\treturn { catchupOpsP };\n\t}\n\n\tprivate async loadBodyAndCatchupOps(\n\t\theaderChunkP: Promise<MergeTreeChunkV1>,\n\t\tservices: IChannelStorageService,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\tconst blobsP = services.list(\"\");\n\t\tconst headerChunk = await headerChunkP;\n\n\t\t// TODO we shouldn't need to wait on the body being complete to finish initialization.\n\t\t// To fully support this we need to be able to process inbound ops for pending segments.\n\t\tawait this.loadBody(headerChunk, services);\n\n\t\tconst blobs = await blobsP;\n\t\tif (blobs.length === headerChunk.headerMetadata!.orderedChunkMetadata.length + 1) {\n\t\t\tfor (const md of headerChunk.headerMetadata!.orderedChunkMetadata)\n\t\t\t\tblobs.splice(blobs.indexOf(md.id), 1);\n\t\t\tassert(blobs.length === 1, 0x060 /* There should be only one blob with catch up ops */);\n\n\t\t\t// TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.\n\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\n\t\t\treturn this.loadCatchupOps(services.readBlob(blobs[0]), this.serializer);\n\t\t} else if (blobs.length !== headerChunk.headerMetadata!.orderedChunkMetadata.length) {\n\t\t\tthrow new Error(\"Unexpected blobs in snapshot\");\n\t\t}\n\t\treturn [];\n\t}\n\n\tprivate readonly specToSegment = (\n\t\tspec: IJSONSegment | IJSONSegmentWithMergeInfo,\n\t): SegmentWithInfo<IInsertionInfo> => {\n\t\tif (hasMergeInfo(spec)) {\n\t\t\tconst seg = overwriteInfo<IInsertionInfo>(this.client.specToSegment(spec.json), {\n\t\t\t\tclientId:\n\t\t\t\t\tspec.client === undefined\n\t\t\t\t\t\t? NonCollabClient\n\t\t\t\t\t\t: this.client.getOrAddShortClientId(spec.client),\n\t\t\t\tseq: spec.seq ?? UniversalSequenceNumber,\n\t\t\t});\n\n\t\t\tif (spec.removedSeq !== undefined) {\n\t\t\t\t// this format had a bug where it didn't store all the overlap clients\n\t\t\t\t// this is for back compat, so we change the singular id to an array\n\t\t\t\t// this will only cause problems if there is an overlapping delete\n\t\t\t\t// spanning the snapshot, which should be rare\n\t\t\t\tconst specAsBuggyFormat: IJSONSegmentWithMergeInfo & { removedClient?: string } = spec;\n\t\t\t\tif (specAsBuggyFormat.removedClient !== undefined) {\n\t\t\t\t\tspec.removedClientIds ??= [specAsBuggyFormat.removedClient];\n\t\t\t\t}\n\t\t\t\tassert(spec.removedClientIds !== undefined, 0xaac /* must have removedClient ids */);\n\t\t\t\toverwriteInfo<IRemovalInfo>(seg, {\n\t\t\t\t\tremovedSeq: spec.removedSeq,\n\t\t\t\t\tremovedClientIds: spec.removedClientIds.map((id) =>\n\t\t\t\t\t\tthis.client.getOrAddShortClientId(id),\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (spec.movedSeq !== undefined) {\n\t\t\t\tassert(\n\t\t\t\t\tspec.movedClientIds !== undefined && spec.movedSeqs !== undefined,\n\t\t\t\t\t0xaa5 /* must have movedIds ids */,\n\t\t\t\t);\n\t\t\t\toverwriteInfo<IMoveInfo>(seg, {\n\t\t\t\t\tmovedSeq: spec.movedSeq,\n\t\t\t\t\tmovedSeqs: spec.movedSeqs,\n\t\t\t\t\tmovedClientIds: spec.movedClientIds.map((id) =>\n\t\t\t\t\t\tthis.client.getOrAddShortClientId(id),\n\t\t\t\t\t),\n\t\t\t\t\t// TODO:AB#29553: This property should be derived from segment data, not hard-coded.\n\t\t\t\t\twasMovedOnInsert: false,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn seg;\n\t\t}\n\t\treturn overwriteInfo(this.client.specToSegment(spec), {\n\t\t\tseq: UniversalSequenceNumber,\n\t\t\tclientId: NonCollabClient,\n\t\t});\n\t};\n\n\tprivate loadHeader(header: string): MergeTreeChunkV1 {\n\t\tconst chunk = SnapshotV1.processChunk(\n\t\t\tSnapshotLegacy.header,\n\t\t\theader,\n\t\t\tthis.logger,\n\t\t\tthis.mergeTree.options,\n\t\t\tthis.serializer,\n\t\t);\n\t\tconst segs = chunk.segments.map((element) => this.specToSegment(element));\n\t\tthis.extractAttribution(segs, chunk);\n\n\t\tthis.mergeTree.reloadFromSegments(segs);\n\n\t\tif (chunk.headerMetadata === undefined) {\n\t\t\tthrow new Error(\"header metadata not available\");\n\t\t}\n\t\t// If we load a detached container from snapshot, then we don't supply a default clientId\n\t\t// because we don't want to start collaboration.\n\t\tif (this.runtime.attachState !== AttachState.Detached) {\n\t\t\t// specify a default client id, \"snapshot\" here as we\n\t\t\t// should enter collaboration/op sending mode if we load\n\t\t\t// a snapshot in any case (summary or attach message)\n\t\t\t// once we get a client id this will be called with that\n\t\t\t// clientId in the connected event\n\t\t\tthis.client.startOrUpdateCollaboration(\n\t\t\t\tthis.runtime.clientId ?? \"snapshot\",\n\n\t\t\t\t// TODO: Make 'minSeq' non-optional once the new snapshot format becomes the default?\n\t\t\t\t// (See https://github.com/microsoft/FluidFramework/issues/84)\n\t\t\t\t/* minSeq: */ chunk.headerMetadata.minSequenceNumber ??\n\t\t\t\t\tchunk.headerMetadata.sequenceNumber,\n\t\t\t\t/* currentSeq: */ chunk.headerMetadata.sequenceNumber,\n\t\t\t);\n\t\t}\n\n\t\treturn chunk;\n\t}\n\n\tprivate async loadBody(\n\t\tchunk1: MergeTreeChunkV1,\n\t\tservices: IChannelStorageService,\n\t): Promise<void> {\n\t\tconst headerMetadata = chunk1.headerMetadata!;\n\t\tassert(chunk1.length <= headerMetadata.totalLength, 0x061 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount <= headerMetadata.totalSegmentCount,\n\t\t\t0x062 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\tif (chunk1.segmentCount === headerMetadata.totalSegmentCount) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet chunksWithAttribution = chunk1.attribution === undefined ? 0 : 1;\n\t\tconst segs: SegmentWithInfo<IInsertionInfo>[] = [];\n\t\tlet lengthSofar = chunk1.length;\n\t\tfor (\n\t\t\tlet chunkIndex = 1;\n\t\t\tchunkIndex < headerMetadata.orderedChunkMetadata.length;\n\t\t\tchunkIndex++\n\t\t) {\n\t\t\tconst chunk = await SnapshotV1.loadChunk(\n\t\t\t\tservices,\n\t\t\t\theaderMetadata.orderedChunkMetadata[chunkIndex].id,\n\t\t\t\tthis.logger,\n\t\t\t\tthis.mergeTree.options,\n\t\t\t\tthis.serializer,\n\t\t\t);\n\t\t\tlengthSofar += chunk.length;\n\t\t\t// Deserialize each chunk segment and append it to the end of the MergeTree.\n\t\t\tconst newSegs = chunk.segments.map((element) => this.specToSegment(element));\n\t\t\tthis.extractAttribution(newSegs, chunk);\n\t\t\tchunksWithAttribution += chunk.attribution === undefined ? 0 : 1;\n\t\t\tsegs.push(...newSegs);\n\t\t}\n\n\t\tassert(\n\t\t\tchunksWithAttribution === 0 ||\n\t\t\t\tchunksWithAttribution === headerMetadata.orderedChunkMetadata.length,\n\t\t\t0x4c0 /* all or no chunks should have attribution information */,\n\t\t);\n\n\t\tassert(lengthSofar === headerMetadata.totalLength, 0x063 /* \"Mismatch in totalLength\" */);\n\n\t\tassert(\n\t\t\tchunk1.segmentCount + segs.length === headerMetadata.totalSegmentCount,\n\t\t\t0x064 /* \"Mismatch in totalSegmentCount\" */,\n\t\t);\n\n\t\t// Helper to insert segments at the end of the MergeTree.\n\t\tconst mergeTree = this.mergeTree;\n\t\tconst append = (segments: ISegmentPrivate[], cli: number, seq: number): void => {\n\t\t\tmergeTree.insertSegments(\n\t\t\t\tmergeTree.root.cachedLength ?? 0,\n\t\t\t\tsegments,\n\t\t\t\t/* refSeq: */ UniversalSequenceNumber,\n\t\t\t\tcli,\n\t\t\t\tseq,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t};\n\n\t\t// Helpers to batch-insert segments that are below the min seq\n\t\tconst batch: SegmentWithInfo<IInsertionInfo>[] = [];\n\t\tconst flushBatch = (): void => {\n\t\t\tif (batch.length > 0) {\n\t\t\t\tappend(batch, NonCollabClient, UniversalSequenceNumber);\n\t\t\t}\n\t\t};\n\n\t\tfor (const seg of segs) {\n\t\t\tconst { clientId, seq } = seg;\n\t\t\t// If the segment can be batch inserted, add it to the 'batch' array. Otherwise, flush\n\t\t\t// any batched segments and then insert the current segment individually.\n\t\t\tif (clientId === NonCollabClient && seq === UniversalSequenceNumber) {\n\t\t\t\tbatch.push(seg);\n\t\t\t} else {\n\t\t\t\tflushBatch();\n\t\t\t\tappend([seg], clientId, seq);\n\t\t\t}\n\t\t}\n\n\t\tflushBatch();\n\t}\n\n\tprivate extractAttribution(segments: ISegmentPrivate[], chunk: MergeTreeChunkV1): void {\n\t\tif (chunk.attribution) {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy === undefined) {\n\t\t\t\tthrow new UsageError(\n\t\t\t\t\t\"Attribution policy must be provided when loading a document with attribution information.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { isAttached, attach, serializer } = attributionPolicy;\n\t\t\tif (!isAttached) {\n\t\t\t\tattach(this.client);\n\t\t\t}\n\t\t\tserializer.populateAttributionCollections(segments, chunk.attribution);\n\t\t} else {\n\t\t\tconst { attributionPolicy } = this.mergeTree;\n\t\t\tif (attributionPolicy?.isAttached) {\n\t\t\t\tattributionPolicy?.detach();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If loading from a snapshot, get the catchup messages.\n\t * @param rawMessages - The messages in original encoding\n\t * @returns The decoded messages with parsed+hydrated handles. Matches the format that will be passed in\n\t * SharedObject.processCore.\n\t */\n\tprivate async loadCatchupOps(\n\t\trawMessages: Promise<ArrayBufferLike>,\n\t\tserializer: IFluidSerializer,\n\t): Promise<ISequencedDocumentMessage[]> {\n\t\treturn serializer.parse(\n\t\t\tbufferToString(await rawMessages, \"utf8\"),\n\t\t) as ISequencedDocumentMessage[];\n\t}\n}\n"]}
@@ -23,9 +23,11 @@ export type SortedSegmentSetItem = ISegmentInternal | LocalReferencePosition | {
23
23
  *
24
24
  * @internal
25
25
  */
26
- export declare class SortedSegmentSet<T extends SortedSegmentSetItem = ISegmentInternal> extends SortedSet<T, string> {
27
- protected getKey(item: T): string;
28
- protected findItemPosition(item: T): {
26
+ export declare class SortedSegmentSet<T extends SortedSegmentSetItem = ISegmentInternal> extends SortedSet<T> {
27
+ private getOrdinal;
28
+ private getOffset;
29
+ protected compare(a: T, b: T): number;
30
+ protected onFindEquivalent(item: T, startIndex: number): {
29
31
  exists: boolean;
30
32
  index: number;
31
33
  };
@@ -1 +1 @@
1
- {"version":3,"file":"sortedSegmentSet.d.ts","sourceRoot":"","sources":["../src/sortedSegmentSet.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAC7B,gBAAgB,GAChB,sBAAsB,GACtB;IAAE,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE1C;;;;;;;;;;;GAWG;AAEH,qBAAa,gBAAgB,CAC5B,CAAC,SAAS,oBAAoB,GAAG,gBAAgB,CAChD,SAAQ,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM;IAiBjC,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,GAAG;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;CAqDvE"}
1
+ {"version":3,"file":"sortedSegmentSet.d.ts","sourceRoot":"","sources":["../src/sortedSegmentSet.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAC7B,gBAAgB,GAChB,sBAAsB,GACtB;IAAE,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAgB,CAC5B,CAAC,SAAS,oBAAoB,GAAG,gBAAgB,CAChD,SAAQ,SAAS,CAAC,CAAC,CAAC;IACrB,OAAO,CAAC,UAAU;IAiBlB,OAAO,CAAC,SAAS;IASjB,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM;IAarC,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;CAuB3F"}