@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
@@ -1 +1 @@
1
- {"version":3,"file":"testClient.js","sourceRoot":"","sources":["../../src/test/testClient.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 { strict as assert } from \"node:assert\";\n\nimport { Trace } from \"@fluid-internal/client-utils\";\nimport { makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions/internal\";\nimport { ISummaryTree } from \"@fluidframework/driver-definitions\";\nimport {\n\tITree,\n\tMessageType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { AttributionKey } from \"@fluidframework/runtime-definitions/internal\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\nimport { MockStorage } from \"@fluidframework/test-runtime-utils/internal\";\n\nimport { MergeTreeTextHelper } from \"../MergeTreeTextHelper.js\";\nimport { Client } from \"../client.js\";\nimport { DoublyLinkedList } from \"../collections/index.js\";\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport { IMergeTreeOptions, ReferencePosition } from \"../index.js\";\nimport { MergeTree, getSlideToSegoff } from \"../mergeTree.js\";\nimport {\n\tbackwardExcursion,\n\tforwardExcursion,\n\twalkAllChildSegments,\n} from \"../mergeTreeNodeWalk.js\";\nimport {\n\tMergeBlock,\n\tISegmentPrivate,\n\tMarker,\n\tMaxNodesInBlock,\n\ttype SegmentGroup,\n\tassertSegmentLeaf,\n} from \"../mergeTreeNodes.js\";\nimport {\n\tcreateAnnotateRangeOp,\n\tcreateInsertSegmentOp,\n\tcreateRemoveRangeOp,\n} from \"../opBuilder.js\";\nimport {\n\tIJSONSegment,\n\tIMarkerDef,\n\tIMergeTreeOp,\n\tMergeTreeDeltaType,\n\tReferenceType,\n\ttype IMergeTreeInsertMsg,\n} from \"../ops.js\";\nimport { PropertySet } from \"../properties.js\";\nimport { DetachedReferencePosition, refHasTileLabel } from \"../referencePositions.js\";\nimport { MergeTreeRevertibleDriver } from \"../revertibles.js\";\nimport {\n\tassertInserted,\n\tassertMergeNode,\n\tisInserted,\n\tisMoved,\n\tisRemoved,\n} from \"../segmentInfos.js\";\nimport { SnapshotLegacy } from \"../snapshotlegacy.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestSerializer } from \"./testSerializer.js\";\nimport { nodeOrdinalsHaveIntegrity } from \"./testUtils.js\";\n\nexport function specToSegment(spec: IJSONSegment): ISegmentPrivate {\n\tconst maybeText = TextSegment.fromJSONObject(spec);\n\tif (maybeText) {\n\t\treturn maybeText;\n\t}\n\n\tconst maybeMarker = Marker.fromJSONObject(spec);\n\tif (maybeMarker) {\n\t\treturn maybeMarker;\n\t}\n\n\tthrow new Error(`Unrecognized IJSONSegment type: '${JSON.stringify(spec)}'`);\n}\n\nconst random = makeRandom(0xdeadbeef, 0xfeedbed);\n\nexport class TestClient extends Client {\n\tpublic static searchChunkSize = 256;\n\tpublic static readonly serializer = new TestSerializer();\n\tpublic measureOps = false;\n\tpublic accumTime = 0;\n\tpublic accumWindowTime = 0;\n\tpublic accumWindow = 0;\n\tpublic accumOps = 0;\n\tpublic maxWindowTime = 0;\n\n\t/**\n\t * Used for in-memory testing. This will queue a reference string for each client message.\n\t */\n\tpublic static useCheckQ = false;\n\n\tpublic static async createFromClientSnapshot(\n\t\tclient1: TestClient,\n\t\tnewLongClientId: string,\n\t): Promise<TestClient> {\n\t\tconst snapshot = new SnapshotLegacy(\n\t\t\tclient1.mergeTree,\n\t\t\tcreateChildLogger({ namespace: \"fluid:snapshot\" }),\n\t\t);\n\t\tsnapshot.extractSync();\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst summaryTree = snapshot.emit([], TestClient.serializer, undefined!).summary;\n\t\treturn TestClient.createFromSummary(\n\t\t\tsummaryTree,\n\t\t\tnewLongClientId,\n\t\t\tclient1.specToSegment,\n\t\t\tclient1.mergeTree.options,\n\t\t);\n\t}\n\n\tpublic static async createFromSnapshot(\n\t\tsnapshotTree: ITree,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\treturn TestClient.createFromStorage(\n\t\t\tnew MockStorage(snapshotTree),\n\t\t\tnewLongClientId,\n\t\t\tspecToSeg,\n\t\t\toptions,\n\t\t);\n\t}\n\n\tpublic static async createFromSummary(\n\t\tsummaryTree: ISummaryTree,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\treturn TestClient.createFromStorage(\n\t\t\tMockStorage.createFromSummary(summaryTree),\n\t\t\tnewLongClientId,\n\t\t\tspecToSeg,\n\t\t\toptions,\n\t\t);\n\t}\n\n\tpublic static async createFromStorage(\n\t\tstorage: MockStorage,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\tconst client2 = new TestClient(options, specToSeg);\n\t\tconst { catchupOpsP } = await client2.load(\n\t\t\t{\n\t\t\t\tlogger: client2.logger,\n\t\t\t\tclientId: newLongClientId,\n\t\t\t} as unknown as IFluidDataStoreRuntime,\n\t\t\tstorage,\n\t\t\tTestClient.serializer,\n\t\t);\n\t\tawait catchupOpsP;\n\t\treturn client2;\n\t}\n\n\tpublic readonly mergeTree: MergeTree;\n\n\tpublic readonly checkQ: DoublyLinkedList<string> = new DoublyLinkedList<string>();\n\tprotected readonly q: DoublyLinkedList<ISequencedDocumentMessage> =\n\t\tnew DoublyLinkedList<ISequencedDocumentMessage>();\n\n\tprivate readonly textHelper: MergeTreeTextHelper;\n\tconstructor(\n\t\toptions?: IMergeTreeOptions & PropertySet,\n\t\tspecToSeg = specToSegment,\n\t\tgetMinInFlightRefSeq: () => number | undefined = (): undefined => undefined,\n\t) {\n\t\tsuper(\n\t\t\tspecToSeg,\n\t\t\tcreateChildLogger({ namespace: \"fluid:testClient\" }),\n\t\t\toptions,\n\t\t\tgetMinInFlightRefSeq,\n\t\t);\n\t\tthis.mergeTree = (this as Record<\"_mergeTree\", MergeTree>)._mergeTree;\n\t\tthis.textHelper = new MergeTreeTextHelper(this.mergeTree);\n\n\t\t// Validate by default\n\t\tthis.on(\"delta\", (o, d) => {\n\t\t\t// assert.notEqual(d.deltaSegments.length, 0);\n\t\t\tfor (const s of d.deltaSegments) {\n\t\t\t\tif (d.operation === MergeTreeDeltaType.INSERT) {\n\t\t\t\t\tassertMergeNode(s.segment);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic getText(start?: number, end?: number): string {\n\t\treturn this.textHelper.getText(this.getCurrentSeq(), this.getClientId(), \"\", start, end);\n\t}\n\n\tpublic enqueueTestString(): void {\n\t\tthis.checkQ.push(this.getText());\n\t}\n\tpublic getMessageCount(): number {\n\t\treturn this.q.length;\n\t}\n\tpublic enqueueMsg(msg: ISequencedDocumentMessage): void {\n\t\tthis.q.push(msg);\n\t}\n\tpublic dequeueMsg(): ISequencedDocumentMessage | undefined {\n\t\treturn this.q.shift()?.data;\n\t}\n\tpublic applyMessages(msgCount: number): boolean {\n\t\tlet currMsgCount = msgCount;\n\t\twhile (currMsgCount > 0) {\n\t\t\tconst msg = this.dequeueMsg();\n\t\t\tif (msg) {\n\t\t\t\tthis.applyMsg(msg);\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurrMsgCount--;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tpublic insertTextLocal(\n\t\tpos: number,\n\t\ttext: string,\n\t\tprops?: PropertySet,\n\t): IMergeTreeInsertMsg | undefined {\n\t\tconst segment = TextSegment.make(text, props);\n\t\treturn this.insertSegmentLocal(pos, segment);\n\t}\n\n\tpublic insertTextRemote(\n\t\tpos: number,\n\t\ttext: string,\n\t\tprops: PropertySet | undefined,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tconst segment = TextSegment.make(text, props);\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createInsertSegmentOp(pos, segment), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic removeRangeRemote(\n\t\tstart: number,\n\t\tend: number,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createRemoveRangeOp(start, end), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic annotateRangeRemote(\n\t\tstart: number,\n\t\tend: number,\n\t\tprops: PropertySet,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createAnnotateRangeOp(start, end, props), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic insertMarkerLocal(\n\t\tpos: number,\n\t\tbehaviors: ReferenceType,\n\t\tprops?: PropertySet,\n\t): IMergeTreeInsertMsg | undefined {\n\t\tconst segment = Marker.make(behaviors, props);\n\n\t\treturn this.insertSegmentLocal(pos, segment);\n\t}\n\n\tpublic insertMarkerRemote(\n\t\tpos: number,\n\t\tmarkerDef: IMarkerDef,\n\t\tprops: PropertySet,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tconst segment = Marker.make(markerDef.refType ?? ReferenceType.Tile, props);\n\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createInsertSegmentOp(pos, segment), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic relText(clientId: number, refSeq: number): string {\n\t\treturn `cli: ${this.getLongClientId(\n\t\t\tclientId,\n\t\t)} refSeq: ${refSeq}: ${this.textHelper.getText(refSeq, clientId)}`;\n\t}\n\n\tpublic makeOpMessage(\n\t\top: IMergeTreeOp | undefined,\n\t\tseq: number = UnassignedSequenceNumber,\n\t\trefSeq: number = this.getCurrentSeq(),\n\t\tlongClientId?: string,\n\t\tminSeqNumber = 0,\n\t): ISequencedDocumentMessage {\n\t\tif (op === undefined) {\n\t\t\tthrow new Error(\"op cannot be undefined\");\n\t\t}\n\t\tconst msg: ISequencedDocumentMessage = {\n\t\t\tclientId: longClientId ?? this.longClientId ?? \"\",\n\t\t\tclientSequenceNumber: 1,\n\t\t\tcontents: op,\n\t\t\tmetadata: undefined,\n\t\t\tminimumSequenceNumber: minSeqNumber,\n\t\t\treferenceSequenceNumber: refSeq,\n\t\t\tsequenceNumber: seq,\n\t\t\ttimestamp: Date.now(),\n\t\t\ttraces: [],\n\t\t\ttype: MessageType.Operation,\n\t\t};\n\t\treturn msg;\n\t}\n\n\tpublic validate(): void {\n\t\tassert(nodeOrdinalsHaveIntegrity(this.mergeTree.root));\n\t}\n\n\tpublic searchFromPos(\n\t\tpos: number,\n\t\ttarget: RegExp,\n\t): { text: string; pos: number } | undefined {\n\t\tlet start = pos;\n\t\tlet chunk = \"\";\n\t\twhile (start < this.getLength()) {\n\t\t\tchunk = this.getText(start, start + TestClient.searchChunkSize);\n\n\t\t\tconst result = chunk.match(target);\n\t\t\tif (result?.index) {\n\t\t\t\treturn { text: result[0], pos: result.index + start };\n\t\t\t}\n\t\t\tstart += TestClient.searchChunkSize;\n\t\t}\n\t}\n\n\tpublic findRandomWord(): { text: string; pos: number } | undefined {\n\t\tconst len = this.getLength();\n\t\tconst pos = random.integer(0, len);\n\t\tconst nextWord = this.searchFromPos(pos, /\\s\\w+\\b/);\n\t\treturn nextWord;\n\t}\n\n\tpublic debugDumpTree(tree: MergeTree): void {\n\t\t// want the segment's content and the state of insert/remove\n\t\tconst test: string[] = [];\n\t\twalkAllChildSegments(tree.root, (segment: ISegmentPrivate) => {\n\t\t\tconst prefixes: (string | undefined | number)[] = [];\n\t\t\tassertInserted(segment);\n\t\t\tprefixes.push(\n\t\t\t\tsegment.seq === UnassignedSequenceNumber ? `L${segment.localSeq}` : segment.seq,\n\t\t\t);\n\t\t\tif (isRemoved(segment)) {\n\t\t\t\tprefixes.push(\n\t\t\t\t\tsegment.removedSeq === UnassignedSequenceNumber\n\t\t\t\t\t\t? `L${segment.localRemovedSeq}`\n\t\t\t\t\t\t: segment.removedSeq,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\ttest.push(`${prefixes.join(\",\")}:${(segment as any).text}`);\n\t\t});\n\t}\n\n\t/**\n\t * Rebases a (local) position from the perspective `{ seq: seqNumberFrom, localSeq }` to the perspective\n\t * of the current sequence number. This is desirable when rebasing operations for reconnection. Perform\n\t * slow-path computations in this function without leveraging the merge-tree's structure\n\t */\n\tpublic rebasePosition(pos: number, seqNumberFrom: number, localSeq: number): number {\n\t\tlet segment: ISegmentPrivate | undefined;\n\t\tlet posAccumulated = 0;\n\t\tlet offset = pos;\n\t\tconst isInsertedInView = (seg: ISegmentPrivate): boolean =>\n\t\t\tisInserted(seg) &&\n\t\t\t((seg.seq !== UnassignedSequenceNumber && seg.seq <= seqNumberFrom) ||\n\t\t\t\t(seg.localSeq !== undefined && seg.localSeq <= localSeq));\n\n\t\tconst isRemovedFromView = (s: ISegmentPrivate): boolean =>\n\t\t\tisRemoved(s) &&\n\t\t\t((s.removedSeq !== UnassignedSequenceNumber && s.removedSeq <= seqNumberFrom) ||\n\t\t\t\t(s.localRemovedSeq !== undefined && s.localRemovedSeq <= localSeq));\n\n\t\twalkAllChildSegments(this.mergeTree.root, (seg) => {\n\t\t\tassertInserted(seg);\n\t\t\tsegment = seg;\n\n\t\t\tif (isInsertedInView(seg) && !isRemovedFromView(seg)) {\n\t\t\t\tposAccumulated += seg.cachedLength;\n\t\t\t\tif (offset >= seg.cachedLength) {\n\t\t\t\t\toffset -= seg.cachedLength;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Keep going while we've yet to reach the segment at the desired position\n\t\t\treturn posAccumulated <= pos;\n\t\t});\n\n\t\tassert(segment !== undefined, \"No segment found\");\n\t\tconst segoff = getSlideToSegoff({ segment, offset }) ?? segment;\n\t\tif (segoff.segment === undefined || segoff.offset === undefined) {\n\t\t\treturn DetachedReferencePosition;\n\t\t}\n\n\t\treturn this.findReconnectionPosition(segoff.segment, localSeq) + segoff.offset;\n\t}\n\n\tpublic findReconnectionPosition(segment: ISegmentPrivate, localSeq: number): number {\n\t\tconst fasterComputedPosition = super.findReconnectionPosition(segment, localSeq);\n\n\t\tlet segmentPosition = 0;\n\t\tconst isInsertedInView = (seg: ISegmentPrivate): boolean =>\n\t\t\tisInserted(seg) && (seg.localSeq === undefined || seg.localSeq <= localSeq);\n\t\tconst isRemovedFromView = (s: ISegmentPrivate): boolean =>\n\t\t\tisRemoved(s) &&\n\t\t\t(s.removedSeq !== UnassignedSequenceNumber ||\n\t\t\t\t(s.localRemovedSeq !== undefined && s.localRemovedSeq <= localSeq));\n\t\tconst isMovedFromView = (s: ISegmentPrivate): boolean =>\n\t\t\tisMoved(s) &&\n\t\t\t(s.movedSeq !== UnassignedSequenceNumber ||\n\t\t\t\t(s.localMovedSeq !== undefined && s.localMovedSeq <= localSeq));\n\t\t/*\n Walk the segments up to the current segment, and calculate its\n position taking into account local segments that were modified,\n after the current segment.\n */\n\t\twalkAllChildSegments(this.mergeTree.root, (seg) => {\n\t\t\t// If we've found the desired segment, terminate the walk and return 'segmentPosition'.\n\t\t\tif (seg === segment) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise, advance segmentPosition if the segment has been inserted and not removed\n\t\t\t// with respect to the given 'localSeq'.\n\t\t\t//\n\t\t\t// Note that all ACKed / remote ops are applied and we only need concern ourself with\n\t\t\t// determining if locally pending ops fall before/after the given 'localSeq'.\n\t\t\tif (isInsertedInView(seg) && !isRemovedFromView(seg) && !isMovedFromView(seg)) {\n\t\t\t\tsegmentPosition += seg.cachedLength;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t});\n\n\t\tassert.equal(\n\t\t\tfasterComputedPosition,\n\t\t\tsegmentPosition,\n\t\t\t\"Expected fast-path computation to match result from walk all segments\",\n\t\t);\n\t\treturn segmentPosition;\n\t}\n\n\t/**\n\t * Validates segments either all have attribution information or none of them.\n\t * If no segment has attribution information, returns undefined.\n\t *\n\t * @param channel - Attribution channel name to request information from.\n\t * @returns an array of all attribution seq#s from the current perspective.\n\t * The `i`th entry of the array is the attribution key for the character at position `i`.\n\t */\n\tpublic getAllAttributionSeqs(channel?: string): (number | AttributionKey | undefined)[] {\n\t\tconst seqs: (number | AttributionKey | undefined)[] = [];\n\t\tthis.walkAllSegments((segment) => {\n\t\t\tfor (let i = 0; i < segment.cachedLength; i++) {\n\t\t\t\tconst key = segment.attribution?.getAtOffset(i, channel);\n\t\t\t\tseqs.push(key?.type === \"op\" ? key.seq : key);\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t\treturn seqs;\n\t}\n\n\tpublic peekPendingSegmentGroups(): SegmentGroup | undefined;\n\tpublic peekPendingSegmentGroups(count: number): SegmentGroup | SegmentGroup[] | undefined;\n\tpublic peekPendingSegmentGroups(\n\t\tcount: number = 1,\n\t): SegmentGroup | SegmentGroup[] | undefined {\n\t\treturn super.peekPendingSegmentGroups(count) as SegmentGroup | SegmentGroup[] | undefined;\n\t}\n\n\t/**\n\t * Override and add some test only metrics\n\t */\n\tpublic applyMsg(msg: ISequencedDocumentMessage, local: boolean = false): void {\n\t\tlet traceStart: Trace | undefined;\n\t\tif (this.measureOps) {\n\t\t\ttraceStart = Trace.start();\n\t\t}\n\n\t\tsuper.applyMsg(msg, local);\n\n\t\tif (traceStart) {\n\t\t\tthis.accumTime += elapsedMicroseconds(traceStart);\n\t\t\tthis.accumOps++;\n\t\t\tthis.accumWindow += this.getCurrentSeq() - this.getCollabWindow().minSeq;\n\t\t}\n\t}\n\n\t/**\n\t * Override and add some test only metrics\n\t */\n\tupdateMinSeq(minSeq: number): void {\n\t\tlet trace: Trace | undefined;\n\t\tif (this.measureOps) {\n\t\t\ttrace = Trace.start();\n\t\t}\n\n\t\tsuper.updateMinSeq(minSeq);\n\t\tif (trace) {\n\t\t\tconst elapsed = elapsedMicroseconds(trace);\n\t\t\tthis.accumWindowTime += elapsed;\n\t\t\tif (elapsed > this.maxWindowTime) {\n\t\t\t\tthis.maxWindowTime = elapsed;\n\t\t\t}\n\t\t}\n\t}\n\n\tslowSearchForMarker(\n\t\tstartPos: number,\n\t\tmarkerLabel: string,\n\t\tforwards = true,\n\t): ReferencePosition | undefined {\n\t\tlet foundMarker: Marker | undefined;\n\n\t\tconst { segment } = this.getContainingSegment<ISegmentPrivate>(startPos);\n\t\tassertSegmentLeaf(segment);\n\t\tif (Marker.is(segment)) {\n\t\t\tif (refHasTileLabel(segment, markerLabel)) {\n\t\t\t\tfoundMarker = segment;\n\t\t\t}\n\t\t} else {\n\t\t\tif (forwards) {\n\t\t\t\tforwardExcursion(segment, (seg) => {\n\t\t\t\t\tif (Marker.is(seg) && refHasTileLabel(seg, markerLabel)) {\n\t\t\t\t\t\tfoundMarker = seg;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tbackwardExcursion(segment, (seg) => {\n\t\t\t\t\tif (Marker.is(seg) && refHasTileLabel(seg, markerLabel)) {\n\t\t\t\t\t\tfoundMarker = seg;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn foundMarker;\n\t}\n}\n\nfunction elapsedMicroseconds(trace: Trace): number {\n\treturn trace.trace().duration * 1000;\n}\n\n// the client doesn't submit ops, so this adds a callback to capture them\nexport type TestClientRevertibleDriver = MergeTreeRevertibleDriver &\n\tPartial<{ submitOpCallback?: (op: IMergeTreeOp | undefined) => void }>;\n\nexport const createRevertDriver = (client: TestClient): TestClientRevertibleDriver => {\n\treturn {\n\t\tremoveRange(start: number, end: number): void {\n\t\t\tconst op = client.removeRangeLocal(start, end);\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t\tannotateRange(start: number, end: number, props: PropertySet): void {\n\t\t\tconst op = client.annotateRangeLocal(start, end, props);\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t\tinsertFromSpec(pos: number, spec: IJSONSegment): void {\n\t\t\tconst op = client.insertSegmentLocal(pos, client.specToSegment(spec));\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t};\n};\n\nexport interface MergeTreeStats {\n\tmaxHeight: number;\n\tnodeCount: number;\n\tleafCount: number;\n\tremovedLeafCount: number;\n\tliveCount: number;\n\thisto: number[];\n\twindowTime?: number;\n\tpackTime?: number;\n\tordTime?: number;\n\tmaxOrdTime?: number;\n}\n\nexport function getStats(tree: MergeTree): MergeTreeStats {\n\tconst nodeGetStats = (block: MergeBlock): MergeTreeStats => {\n\t\tconst stats: MergeTreeStats = {\n\t\t\tmaxHeight: 0,\n\t\t\tnodeCount: 0,\n\t\t\tleafCount: 0,\n\t\t\tremovedLeafCount: 0,\n\t\t\tliveCount: 0,\n\t\t\thisto: [],\n\t\t};\n\t\tfor (let k = 0; k < MaxNodesInBlock; k++) {\n\t\t\tstats.histo[k] = 0;\n\t\t}\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tlet height = 1;\n\t\t\tif (child.isLeaf()) {\n\t\t\t\tstats.leafCount++;\n\t\t\t\tconst segment = child;\n\t\t\t\tif (isRemoved(segment)) {\n\t\t\t\t\tstats.removedLeafCount++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst childStats = nodeGetStats(child);\n\t\t\t\theight = 1 + childStats.maxHeight;\n\t\t\t\tstats.nodeCount += childStats.nodeCount;\n\t\t\t\tstats.leafCount += childStats.leafCount;\n\t\t\t\tstats.removedLeafCount += childStats.removedLeafCount;\n\t\t\t\tstats.liveCount += childStats.liveCount;\n\t\t\t\tfor (let j = 0; j < MaxNodesInBlock; j++) {\n\t\t\t\t\tstats.histo[j] += childStats.histo[j];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (height > stats.maxHeight) {\n\t\t\t\tstats.maxHeight = height;\n\t\t\t}\n\t\t}\n\t\tstats.histo[block.childCount]++;\n\t\tstats.nodeCount++;\n\t\tstats.liveCount += block.childCount;\n\t\treturn stats;\n\t};\n\tconst rootStats = nodeGetStats(tree.root);\n\treturn rootStats;\n}\n"]}
1
+ {"version":3,"file":"testClient.js","sourceRoot":"","sources":["../../src/test/testClient.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 { strict as assert } from \"node:assert\";\n\nimport { Trace } from \"@fluid-internal/client-utils\";\nimport { makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions/internal\";\nimport { ISummaryTree } from \"@fluidframework/driver-definitions\";\nimport {\n\tITree,\n\tMessageType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { AttributionKey } from \"@fluidframework/runtime-definitions/internal\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\nimport { MockStorage } from \"@fluidframework/test-runtime-utils/internal\";\n\nimport { MergeTreeTextHelper } from \"../MergeTreeTextHelper.js\";\nimport { Client } from \"../client.js\";\nimport { DoublyLinkedList } from \"../collections/index.js\";\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport { IMergeTreeOptions, ReferencePosition } from \"../index.js\";\nimport { MergeTree, getSlideToSegoff } from \"../mergeTree.js\";\nimport {\n\tbackwardExcursion,\n\tforwardExcursion,\n\twalkAllChildSegments,\n} from \"../mergeTreeNodeWalk.js\";\nimport {\n\tMergeBlock,\n\tISegmentPrivate,\n\tMarker,\n\tMaxNodesInBlock,\n\ttype SegmentGroup,\n\tassertSegmentLeaf,\n} from \"../mergeTreeNodes.js\";\nimport {\n\tcreateAnnotateRangeOp,\n\tcreateInsertSegmentOp,\n\tcreateRemoveRangeOp,\n} from \"../opBuilder.js\";\nimport {\n\tIJSONSegment,\n\tIMarkerDef,\n\tIMergeTreeOp,\n\tMergeTreeDeltaType,\n\tReferenceType,\n\ttype IMergeTreeInsertMsg,\n} from \"../ops.js\";\nimport { PropertySet } from \"../properties.js\";\nimport { DetachedReferencePosition, refHasTileLabel } from \"../referencePositions.js\";\nimport { MergeTreeRevertibleDriver } from \"../revertibles.js\";\nimport {\n\tassertInserted,\n\tassertMergeNode,\n\tisInserted,\n\tisMoved,\n\tisRemoved,\n} from \"../segmentInfos.js\";\nimport { SnapshotLegacy } from \"../snapshotlegacy.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestSerializer } from \"./testSerializer.js\";\nimport { nodeOrdinalsHaveIntegrity } from \"./testUtils.js\";\n\nexport function specToSegment(spec: IJSONSegment): ISegmentPrivate {\n\tconst maybeText = TextSegment.fromJSONObject(spec);\n\tif (maybeText) {\n\t\treturn maybeText;\n\t}\n\n\tconst maybeMarker = Marker.fromJSONObject(spec);\n\tif (maybeMarker) {\n\t\treturn maybeMarker;\n\t}\n\n\tthrow new Error(`Unrecognized IJSONSegment type: '${JSON.stringify(spec)}'`);\n}\n\nconst random = makeRandom(0xdeadbeef, 0xfeedbed);\n\nexport class TestClient extends Client {\n\tpublic static searchChunkSize = 256;\n\tpublic static readonly serializer = new TestSerializer();\n\tpublic measureOps = false;\n\tpublic accumTime = 0;\n\tpublic accumWindowTime = 0;\n\tpublic accumWindow = 0;\n\tpublic accumOps = 0;\n\tpublic maxWindowTime = 0;\n\n\t/**\n\t * Used for in-memory testing. This will queue a reference string for each client message.\n\t */\n\tpublic static useCheckQ = false;\n\n\tpublic static async createFromClientSnapshot(\n\t\tclient1: TestClient,\n\t\tnewLongClientId: string,\n\t): Promise<TestClient> {\n\t\tconst snapshot = new SnapshotLegacy(\n\t\t\tclient1.mergeTree,\n\t\t\tcreateChildLogger({ namespace: \"fluid:snapshot\" }),\n\t\t);\n\t\tsnapshot.extractSync();\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst summaryTree = snapshot.emit([], TestClient.serializer, undefined!).summary;\n\t\treturn TestClient.createFromSummary(\n\t\t\tsummaryTree,\n\t\t\tnewLongClientId,\n\t\t\tclient1.specToSegment,\n\t\t\tclient1.mergeTree.options,\n\t\t);\n\t}\n\n\tpublic static async createFromSnapshot(\n\t\tsnapshotTree: ITree,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\treturn TestClient.createFromStorage(\n\t\t\tnew MockStorage(snapshotTree),\n\t\t\tnewLongClientId,\n\t\t\tspecToSeg,\n\t\t\toptions,\n\t\t);\n\t}\n\n\tpublic static async createFromSummary(\n\t\tsummaryTree: ISummaryTree,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\treturn TestClient.createFromStorage(\n\t\t\tMockStorage.createFromSummary(summaryTree),\n\t\t\tnewLongClientId,\n\t\t\tspecToSeg,\n\t\t\toptions,\n\t\t);\n\t}\n\n\tpublic static async createFromStorage(\n\t\tstorage: MockStorage,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\tconst client2 = new TestClient(options, specToSeg);\n\t\tconst { catchupOpsP } = await client2.load(\n\t\t\t{\n\t\t\t\tlogger: client2.logger,\n\t\t\t\tclientId: newLongClientId,\n\t\t\t} as unknown as IFluidDataStoreRuntime,\n\t\t\tstorage,\n\t\t\tTestClient.serializer,\n\t\t);\n\t\tawait catchupOpsP;\n\t\treturn client2;\n\t}\n\n\tpublic readonly mergeTree: MergeTree;\n\n\tpublic readonly checkQ: DoublyLinkedList<string> = new DoublyLinkedList<string>();\n\tprotected readonly q: DoublyLinkedList<ISequencedDocumentMessage> =\n\t\tnew DoublyLinkedList<ISequencedDocumentMessage>();\n\n\tprivate readonly textHelper: MergeTreeTextHelper;\n\tconstructor(\n\t\toptions?: IMergeTreeOptions & PropertySet,\n\t\tspecToSeg = specToSegment,\n\t\tgetMinInFlightRefSeq: () => number | undefined = (): undefined => undefined,\n\t) {\n\t\tsuper(\n\t\t\tspecToSeg,\n\t\t\tcreateChildLogger({ namespace: \"fluid:testClient\" }),\n\t\t\toptions,\n\t\t\tgetMinInFlightRefSeq,\n\t\t);\n\t\tthis.mergeTree = (this as Record<\"_mergeTree\", MergeTree>)._mergeTree;\n\t\tthis.textHelper = new MergeTreeTextHelper(this.mergeTree);\n\n\t\t// Validate by default\n\t\tthis.on(\"delta\", (o, d) => {\n\t\t\t// assert.notEqual(d.deltaSegments.length, 0);\n\t\t\tfor (const s of d.deltaSegments) {\n\t\t\t\tif (d.operation === MergeTreeDeltaType.INSERT) {\n\t\t\t\t\tassertMergeNode(s.segment);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic getText(start?: number, end?: number): string {\n\t\treturn this.textHelper.getText(this.getCurrentSeq(), this.getClientId(), \"\", start, end);\n\t}\n\n\tpublic enqueueTestString(): void {\n\t\tthis.checkQ.push(this.getText());\n\t}\n\tpublic getMessageCount(): number {\n\t\treturn this.q.length;\n\t}\n\tpublic enqueueMsg(msg: ISequencedDocumentMessage): void {\n\t\tthis.q.push(msg);\n\t}\n\tpublic dequeueMsg(): ISequencedDocumentMessage | undefined {\n\t\treturn this.q.shift()?.data;\n\t}\n\tpublic applyMessages(msgCount: number): boolean {\n\t\tlet currMsgCount = msgCount;\n\t\twhile (currMsgCount > 0) {\n\t\t\tconst msg = this.dequeueMsg();\n\t\t\tif (msg) {\n\t\t\t\tthis.applyMsg(msg);\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurrMsgCount--;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tpublic insertTextLocal(\n\t\tpos: number,\n\t\ttext: string,\n\t\tprops?: PropertySet,\n\t): IMergeTreeInsertMsg | undefined {\n\t\tconst segment = TextSegment.make(text, props);\n\t\treturn this.insertSegmentLocal(pos, segment);\n\t}\n\n\tpublic insertTextRemote(\n\t\tpos: number,\n\t\ttext: string,\n\t\tprops: PropertySet | undefined,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tconst segment = TextSegment.make(text, props);\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createInsertSegmentOp(pos, segment), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic removeRangeRemote(\n\t\tstart: number,\n\t\tend: number,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createRemoveRangeOp(start, end), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic annotateRangeRemote(\n\t\tstart: number,\n\t\tend: number,\n\t\tprops: PropertySet,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createAnnotateRangeOp(start, end, props), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic insertMarkerLocal(\n\t\tpos: number,\n\t\tbehaviors: ReferenceType,\n\t\tprops?: PropertySet,\n\t): IMergeTreeInsertMsg | undefined {\n\t\tconst segment = Marker.make(behaviors, props);\n\n\t\treturn this.insertSegmentLocal(pos, segment);\n\t}\n\n\tpublic insertMarkerRemote(\n\t\tpos: number,\n\t\tmarkerDef: IMarkerDef,\n\t\tprops: PropertySet,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tconst segment = Marker.make(markerDef.refType ?? ReferenceType.Tile, props);\n\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createInsertSegmentOp(pos, segment), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic relText(clientId: number, refSeq: number): string {\n\t\treturn `cli: ${this.getLongClientId(\n\t\t\tclientId,\n\t\t)} refSeq: ${refSeq}: ${this.textHelper.getText(refSeq, clientId)}`;\n\t}\n\n\tpublic makeOpMessage(\n\t\top: IMergeTreeOp | undefined,\n\t\tseq: number = UnassignedSequenceNumber,\n\t\trefSeq: number = this.getCurrentSeq(),\n\t\tlongClientId?: string,\n\t\tminSeqNumber = 0,\n\t): ISequencedDocumentMessage {\n\t\tif (op === undefined) {\n\t\t\tthrow new Error(\"op cannot be undefined\");\n\t\t}\n\t\tconst msg: ISequencedDocumentMessage = {\n\t\t\tclientId: longClientId ?? this.longClientId ?? \"\",\n\t\t\tclientSequenceNumber: 1,\n\t\t\tcontents: op,\n\t\t\tmetadata: undefined,\n\t\t\tminimumSequenceNumber: minSeqNumber,\n\t\t\treferenceSequenceNumber: refSeq,\n\t\t\tsequenceNumber: seq,\n\t\t\ttimestamp: Date.now(),\n\t\t\ttraces: [],\n\t\t\ttype: MessageType.Operation,\n\t\t};\n\t\treturn msg;\n\t}\n\n\tpublic validate(): void {\n\t\tassert(nodeOrdinalsHaveIntegrity(this.mergeTree.root));\n\t}\n\n\tpublic searchFromPos(\n\t\tpos: number,\n\t\ttarget: RegExp,\n\t): { text: string; pos: number } | undefined {\n\t\tlet start = pos;\n\t\tlet chunk = \"\";\n\t\twhile (start < this.getLength()) {\n\t\t\tchunk = this.getText(start, start + TestClient.searchChunkSize);\n\n\t\t\tconst result = chunk.match(target);\n\t\t\tif (result?.index) {\n\t\t\t\treturn { text: result[0], pos: result.index + start };\n\t\t\t}\n\t\t\tstart += TestClient.searchChunkSize;\n\t\t}\n\t}\n\n\tpublic findRandomWord(): { text: string; pos: number } | undefined {\n\t\tconst len = this.getLength();\n\t\tconst pos = random.integer(0, len);\n\t\tconst nextWord = this.searchFromPos(pos, /\\s\\w+\\b/);\n\t\treturn nextWord;\n\t}\n\n\tpublic debugDumpTree(tree: MergeTree): string[] {\n\t\t// want the segment's content and the state of insert/remove\n\t\tconst test: string[] = [];\n\t\twalkAllChildSegments(tree.root, (segment: ISegmentPrivate) => {\n\t\t\tconst prefixes: (string | undefined | number)[] = [];\n\t\t\tassertInserted(segment);\n\t\t\tprefixes.push(\n\t\t\t\tsegment.seq === UnassignedSequenceNumber ? `L${segment.localSeq}` : segment.seq,\n\t\t\t);\n\t\t\tif (isRemoved(segment)) {\n\t\t\t\tprefixes.push(\n\t\t\t\t\tsegment.removedSeq === UnassignedSequenceNumber\n\t\t\t\t\t\t? `L${segment.localRemovedSeq}`\n\t\t\t\t\t\t: segment.removedSeq,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\ttest.push(`${prefixes.join(\",\")}:${(segment as any).text}`);\n\t\t});\n\t\treturn test;\n\t}\n\n\t/**\n\t * Rebases a (local) position from the perspective `{ seq: seqNumberFrom, localSeq }` to the perspective\n\t * of the current sequence number. This is desirable when rebasing operations for reconnection. Perform\n\t * slow-path computations in this function without leveraging the merge-tree's structure\n\t */\n\tpublic rebasePosition(pos: number, seqNumberFrom: number, localSeq: number): number {\n\t\tlet segment: ISegmentPrivate | undefined;\n\t\tlet posAccumulated = 0;\n\t\tlet offset = pos;\n\t\tconst isInsertedInView = (seg: ISegmentPrivate): boolean =>\n\t\t\tisInserted(seg) &&\n\t\t\t((seg.seq !== UnassignedSequenceNumber && seg.seq <= seqNumberFrom) ||\n\t\t\t\t(seg.localSeq !== undefined && seg.localSeq <= localSeq));\n\n\t\tconst isRemovedFromView = (s: ISegmentPrivate): boolean =>\n\t\t\tisRemoved(s) &&\n\t\t\t((s.removedSeq !== UnassignedSequenceNumber && s.removedSeq <= seqNumberFrom) ||\n\t\t\t\t(s.localRemovedSeq !== undefined && s.localRemovedSeq <= localSeq));\n\n\t\twalkAllChildSegments(this.mergeTree.root, (seg) => {\n\t\t\tassertInserted(seg);\n\t\t\tsegment = seg;\n\n\t\t\tif (isInsertedInView(seg) && !isRemovedFromView(seg)) {\n\t\t\t\tposAccumulated += seg.cachedLength;\n\t\t\t\tif (offset >= seg.cachedLength) {\n\t\t\t\t\toffset -= seg.cachedLength;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Keep going while we've yet to reach the segment at the desired position\n\t\t\treturn posAccumulated <= pos;\n\t\t});\n\n\t\tassert(segment !== undefined, \"No segment found\");\n\t\tconst segoff = getSlideToSegoff({ segment, offset }) ?? segment;\n\t\tif (segoff.segment === undefined || segoff.offset === undefined) {\n\t\t\treturn DetachedReferencePosition;\n\t\t}\n\n\t\treturn this.findReconnectionPosition(segoff.segment, localSeq) + segoff.offset;\n\t}\n\n\tpublic findReconnectionPosition(segment: ISegmentPrivate, localSeq: number): number {\n\t\tconst fasterComputedPosition = super.findReconnectionPosition(segment, localSeq);\n\n\t\tlet segmentPosition = 0;\n\t\tconst isInsertedInView = (seg: ISegmentPrivate): boolean =>\n\t\t\tisInserted(seg) && (seg.localSeq === undefined || seg.localSeq <= localSeq);\n\t\tconst isRemovedFromView = (s: ISegmentPrivate): boolean =>\n\t\t\tisRemoved(s) &&\n\t\t\t(s.removedSeq !== UnassignedSequenceNumber ||\n\t\t\t\t(s.localRemovedSeq !== undefined && s.localRemovedSeq <= localSeq));\n\t\tconst isMovedFromView = (s: ISegmentPrivate): boolean =>\n\t\t\tisMoved(s) &&\n\t\t\t(s.movedSeq !== UnassignedSequenceNumber ||\n\t\t\t\t(s.localMovedSeq !== undefined && s.localMovedSeq <= localSeq));\n\t\t/*\n Walk the segments up to the current segment, and calculate its\n position taking into account local segments that were modified,\n after the current segment.\n */\n\t\twalkAllChildSegments(this.mergeTree.root, (seg) => {\n\t\t\t// If we've found the desired segment, terminate the walk and return 'segmentPosition'.\n\t\t\tif (seg === segment) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise, advance segmentPosition if the segment has been inserted and not removed\n\t\t\t// with respect to the given 'localSeq'.\n\t\t\t//\n\t\t\t// Note that all ACKed / remote ops are applied and we only need concern ourself with\n\t\t\t// determining if locally pending ops fall before/after the given 'localSeq'.\n\t\t\tif (isInsertedInView(seg) && !isRemovedFromView(seg) && !isMovedFromView(seg)) {\n\t\t\t\tsegmentPosition += seg.cachedLength;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t});\n\n\t\tassert.equal(\n\t\t\tfasterComputedPosition,\n\t\t\tsegmentPosition,\n\t\t\t\"Expected fast-path computation to match result from walk all segments\",\n\t\t);\n\t\treturn segmentPosition;\n\t}\n\n\t/**\n\t * Validates segments either all have attribution information or none of them.\n\t * If no segment has attribution information, returns undefined.\n\t *\n\t * @param channel - Attribution channel name to request information from.\n\t * @returns an array of all attribution seq#s from the current perspective.\n\t * The `i`th entry of the array is the attribution key for the character at position `i`.\n\t */\n\tpublic getAllAttributionSeqs(channel?: string): (number | AttributionKey | undefined)[] {\n\t\tconst seqs: (number | AttributionKey | undefined)[] = [];\n\t\tthis.walkAllSegments((segment) => {\n\t\t\tfor (let i = 0; i < segment.cachedLength; i++) {\n\t\t\t\tconst key = segment.attribution?.getAtOffset(i, channel);\n\t\t\t\tseqs.push(key?.type === \"op\" ? key.seq : key);\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t\treturn seqs;\n\t}\n\n\tpublic peekPendingSegmentGroups(): SegmentGroup | undefined;\n\tpublic peekPendingSegmentGroups(count: number): SegmentGroup | SegmentGroup[] | undefined;\n\tpublic peekPendingSegmentGroups(\n\t\tcount: number = 1,\n\t): SegmentGroup | SegmentGroup[] | undefined {\n\t\treturn super.peekPendingSegmentGroups(count) as SegmentGroup | SegmentGroup[] | undefined;\n\t}\n\n\t/**\n\t * Override and add some test only metrics\n\t */\n\tpublic applyMsg(msg: ISequencedDocumentMessage, local: boolean = false): void {\n\t\tlet traceStart: Trace | undefined;\n\t\tif (this.measureOps) {\n\t\t\ttraceStart = Trace.start();\n\t\t}\n\n\t\tsuper.applyMsg(msg, local);\n\n\t\tif (traceStart) {\n\t\t\tthis.accumTime += elapsedMicroseconds(traceStart);\n\t\t\tthis.accumOps++;\n\t\t\tthis.accumWindow += this.getCurrentSeq() - this.getCollabWindow().minSeq;\n\t\t}\n\t}\n\n\t/**\n\t * Override and add some test only metrics\n\t */\n\tupdateMinSeq(minSeq: number): void {\n\t\tlet trace: Trace | undefined;\n\t\tif (this.measureOps) {\n\t\t\ttrace = Trace.start();\n\t\t}\n\n\t\tsuper.updateMinSeq(minSeq);\n\t\tif (trace) {\n\t\t\tconst elapsed = elapsedMicroseconds(trace);\n\t\t\tthis.accumWindowTime += elapsed;\n\t\t\tif (elapsed > this.maxWindowTime) {\n\t\t\t\tthis.maxWindowTime = elapsed;\n\t\t\t}\n\t\t}\n\t}\n\n\tslowSearchForMarker(\n\t\tstartPos: number,\n\t\tmarkerLabel: string,\n\t\tforwards = true,\n\t): ReferencePosition | undefined {\n\t\tlet foundMarker: Marker | undefined;\n\n\t\tconst { segment } = this.getContainingSegment<ISegmentPrivate>(startPos);\n\t\tassertSegmentLeaf(segment);\n\t\tif (Marker.is(segment)) {\n\t\t\tif (refHasTileLabel(segment, markerLabel)) {\n\t\t\t\tfoundMarker = segment;\n\t\t\t}\n\t\t} else {\n\t\t\tif (forwards) {\n\t\t\t\tforwardExcursion(segment, (seg) => {\n\t\t\t\t\tif (Marker.is(seg) && refHasTileLabel(seg, markerLabel)) {\n\t\t\t\t\t\tfoundMarker = seg;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tbackwardExcursion(segment, (seg) => {\n\t\t\t\t\tif (Marker.is(seg) && refHasTileLabel(seg, markerLabel)) {\n\t\t\t\t\t\tfoundMarker = seg;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn foundMarker;\n\t}\n}\n\nfunction elapsedMicroseconds(trace: Trace): number {\n\treturn trace.trace().duration * 1000;\n}\n\n// the client doesn't submit ops, so this adds a callback to capture them\nexport type TestClientRevertibleDriver = MergeTreeRevertibleDriver &\n\tPartial<{ submitOpCallback?: (op: IMergeTreeOp | undefined) => void }>;\n\nexport const createRevertDriver = (client: TestClient): TestClientRevertibleDriver => {\n\treturn {\n\t\tremoveRange(start: number, end: number): void {\n\t\t\tconst op = client.removeRangeLocal(start, end);\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t\tannotateRange(start: number, end: number, props: PropertySet): void {\n\t\t\tconst op = client.annotateRangeLocal(start, end, props);\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t\tinsertFromSpec(pos: number, spec: IJSONSegment): void {\n\t\t\tconst op = client.insertSegmentLocal(pos, client.specToSegment(spec));\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t};\n};\n\nexport interface MergeTreeStats {\n\tmaxHeight: number;\n\tnodeCount: number;\n\tleafCount: number;\n\tremovedLeafCount: number;\n\tliveCount: number;\n\thisto: number[];\n\twindowTime?: number;\n\tpackTime?: number;\n\tordTime?: number;\n\tmaxOrdTime?: number;\n}\n\nexport function getStats(tree: MergeTree): MergeTreeStats {\n\tconst nodeGetStats = (block: MergeBlock): MergeTreeStats => {\n\t\tconst stats: MergeTreeStats = {\n\t\t\tmaxHeight: 0,\n\t\t\tnodeCount: 0,\n\t\t\tleafCount: 0,\n\t\t\tremovedLeafCount: 0,\n\t\t\tliveCount: 0,\n\t\t\thisto: [],\n\t\t};\n\t\tfor (let k = 0; k < MaxNodesInBlock; k++) {\n\t\t\tstats.histo[k] = 0;\n\t\t}\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tlet height = 1;\n\t\t\tif (child.isLeaf()) {\n\t\t\t\tstats.leafCount++;\n\t\t\t\tconst segment = child;\n\t\t\t\tif (isRemoved(segment)) {\n\t\t\t\t\tstats.removedLeafCount++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst childStats = nodeGetStats(child);\n\t\t\t\theight = 1 + childStats.maxHeight;\n\t\t\t\tstats.nodeCount += childStats.nodeCount;\n\t\t\t\tstats.leafCount += childStats.leafCount;\n\t\t\t\tstats.removedLeafCount += childStats.removedLeafCount;\n\t\t\t\tstats.liveCount += childStats.liveCount;\n\t\t\t\tfor (let j = 0; j < MaxNodesInBlock; j++) {\n\t\t\t\t\tstats.histo[j] += childStats.histo[j];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (height > stats.maxHeight) {\n\t\t\t\tstats.maxHeight = height;\n\t\t\t}\n\t\t}\n\t\tstats.histo[block.childCount]++;\n\t\tstats.nodeCount++;\n\t\tstats.liveCount += block.childCount;\n\t\treturn stats;\n\t};\n\tconst rootStats = nodeGetStats(tree.root);\n\treturn rootStats;\n}\n"]}
@@ -181,11 +181,11 @@ exports.validateRefCount = validateRefCount;
181
181
  * fuzz tests).
182
182
  */
183
183
  function useStrictPartialLengthChecks() {
184
- beforeEach(() => {
184
+ beforeEach("Enable strict partial lengths", () => {
185
185
  partialLengths_js_1.PartialSequenceLengths.options.verifier = partialLengths_js_1.verifyPartialLengths;
186
186
  partialLengths_js_1.PartialSequenceLengths.options.verifyExpected = partialLengths_js_1.verifyExpectedPartialLengths;
187
187
  });
188
- afterEach(() => {
188
+ afterEach("Disable strict partial lengths", () => {
189
189
  partialLengths_js_1.PartialSequenceLengths.options.verifier = undefined;
190
190
  partialLengths_js_1.PartialSequenceLengths.options.verifyExpected = undefined;
191
191
  });
@@ -1 +1 @@
1
- {"version":3,"file":"testUtils.js","sourceRoot":"","sources":["../../src/test/testUtils.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 { strict as assert } from \"node:assert\";\nimport fs from \"node:fs\";\n\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport { LocalReferenceCollection } from \"../localReference.js\";\nimport { MergeTree } from \"../mergeTree.js\";\nimport {\n\tIMergeTreeDeltaOpArgs,\n\ttype IMergeTreeDeltaCallbackArgs,\n\ttype IMergeTreeMaintenanceCallbackArgs,\n} from \"../mergeTreeDeltaCallback.js\";\nimport { walkAllChildSegments } from \"../mergeTreeNodeWalk.js\";\nimport { MergeBlock, ISegmentPrivate, Marker } from \"../mergeTreeNodes.js\";\nimport { ReferenceType } from \"../ops.js\";\nimport {\n\tPartialSequenceLengths,\n\tverifyExpectedPartialLengths,\n\tverifyPartialLengths,\n} from \"../partialLengths.js\";\nimport { PropertySet } from \"../properties.js\";\nimport * as info from \"../segmentInfos.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { loadText } from \"./text.js\";\n\nexport function loadTextFromFile(\n\tfilename: string,\n\tmergeTree: MergeTree,\n\tsegLimit = 0,\n): MergeTree {\n\tconst content = fs.readFileSync(filename, \"utf8\");\n\treturn loadText(content, mergeTree, segLimit);\n}\n\nexport function loadTextFromFileWithMarkers(\n\tfilename: string,\n\tmergeTree: MergeTree,\n\tsegLimit = 0,\n): MergeTree {\n\tconst content = fs.readFileSync(filename, \"utf8\");\n\treturn loadText(content, mergeTree, segLimit, true);\n}\n\ninterface InsertMarkerArgs {\n\tmergeTree: MergeTree;\n\tpos: number;\n\trefSeq: number;\n\tclientId: number;\n\tseq: number;\n\tbehaviors: ReferenceType;\n\tprops: PropertySet | undefined;\n\topArgs: IMergeTreeDeltaOpArgs;\n}\n\nexport function insertMarker({\n\tmergeTree,\n\tpos,\n\trefSeq,\n\tclientId,\n\tseq,\n\tbehaviors,\n\tprops,\n\topArgs,\n}: InsertMarkerArgs): void {\n\tmergeTree.insertSegments(\n\t\tpos,\n\t\t[Marker.make(behaviors, props)],\n\t\trefSeq,\n\t\tclientId,\n\t\tseq,\n\t\topArgs,\n\t);\n}\n\ninterface InsertTextArgs {\n\tmergeTree: MergeTree;\n\tpos: number;\n\trefSeq: number;\n\tclientId: number;\n\tseq: number;\n\ttext: string;\n\tprops?: PropertySet;\n\topArgs?: IMergeTreeDeltaOpArgs;\n}\n\nexport function insertText({\n\tmergeTree,\n\tpos,\n\trefSeq,\n\tclientId,\n\tseq,\n\ttext,\n\tprops,\n\topArgs,\n}: InsertTextArgs): void {\n\tmergeTree.insertSegments(\n\t\tpos,\n\t\t[TextSegment.make(text, props)],\n\t\trefSeq,\n\t\tclientId,\n\t\tseq,\n\t\topArgs,\n\t);\n}\n\ninterface InsertSegmentsArgs {\n\tmergeTree: MergeTree;\n\tpos: number;\n\tsegments: ISegmentPrivate[];\n\trefSeq: number;\n\tclientId: number;\n\tseq: number;\n\topArgs: IMergeTreeDeltaOpArgs | undefined;\n}\n\nexport function insertSegments({\n\tmergeTree,\n\tpos,\n\tsegments,\n\trefSeq,\n\tclientId,\n\tseq,\n\topArgs,\n}: InsertSegmentsArgs): void {\n\tmergeTree.insertSegments(pos, segments, refSeq, clientId, seq, opArgs);\n}\n\ninterface MarkRangeRemovedArgs {\n\tmergeTree: MergeTree;\n\tstart: number;\n\tend: number;\n\trefSeq: number;\n\tclientId: number;\n\tseq: number;\n\toverwrite: boolean;\n\topArgs: IMergeTreeDeltaOpArgs;\n}\n\nexport function markRangeRemoved({\n\tmergeTree,\n\tstart,\n\tend,\n\trefSeq,\n\tclientId,\n\tseq,\n\topArgs,\n}: MarkRangeRemovedArgs): void {\n\tmergeTree.markRangeRemoved(start, end, refSeq, clientId, seq, opArgs);\n}\n\nexport function obliterateRange({\n\tmergeTree,\n\tstart,\n\tend,\n\trefSeq,\n\tclientId,\n\tseq,\n\topArgs,\n}: {\n\tmergeTree: MergeTree;\n\tstart: number;\n\tend: number;\n\trefSeq: number;\n\tclientId: number;\n\tseq: number;\n\topArgs: IMergeTreeDeltaOpArgs;\n}): void {\n\tmergeTree.obliterateRange(start, end, refSeq, clientId, seq, opArgs);\n}\n\nexport function nodeOrdinalsHaveIntegrity(block: MergeBlock): boolean {\n\tconst olen = block.ordinal.length;\n\tfor (let i = 0; i < block.childCount; i++) {\n\t\tif (block.children[i].ordinal) {\n\t\t\tif (olen !== block.children[i].ordinal.length - 1) {\n\t\t\t\tconsole.log(\"node integrity issue\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (i > 0 && block.children[i].ordinal <= block.children[i - 1].ordinal) {\n\t\t\t\tconsole.log(\"node sib integrity issue\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!block.children[i].isLeaf()) {\n\t\t\t\treturn nodeOrdinalsHaveIntegrity(block.children[i] as MergeBlock);\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.log(`node child ordinal not set ${i}`);\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Returns an object that tallies each delta and maintenance operation observed\n * for the given 'mergeTree'.\n */\nexport function countOperations(mergeTree: MergeTree): object {\n\tconst counts = {};\n\n\tassert.strictEqual(mergeTree.mergeTreeDeltaCallback, undefined);\n\tassert.strictEqual(mergeTree.mergeTreeMaintenanceCallback, undefined);\n\n\tconst fn = (\n\t\tdeltaArgs: IMergeTreeDeltaCallbackArgs | IMergeTreeMaintenanceCallbackArgs,\n\t): void => {\n\t\tconst previous = counts[deltaArgs.operation] as undefined | number;\n\t\tcounts[deltaArgs.operation] = previous === undefined ? 1 : previous + 1;\n\t};\n\n\tmergeTree.mergeTreeDeltaCallback = (opArgs, deltaArgs): void => {\n\t\tfn(deltaArgs);\n\t};\n\tmergeTree.mergeTreeMaintenanceCallback = fn;\n\n\treturn counts;\n}\n\nfunction getPartialLengths(\n\tclientId: number,\n\tseq: number,\n\tmergeTree: MergeTree,\n\tlocalSeq?: number,\n\tmergeBlock: MergeBlock = mergeTree.root,\n): {\n\tpartialLen: number | undefined;\n\tactualLen: number;\n} {\n\tconst partialLen = mergeBlock.partialLengths?.getPartialLength(seq, clientId, localSeq);\n\n\tlet actualLen = 0;\n\n\tconst isInserted = (segment: ISegmentPrivate): boolean =>\n\t\tinfo.isInserted(segment) &&\n\t\t((segment.seq !== UnassignedSequenceNumber && segment.seq <= seq) ||\n\t\t\t(localSeq !== undefined &&\n\t\t\t\tsegment.seq === UnassignedSequenceNumber &&\n\t\t\t\tsegment.localSeq !== undefined &&\n\t\t\t\tsegment.localSeq <= localSeq));\n\n\tconst isRemoved = (segment: ISegmentPrivate): boolean =>\n\t\tinfo.isRemoved(segment) &&\n\t\t((localSeq !== undefined &&\n\t\t\tsegment.removedSeq === UnassignedSequenceNumber &&\n\t\t\tsegment.localRemovedSeq !== undefined &&\n\t\t\tsegment.localRemovedSeq <= localSeq) ||\n\t\t\t(segment.removedSeq !== UnassignedSequenceNumber && segment.removedSeq <= seq));\n\n\tconst isMoved = (segment: ISegmentPrivate): boolean =>\n\t\tinfo.isMoved(segment) &&\n\t\t((localSeq !== undefined &&\n\t\t\tsegment.movedSeq === UnassignedSequenceNumber &&\n\t\t\tsegment.localMovedSeq !== undefined &&\n\t\t\tsegment.localMovedSeq <= localSeq) ||\n\t\t\t(segment.movedSeq !== UnassignedSequenceNumber && segment.movedSeq <= seq));\n\n\twalkAllChildSegments(mergeBlock, (segment) => {\n\t\tif (isInserted(segment) && !isRemoved(segment) && !isMoved(segment)) {\n\t\t\tactualLen += segment.cachedLength;\n\t\t}\n\t\treturn true;\n\t});\n\n\treturn {\n\t\tpartialLen,\n\t\tactualLen,\n\t};\n}\n\nexport function validatePartialLengths(\n\tclientId: number,\n\tmergeTree: MergeTree,\n\texpectedValues?: { seq: number; len: number; localSeq?: number }[],\n\tlocalSeq?: number,\n\tmergeBlock: MergeBlock = mergeTree.root,\n): void {\n\tmergeTree.computeLocalPartials(0);\n\tfor (\n\t\tlet i = mergeTree.collabWindow.minSeq + 1;\n\t\ti <= mergeTree.collabWindow.currentSeq;\n\t\ti++\n\t) {\n\t\tconst { partialLen, actualLen } = getPartialLengths(\n\t\t\tclientId,\n\t\t\ti,\n\t\t\tmergeTree,\n\t\t\tlocalSeq,\n\t\t\tmergeBlock,\n\t\t);\n\n\t\tif (partialLen && partialLen < 0) {\n\t\t\tassert.fail(\"Negative partial length returned\");\n\t\t}\n\t\tassert.equal(partialLen, actualLen);\n\t}\n\n\tif (!expectedValues) {\n\t\treturn;\n\t}\n\n\tfor (const { seq, len, localSeq: expectedLocalSeq } of expectedValues) {\n\t\tconst { partialLen, actualLen } = getPartialLengths(\n\t\t\tclientId,\n\t\t\tseq,\n\t\t\tmergeTree,\n\t\t\texpectedLocalSeq ?? localSeq,\n\t\t\tmergeBlock,\n\t\t);\n\n\t\tassert.equal(partialLen, len);\n\t\tassert.equal(actualLen, len);\n\t}\n}\n\nexport function validateRefCount(collection?: LocalReferenceCollection): void {\n\tif (!collection) {\n\t\treturn;\n\t}\n\n\tconst expectedLength = [...collection].length;\n\n\t// eslint-disable-next-line @typescript-eslint/dot-notation\n\tassert.equal(collection[\"refCount\"], expectedLength);\n}\n\n/**\n * Enable stricter partial length assertions inside tests\n *\n * Note that these assertions can be expensive, and so should not be enabled in\n * production code or tests that run through thousands of ops (e.g. the SharedString\n * fuzz tests).\n */\nexport function useStrictPartialLengthChecks(): void {\n\tbeforeEach(() => {\n\t\tPartialSequenceLengths.options.verifier = verifyPartialLengths;\n\t\tPartialSequenceLengths.options.verifyExpected = verifyExpectedPartialLengths;\n\t});\n\n\tafterEach(() => {\n\t\tPartialSequenceLengths.options.verifier = undefined;\n\t\tPartialSequenceLengths.options.verifyExpected = undefined;\n\t});\n}\n"]}
1
+ {"version":3,"file":"testUtils.js","sourceRoot":"","sources":["../../src/test/testUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,6CAA+C;AAC/C,sDAAyB;AAEzB,kDAA2D;AAQ3D,kEAA+D;AAC/D,4DAA2E;AAE3E,4DAI8B;AAE9B,yDAA2C;AAC3C,sDAAgD;AAEhD,uCAAqC;AAErC,SAAgB,gBAAgB,CAC/B,QAAgB,EAChB,SAAoB,EACpB,QAAQ,GAAG,CAAC;IAEZ,MAAM,OAAO,GAAG,iBAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClD,OAAO,IAAA,kBAAQ,EAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAPD,4CAOC;AAED,SAAgB,2BAA2B,CAC1C,QAAgB,EAChB,SAAoB,EACpB,QAAQ,GAAG,CAAC;IAEZ,MAAM,OAAO,GAAG,iBAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClD,OAAO,IAAA,kBAAQ,EAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;AACrD,CAAC;AAPD,kEAOC;AAaD,SAAgB,YAAY,CAAC,EAC5B,SAAS,EACT,GAAG,EACH,MAAM,EACN,QAAQ,EACR,GAAG,EACH,SAAS,EACT,KAAK,EACL,MAAM,GACY;IAClB,SAAS,CAAC,cAAc,CACvB,GAAG,EACH,CAAC,0BAAM,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,EAC/B,MAAM,EACN,QAAQ,EACR,GAAG,EACH,MAAM,CACN,CAAC;AACH,CAAC;AAlBD,oCAkBC;AAaD,SAAgB,UAAU,CAAC,EAC1B,SAAS,EACT,GAAG,EACH,MAAM,EACN,QAAQ,EACR,GAAG,EACH,IAAI,EACJ,KAAK,EACL,MAAM,GACU;IAChB,SAAS,CAAC,cAAc,CACvB,GAAG,EACH,CAAC,4BAAW,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAC/B,MAAM,EACN,QAAQ,EACR,GAAG,EACH,MAAM,CACN,CAAC;AACH,CAAC;AAlBD,gCAkBC;AAYD,SAAgB,cAAc,CAAC,EAC9B,SAAS,EACT,GAAG,EACH,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,GAAG,EACH,MAAM,GACc;IACpB,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AACxE,CAAC;AAVD,wCAUC;AAaD,SAAgB,gBAAgB,CAAC,EAChC,SAAS,EACT,KAAK,EACL,GAAG,EACH,MAAM,EACN,QAAQ,EACR,GAAG,EACH,MAAM,GACgB;IACtB,SAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AACvE,CAAC;AAVD,4CAUC;AAED,SAAgB,eAAe,CAAC,EAC/B,SAAS,EACT,KAAK,EACL,GAAG,EACH,MAAM,EACN,QAAQ,EACR,GAAG,EACH,MAAM,GASN;IACA,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AACtE,CAAC;AAlBD,0CAkBC;AAED,SAAgB,yBAAyB,CAAC,KAAiB;IAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YAC/B,IAAI,IAAI,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnD,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;gBACpC,OAAO,KAAK,CAAC;YACd,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;gBACzE,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;gBACxC,OAAO,KAAK,CAAC;YACd,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;gBACjC,OAAO,yBAAyB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAe,CAAC,CAAC;YACnE,CAAC;QACF,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC;YAC/C,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AArBD,8DAqBC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,SAAoB;IACnD,MAAM,MAAM,GAAG,EAAE,CAAC;IAElB,oBAAM,CAAC,WAAW,CAAC,SAAS,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC;IAChE,oBAAM,CAAC,WAAW,CAAC,SAAS,CAAC,4BAA4B,EAAE,SAAS,CAAC,CAAC;IAEtE,MAAM,EAAE,GAAG,CACV,SAA0E,EACnE,EAAE;QACT,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,CAAuB,CAAC;QACnE,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC;IACzE,CAAC,CAAC;IAEF,SAAS,CAAC,sBAAsB,GAAG,CAAC,MAAM,EAAE,SAAS,EAAQ,EAAE;QAC9D,EAAE,CAAC,SAAS,CAAC,CAAC;IACf,CAAC,CAAC;IACF,SAAS,CAAC,4BAA4B,GAAG,EAAE,CAAC;IAE5C,OAAO,MAAM,CAAC;AACf,CAAC;AAnBD,0CAmBC;AAED,SAAS,iBAAiB,CACzB,QAAgB,EAChB,GAAW,EACX,SAAoB,EACpB,QAAiB,EACjB,aAAyB,SAAS,CAAC,IAAI;IAKvC,MAAM,UAAU,GAAG,UAAU,CAAC,cAAc,EAAE,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAExF,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,MAAM,UAAU,GAAG,CAAC,OAAwB,EAAW,EAAE,CACxD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QACxB,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,uCAAwB,IAAI,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC;YAChE,CAAC,QAAQ,KAAK,SAAS;gBACtB,OAAO,CAAC,GAAG,KAAK,uCAAwB;gBACxC,OAAO,CAAC,QAAQ,KAAK,SAAS;gBAC9B,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,CAAC;IAElC,MAAM,SAAS,GAAG,CAAC,OAAwB,EAAW,EAAE,CACvD,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QACvB,CAAC,CAAC,QAAQ,KAAK,SAAS;YACvB,OAAO,CAAC,UAAU,KAAK,uCAAwB;YAC/C,OAAO,CAAC,eAAe,KAAK,SAAS;YACrC,OAAO,CAAC,eAAe,IAAI,QAAQ,CAAC;YACpC,CAAC,OAAO,CAAC,UAAU,KAAK,uCAAwB,IAAI,OAAO,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC;IAElF,MAAM,OAAO,GAAG,CAAC,OAAwB,EAAW,EAAE,CACrD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACrB,CAAC,CAAC,QAAQ,KAAK,SAAS;YACvB,OAAO,CAAC,QAAQ,KAAK,uCAAwB;YAC7C,OAAO,CAAC,aAAa,KAAK,SAAS;YACnC,OAAO,CAAC,aAAa,IAAI,QAAQ,CAAC;YAClC,CAAC,OAAO,CAAC,QAAQ,KAAK,uCAAwB,IAAI,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC;IAE9E,IAAA,2CAAoB,EAAC,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE;QAC5C,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACrE,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,OAAO;QACN,UAAU;QACV,SAAS;KACT,CAAC;AACH,CAAC;AAED,SAAgB,sBAAsB,CACrC,QAAgB,EAChB,SAAoB,EACpB,cAAkE,EAClE,QAAiB,EACjB,aAAyB,SAAS,CAAC,IAAI;IAEvC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;IAClC,KACC,IAAI,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EACzC,CAAC,IAAI,SAAS,CAAC,YAAY,CAAC,UAAU,EACtC,CAAC,EAAE,EACF,CAAC;QACF,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,iBAAiB,CAClD,QAAQ,EACR,CAAC,EACD,SAAS,EACT,QAAQ,EACR,UAAU,CACV,CAAC;QAEF,IAAI,UAAU,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YAClC,oBAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QACjD,CAAC;QACD,oBAAM,CAAC,KAAK,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,OAAO;IACR,CAAC;IAED,KAAK,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,gBAAgB,EAAE,IAAI,cAAc,EAAE,CAAC;QACvE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,iBAAiB,CAClD,QAAQ,EACR,GAAG,EACH,SAAS,EACT,gBAAgB,IAAI,QAAQ,EAC5B,UAAU,CACV,CAAC;QAEF,oBAAM,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAC9B,oBAAM,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC;AACF,CAAC;AA3CD,wDA2CC;AAED,SAAgB,gBAAgB,CAAC,UAAqC;IACrE,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,OAAO;IACR,CAAC;IAED,MAAM,cAAc,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,MAAM,CAAC;IAE9C,2DAA2D;IAC3D,oBAAM,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC,CAAC;AACtD,CAAC;AATD,4CASC;AAED;;;;;;GAMG;AACH,SAAgB,4BAA4B;IAC3C,UAAU,CAAC,+BAA+B,EAAE,GAAG,EAAE;QAChD,0CAAsB,CAAC,OAAO,CAAC,QAAQ,GAAG,wCAAoB,CAAC;QAC/D,0CAAsB,CAAC,OAAO,CAAC,cAAc,GAAG,gDAA4B,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,gCAAgC,EAAE,GAAG,EAAE;QAChD,0CAAsB,CAAC,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;QACpD,0CAAsB,CAAC,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAC3D,CAAC,CAAC,CAAC;AACJ,CAAC;AAVD,oEAUC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport fs from \"node:fs\";\n\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport { LocalReferenceCollection } from \"../localReference.js\";\nimport { MergeTree } from \"../mergeTree.js\";\nimport {\n\tIMergeTreeDeltaOpArgs,\n\ttype IMergeTreeDeltaCallbackArgs,\n\ttype IMergeTreeMaintenanceCallbackArgs,\n} from \"../mergeTreeDeltaCallback.js\";\nimport { walkAllChildSegments } from \"../mergeTreeNodeWalk.js\";\nimport { MergeBlock, ISegmentPrivate, Marker } from \"../mergeTreeNodes.js\";\nimport { ReferenceType } from \"../ops.js\";\nimport {\n\tPartialSequenceLengths,\n\tverifyExpectedPartialLengths,\n\tverifyPartialLengths,\n} from \"../partialLengths.js\";\nimport { PropertySet } from \"../properties.js\";\nimport * as info from \"../segmentInfos.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { loadText } from \"./text.js\";\n\nexport function loadTextFromFile(\n\tfilename: string,\n\tmergeTree: MergeTree,\n\tsegLimit = 0,\n): MergeTree {\n\tconst content = fs.readFileSync(filename, \"utf8\");\n\treturn loadText(content, mergeTree, segLimit);\n}\n\nexport function loadTextFromFileWithMarkers(\n\tfilename: string,\n\tmergeTree: MergeTree,\n\tsegLimit = 0,\n): MergeTree {\n\tconst content = fs.readFileSync(filename, \"utf8\");\n\treturn loadText(content, mergeTree, segLimit, true);\n}\n\ninterface InsertMarkerArgs {\n\tmergeTree: MergeTree;\n\tpos: number;\n\trefSeq: number;\n\tclientId: number;\n\tseq: number;\n\tbehaviors: ReferenceType;\n\tprops: PropertySet | undefined;\n\topArgs: IMergeTreeDeltaOpArgs;\n}\n\nexport function insertMarker({\n\tmergeTree,\n\tpos,\n\trefSeq,\n\tclientId,\n\tseq,\n\tbehaviors,\n\tprops,\n\topArgs,\n}: InsertMarkerArgs): void {\n\tmergeTree.insertSegments(\n\t\tpos,\n\t\t[Marker.make(behaviors, props)],\n\t\trefSeq,\n\t\tclientId,\n\t\tseq,\n\t\topArgs,\n\t);\n}\n\ninterface InsertTextArgs {\n\tmergeTree: MergeTree;\n\tpos: number;\n\trefSeq: number;\n\tclientId: number;\n\tseq: number;\n\ttext: string;\n\tprops?: PropertySet;\n\topArgs?: IMergeTreeDeltaOpArgs;\n}\n\nexport function insertText({\n\tmergeTree,\n\tpos,\n\trefSeq,\n\tclientId,\n\tseq,\n\ttext,\n\tprops,\n\topArgs,\n}: InsertTextArgs): void {\n\tmergeTree.insertSegments(\n\t\tpos,\n\t\t[TextSegment.make(text, props)],\n\t\trefSeq,\n\t\tclientId,\n\t\tseq,\n\t\topArgs,\n\t);\n}\n\ninterface InsertSegmentsArgs {\n\tmergeTree: MergeTree;\n\tpos: number;\n\tsegments: ISegmentPrivate[];\n\trefSeq: number;\n\tclientId: number;\n\tseq: number;\n\topArgs: IMergeTreeDeltaOpArgs | undefined;\n}\n\nexport function insertSegments({\n\tmergeTree,\n\tpos,\n\tsegments,\n\trefSeq,\n\tclientId,\n\tseq,\n\topArgs,\n}: InsertSegmentsArgs): void {\n\tmergeTree.insertSegments(pos, segments, refSeq, clientId, seq, opArgs);\n}\n\ninterface MarkRangeRemovedArgs {\n\tmergeTree: MergeTree;\n\tstart: number;\n\tend: number;\n\trefSeq: number;\n\tclientId: number;\n\tseq: number;\n\toverwrite: boolean;\n\topArgs: IMergeTreeDeltaOpArgs;\n}\n\nexport function markRangeRemoved({\n\tmergeTree,\n\tstart,\n\tend,\n\trefSeq,\n\tclientId,\n\tseq,\n\topArgs,\n}: MarkRangeRemovedArgs): void {\n\tmergeTree.markRangeRemoved(start, end, refSeq, clientId, seq, opArgs);\n}\n\nexport function obliterateRange({\n\tmergeTree,\n\tstart,\n\tend,\n\trefSeq,\n\tclientId,\n\tseq,\n\topArgs,\n}: {\n\tmergeTree: MergeTree;\n\tstart: number;\n\tend: number;\n\trefSeq: number;\n\tclientId: number;\n\tseq: number;\n\topArgs: IMergeTreeDeltaOpArgs;\n}): void {\n\tmergeTree.obliterateRange(start, end, refSeq, clientId, seq, opArgs);\n}\n\nexport function nodeOrdinalsHaveIntegrity(block: MergeBlock): boolean {\n\tconst olen = block.ordinal.length;\n\tfor (let i = 0; i < block.childCount; i++) {\n\t\tif (block.children[i].ordinal) {\n\t\t\tif (olen !== block.children[i].ordinal.length - 1) {\n\t\t\t\tconsole.log(\"node integrity issue\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (i > 0 && block.children[i].ordinal <= block.children[i - 1].ordinal) {\n\t\t\t\tconsole.log(\"node sib integrity issue\");\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!block.children[i].isLeaf()) {\n\t\t\t\treturn nodeOrdinalsHaveIntegrity(block.children[i] as MergeBlock);\n\t\t\t}\n\t\t} else {\n\t\t\tconsole.log(`node child ordinal not set ${i}`);\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Returns an object that tallies each delta and maintenance operation observed\n * for the given 'mergeTree'.\n */\nexport function countOperations(mergeTree: MergeTree): object {\n\tconst counts = {};\n\n\tassert.strictEqual(mergeTree.mergeTreeDeltaCallback, undefined);\n\tassert.strictEqual(mergeTree.mergeTreeMaintenanceCallback, undefined);\n\n\tconst fn = (\n\t\tdeltaArgs: IMergeTreeDeltaCallbackArgs | IMergeTreeMaintenanceCallbackArgs,\n\t): void => {\n\t\tconst previous = counts[deltaArgs.operation] as undefined | number;\n\t\tcounts[deltaArgs.operation] = previous === undefined ? 1 : previous + 1;\n\t};\n\n\tmergeTree.mergeTreeDeltaCallback = (opArgs, deltaArgs): void => {\n\t\tfn(deltaArgs);\n\t};\n\tmergeTree.mergeTreeMaintenanceCallback = fn;\n\n\treturn counts;\n}\n\nfunction getPartialLengths(\n\tclientId: number,\n\tseq: number,\n\tmergeTree: MergeTree,\n\tlocalSeq?: number,\n\tmergeBlock: MergeBlock = mergeTree.root,\n): {\n\tpartialLen: number | undefined;\n\tactualLen: number;\n} {\n\tconst partialLen = mergeBlock.partialLengths?.getPartialLength(seq, clientId, localSeq);\n\n\tlet actualLen = 0;\n\n\tconst isInserted = (segment: ISegmentPrivate): boolean =>\n\t\tinfo.isInserted(segment) &&\n\t\t((segment.seq !== UnassignedSequenceNumber && segment.seq <= seq) ||\n\t\t\t(localSeq !== undefined &&\n\t\t\t\tsegment.seq === UnassignedSequenceNumber &&\n\t\t\t\tsegment.localSeq !== undefined &&\n\t\t\t\tsegment.localSeq <= localSeq));\n\n\tconst isRemoved = (segment: ISegmentPrivate): boolean =>\n\t\tinfo.isRemoved(segment) &&\n\t\t((localSeq !== undefined &&\n\t\t\tsegment.removedSeq === UnassignedSequenceNumber &&\n\t\t\tsegment.localRemovedSeq !== undefined &&\n\t\t\tsegment.localRemovedSeq <= localSeq) ||\n\t\t\t(segment.removedSeq !== UnassignedSequenceNumber && segment.removedSeq <= seq));\n\n\tconst isMoved = (segment: ISegmentPrivate): boolean =>\n\t\tinfo.isMoved(segment) &&\n\t\t((localSeq !== undefined &&\n\t\t\tsegment.movedSeq === UnassignedSequenceNumber &&\n\t\t\tsegment.localMovedSeq !== undefined &&\n\t\t\tsegment.localMovedSeq <= localSeq) ||\n\t\t\t(segment.movedSeq !== UnassignedSequenceNumber && segment.movedSeq <= seq));\n\n\twalkAllChildSegments(mergeBlock, (segment) => {\n\t\tif (isInserted(segment) && !isRemoved(segment) && !isMoved(segment)) {\n\t\t\tactualLen += segment.cachedLength;\n\t\t}\n\t\treturn true;\n\t});\n\n\treturn {\n\t\tpartialLen,\n\t\tactualLen,\n\t};\n}\n\nexport function validatePartialLengths(\n\tclientId: number,\n\tmergeTree: MergeTree,\n\texpectedValues?: { seq: number; len: number; localSeq?: number }[],\n\tlocalSeq?: number,\n\tmergeBlock: MergeBlock = mergeTree.root,\n): void {\n\tmergeTree.computeLocalPartials(0);\n\tfor (\n\t\tlet i = mergeTree.collabWindow.minSeq + 1;\n\t\ti <= mergeTree.collabWindow.currentSeq;\n\t\ti++\n\t) {\n\t\tconst { partialLen, actualLen } = getPartialLengths(\n\t\t\tclientId,\n\t\t\ti,\n\t\t\tmergeTree,\n\t\t\tlocalSeq,\n\t\t\tmergeBlock,\n\t\t);\n\n\t\tif (partialLen && partialLen < 0) {\n\t\t\tassert.fail(\"Negative partial length returned\");\n\t\t}\n\t\tassert.equal(partialLen, actualLen);\n\t}\n\n\tif (!expectedValues) {\n\t\treturn;\n\t}\n\n\tfor (const { seq, len, localSeq: expectedLocalSeq } of expectedValues) {\n\t\tconst { partialLen, actualLen } = getPartialLengths(\n\t\t\tclientId,\n\t\t\tseq,\n\t\t\tmergeTree,\n\t\t\texpectedLocalSeq ?? localSeq,\n\t\t\tmergeBlock,\n\t\t);\n\n\t\tassert.equal(partialLen, len);\n\t\tassert.equal(actualLen, len);\n\t}\n}\n\nexport function validateRefCount(collection?: LocalReferenceCollection): void {\n\tif (!collection) {\n\t\treturn;\n\t}\n\n\tconst expectedLength = [...collection].length;\n\n\t// eslint-disable-next-line @typescript-eslint/dot-notation\n\tassert.equal(collection[\"refCount\"], expectedLength);\n}\n\n/**\n * Enable stricter partial length assertions inside tests\n *\n * Note that these assertions can be expensive, and so should not be enabled in\n * production code or tests that run through thousands of ops (e.g. the SharedString\n * fuzz tests).\n */\nexport function useStrictPartialLengthChecks(): void {\n\tbeforeEach(\"Enable strict partial lengths\", () => {\n\t\tPartialSequenceLengths.options.verifier = verifyPartialLengths;\n\t\tPartialSequenceLengths.options.verifyExpected = verifyExpectedPartialLengths;\n\t});\n\n\tafterEach(\"Disable strict partial lengths\", () => {\n\t\tPartialSequenceLengths.options.verifier = undefined;\n\t\tPartialSequenceLengths.options.verifyExpected = undefined;\n\t});\n}\n"]}
@@ -130,7 +130,6 @@ export class AttributionCollection {
130
130
  return splitCollection;
131
131
  }
132
132
  append(other) {
133
- var _a;
134
133
  const lastEntry = this.keys[this.keys.length - 1];
135
134
  for (let i = 0; i < other.keys.length; i++) {
136
135
  if (i !== 0 || !areEqualAttributionKeys(lastEntry, other.keys[i])) {
@@ -139,12 +138,12 @@ export class AttributionCollection {
139
138
  }
140
139
  }
141
140
  if (other.channels !== undefined || this.channels !== undefined) {
142
- this.channels ?? (this.channels = {});
141
+ this.channels ??= {};
143
142
  for (const [key, collection] of other.channelEntries) {
144
- const thisCollection = ((_a = this.channels)[key] ?? (_a[key] = new AttributionCollection(this.length,
143
+ const thisCollection = (this.channels[key] ??= new AttributionCollection(this.length,
145
144
  // Null is needed as null and undefined have different meanings in the context of attribution collections.
146
145
  // eslint-disable-next-line unicorn/no-null
147
- null)));
146
+ null));
148
147
  thisCollection.append(collection);
149
148
  }
150
149
  for (const [key, collection] of this.channelEntries) {
@@ -193,7 +192,7 @@ export class AttributionCollection {
193
192
  this.keys = [...channel.keys];
194
193
  }
195
194
  else {
196
- this.channels ?? (this.channels = {});
195
+ this.channels ??= {};
197
196
  if (this.channels[name] === undefined) {
198
197
  this.channels[name] = channel;
199
198
  }
@@ -249,10 +248,9 @@ export class AttributionCollection {
249
248
  if (channels) {
250
249
  for (const [name, collectionSpec] of Object.entries(channels)) {
251
250
  extractOntoSegments(collectionSpec, (collection, segment) => {
252
- var _a;
253
251
  if (segment.attribution !== undefined) {
254
252
  // Cast is valid as we just assigned this field above
255
- ((_a = segment.attribution).channels ?? (_a.channels = {}))[name] =
253
+ (segment.attribution.channels ??= {})[name] =
256
254
  collection;
257
255
  }
258
256
  });
@@ -1 +1 @@
1
- {"version":3,"file":"attributionCollection.js","sourceRoot":"","sources":["../src/attributionCollection.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 {\n\tAttributionKey,\n\tDetachedAttributionKey,\n\tOpAttributionKey,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { ISegment } from \"./mergeTreeNodes.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport interface SequenceOffsets {\n\t/**\n\t * Parallel array with posBreakpoints which tracks the seq of insertion.\n\t *\n\t * @example\n\t *\n\t * If seqs is [45, 46] and posBreakpoints is [0, 3], the section of the string\n\t * between offsets 0 and 3 was inserted at seq 45 and the section of the string between\n\t * 3 and the length of the string was inserted at seq 46.\n\t *\n\t * @remarks We use null here rather than undefined as round-tripping through JSON converts\n\t * undefineds to null anyway\n\t */\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tseqs: (number | AttributionKey | null)[];\n\tposBreakpoints: number[];\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface SerializedAttributionCollection extends SequenceOffsets {\n\tchannels?: { [name: string]: SequenceOffsets };\n\t/* Total length; only necessary for validation */\n\tlength: number;\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface IAttributionCollectionSpec<T> {\n\t// eslint-disable-next-line @rushstack/no-new-null\n\troot: Iterable<{ offset: number; key: T | null }>;\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tchannels?: { [name: string]: Iterable<{ offset: number; key: T | null }> };\n\tlength: number;\n}\n\n/**\n * @legacy\n * @alpha\n * @sealed\n */\nexport interface IAttributionCollectionSerializer {\n\t/***/\n\tserializeAttributionCollections(\n\t\tsegments: Iterable<{\n\t\t\tattribution?: IAttributionCollection<AttributionKey>;\n\t\t\tcachedLength: number;\n\t\t}>,\n\t): SerializedAttributionCollection;\n\n\t/**\n\t * Populates attribution information on segments using the provided summary.\n\t */\n\tpopulateAttributionCollections(\n\t\tsegments: Iterable<ISegment>,\n\t\tsummary: SerializedAttributionCollection,\n\t): void;\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface IAttributionCollection<T> {\n\t/**\n\t * Retrieves the attribution key associated with the provided offset.\n\t * @param channel - When specified, gets an attribution key associated with a particular channel.\n\t */\n\tgetAtOffset(offset: number, channel?: string): AttributionKey | undefined;\n\n\t/**\n\t * Retrieves all the [Offset, Attribution key] pairs for the provided offset range. Note:\n\t * The returned array is sorted by offset.\n\t * The first offset in response could be lower than the startOffset as the Attribution Key for the startOffset\n\t * could start at a lower offset than the startOffset in case where Attribution key offset boundaries don't\n\t * align exactly with startOffset.\n\t * Example: If the Attribution Offsets in the segment is [0, 10, 20, 30, 40] and request is for (startOffset: 5, endOffset: 25),\n\t * then result would be [(offset: 0, key: key1), (offset:10, key: key2), (offset:20, key: key3)].\n\t * @param channel - When specified, gets attribution keys associated with a particular channel.\n\t * @returns - undefined if the provided channel is not found or list of attribution keys along with\n\t * the corresponding offset start boundary.\n\t */\n\tgetKeysInOffsetRange(\n\t\tstartOffset: number,\n\t\tendOffset?: number,\n\t\tchannel?: string,\n\t): { offset: number; key: AttributionKey }[] | undefined;\n\n\t/**\n\t * Total length of all attribution keys in this collection.\n\t */\n\treadonly length: number;\n\n\treadonly channelNames: Iterable<string>;\n\n\t/**\n\t * Retrieve all key/offset pairs stored on this segment. Entries should be ordered by offset, such that\n\t * the `i`th result's attribution key applies to offsets in the open range between the `i`th offset and the\n\t * `i+1`th offset.\n\t * The last entry's key applies to the open interval from the last entry's offset to this collection's length.\n\t */\n\tgetAll(): IAttributionCollectionSpec<T>;\n\n\t/***/\n\tsplitAt(pos: number): IAttributionCollection<T>;\n\n\t/***/\n\tappend(other: IAttributionCollection<T>): void;\n\n\t/***/\n\tclone(): IAttributionCollection<T>;\n\n\t/**\n\t * Updates this collection with new attribution data.\n\t * @param name - Name of the channel that requires an update. Undefined signifies the root channel.\n\t * Updates apply only to the individual channel (i.e. if an attribution policy needs to update the root\n\t * channel and 4 other channels, it should call `.update` 5 times).\n\t * @param channel - Updated collection for that channel.\n\t */\n\tupdate(name: string | undefined, channel: IAttributionCollection<T>): void;\n}\n\n// note: treats null and undefined as equivalent\nexport function areEqualAttributionKeys(\n\t// eslint-disable-next-line @rushstack/no-new-null\n\ta: AttributionKey | null | undefined,\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tb: AttributionKey | null | undefined,\n): boolean {\n\tif (!a && !b) {\n\t\treturn true;\n\t}\n\n\tif (!a || !b) {\n\t\treturn false;\n\t}\n\n\tif (a.type !== b.type) {\n\t\treturn false;\n\t}\n\n\t// Note: TS can't narrow the type of b inside this switch statement, hence the need for casting.\n\tswitch (a.type) {\n\t\tcase \"op\": {\n\t\t\treturn a.seq === (b as OpAttributionKey).seq;\n\t\t}\n\t\tcase \"detached\": {\n\t\t\treturn a.id === (b as DetachedAttributionKey).id;\n\t\t}\n\t\tcase \"local\": {\n\t\t\treturn true;\n\t\t}\n\t\tdefault: {\n\t\t\tunreachableCase(a, \"Unhandled AttributionKey type\");\n\t\t}\n\t}\n}\n\nexport class AttributionCollection implements IAttributionCollection<AttributionKey> {\n\tprivate offsets: number[] = [];\n\tprivate keys: (AttributionKey | null)[] = [];\n\n\tprivate channels?: { [name: string]: AttributionCollection };\n\n\tprivate get channelEntries(): [string, AttributionCollection][] {\n\t\treturn Object.entries(this.channels ?? {});\n\t}\n\n\tpublic constructor(\n\t\tprivate _length: number,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tbaseEntry?: AttributionKey | null,\n\t) {\n\t\tif (baseEntry !== undefined) {\n\t\t\tthis.offsets.push(0);\n\t\t\tthis.keys.push(baseEntry);\n\t\t}\n\t}\n\n\tpublic get channelNames(): string[] {\n\t\treturn Object.keys(this.channels ?? {});\n\t}\n\n\tpublic getAtOffset(offset: number): AttributionKey;\n\tpublic getAtOffset(offset: number, channel: string): AttributionKey | undefined;\n\tpublic getAtOffset(offset: number, channel?: string): AttributionKey | undefined {\n\t\tif (channel !== undefined) {\n\t\t\tconst subCollection = this.channels?.[channel];\n\t\t\treturn subCollection?.getAtOffset(offset);\n\t\t}\n\t\tassert(offset >= 0 && offset < this._length, 0x443 /* Requested offset should be valid */);\n\t\treturn this.get(this.findIndex(offset));\n\t}\n\n\tpublic getKeysInOffsetRange(\n\t\tstartOffset: number,\n\t\tendOffset?: number,\n\t): { offset: number; key: AttributionKey }[];\n\tpublic getKeysInOffsetRange(\n\t\tstartOffset: number,\n\t\tendOffset?: number,\n\t\tchannel?: string,\n\t): { offset: number; key: AttributionKey }[] | undefined;\n\tpublic getKeysInOffsetRange(\n\t\tstartOffset: number,\n\t\tendOffset?: number,\n\t\tchannel?: string,\n\t): { offset: number; key: AttributionKey }[] | undefined {\n\t\tif (startOffset < 0 || startOffset >= this._length) {\n\t\t\tthrow new UsageError(\"startOffset should be valid and in range\");\n\t\t}\n\t\tif (\n\t\t\tendOffset !== undefined &&\n\t\t\t(endOffset < 0 || endOffset >= this._length || startOffset > endOffset)\n\t\t) {\n\t\t\tthrow new UsageError(\"endOffset should be valid and in range\");\n\t\t}\n\n\t\tif (channel !== undefined) {\n\t\t\tconst subCollection = this.channels?.[channel];\n\t\t\treturn subCollection?.getKeysInOffsetRange(startOffset, endOffset);\n\t\t}\n\t\tconst result: { offset: number; key: AttributionKey }[] = [];\n\t\tlet index = this.findIndex(startOffset);\n\t\tlet attributionKey = this.get(index);\n\t\tif (attributionKey !== undefined) {\n\t\t\tresult.push({ offset: this.offsets[index], key: attributionKey });\n\t\t}\n\t\tindex++;\n\t\tconst endOffsetVal = endOffset ?? Number.MAX_SAFE_INTEGER;\n\t\twhile (index < this.offsets.length && endOffsetVal >= this.offsets[index]) {\n\t\t\tattributionKey = this.get(index);\n\t\t\tif (attributionKey !== undefined) {\n\t\t\t\tresult.push({ offset: this.offsets[index], key: attributionKey });\n\t\t\t}\n\t\t\tindex++;\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate findIndex(offset: number): number {\n\t\t// Note: maximum length here is 256 for text segments. Perf testing shows that linear scan beats binary search\n\t\t// for attribution collections with under ~64 entries, and even at maximum size (which would require a maximum\n\t\t// length segment with every offset having different attribution), getAtOffset is on the order of 100ns.\n\t\tlet i = 0;\n\t\twhile (i < this.offsets.length && offset > this.offsets[i]) {\n\t\t\ti++;\n\t\t}\n\t\treturn this.offsets[i] === offset ? i : i - 1;\n\t}\n\n\tprivate get(index: number): AttributionKey | undefined {\n\t\tconst key = this.keys[index];\n\t\treturn key ?? undefined;\n\t}\n\n\tpublic get length(): number {\n\t\treturn this._length;\n\t}\n\n\t/**\n\t * Splits this attribution collection into two with entries for [0, pos) and [pos, length).\n\t */\n\tpublic splitAt(pos: number): AttributionCollection {\n\t\tconst splitIndex = this.findIndex(pos);\n\t\tconst splitCollection = new AttributionCollection(this.length - pos);\n\t\tfor (let i = splitIndex; i < this.keys.length; i++) {\n\t\t\tsplitCollection.offsets.push(Math.max(this.offsets[i] - pos, 0));\n\t\t\tsplitCollection.keys.push(this.keys[i]);\n\t\t}\n\n\t\tif (this.channels) {\n\t\t\tsplitCollection.channels = {};\n\t\t\tfor (const [key, collection] of this.channelEntries) {\n\t\t\t\tsplitCollection.channels[key] = collection.splitAt(pos);\n\t\t\t}\n\t\t}\n\n\t\tconst spliceIndex = this.offsets[splitIndex] === pos ? splitIndex : splitIndex + 1;\n\t\tthis.keys.splice(spliceIndex);\n\t\tthis.offsets.splice(spliceIndex);\n\t\tthis._length = pos;\n\t\treturn splitCollection;\n\t}\n\n\tpublic append(other: AttributionCollection): void {\n\t\tconst lastEntry = this.keys[this.keys.length - 1];\n\t\tfor (let i = 0; i < other.keys.length; i++) {\n\t\t\tif (i !== 0 || !areEqualAttributionKeys(lastEntry, other.keys[i])) {\n\t\t\t\tthis.offsets.push(other.offsets[i] + this.length);\n\t\t\t\tthis.keys.push(other.keys[i]);\n\t\t\t}\n\t\t}\n\n\t\tif (other.channels !== undefined || this.channels !== undefined) {\n\t\t\tthis.channels ??= {};\n\t\t\tfor (const [key, collection] of other.channelEntries) {\n\t\t\t\tconst thisCollection = (this.channels[key] ??= new AttributionCollection(\n\t\t\t\t\tthis.length,\n\t\t\t\t\t// Null is needed as null and undefined have different meanings in the context of attribution collections.\n\t\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\t\tnull,\n\t\t\t\t));\n\t\t\t\tthisCollection.append(collection);\n\t\t\t}\n\t\t\tfor (const [key, collection] of this.channelEntries) {\n\t\t\t\tif (other.channels?.[key] === undefined) {\n\t\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\t\tcollection.append(new AttributionCollection(other.length, null));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis._length += other.length;\n\t}\n\n\tpublic getAll(): IAttributionCollectionSpec<AttributionKey> {\n\t\ttype ExtractGeneric<T> = T extends Iterable<infer Q> ? Q : unknown;\n\t\tconst root: ExtractGeneric<IAttributionCollectionSpec<AttributionKey>[\"root\"]>[] =\n\t\t\tArray.from({ length: this.keys.length });\n\t\tfor (let i = 0; i < this.keys.length; i++) {\n\t\t\troot[i] = { offset: this.offsets[i], key: this.keys[i] };\n\t\t}\n\t\tconst result: IAttributionCollectionSpec<AttributionKey> = {\n\t\t\troot,\n\t\t\tlength: this.length,\n\t\t};\n\t\tif (this.channels !== undefined) {\n\t\t\tresult.channels = {};\n\t\t\tfor (const [key, collection] of this.channelEntries) {\n\t\t\t\tresult.channels[key] = collection.getAll().root;\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tpublic clone(): AttributionCollection {\n\t\tconst copy = new AttributionCollection(this.length);\n\t\tcopy.keys = [...this.keys];\n\t\tcopy.offsets = [...this.offsets];\n\t\tif (this.channels !== undefined) {\n\t\t\tconst channelsCopy: Record<string, AttributionCollection> = {};\n\t\t\tfor (const [key, collection] of this.channelEntries) {\n\t\t\t\tchannelsCopy[key] = collection.clone();\n\t\t\t}\n\t\t\tcopy.channels = channelsCopy;\n\t\t}\n\t\treturn copy;\n\t}\n\n\tpublic update(name: string | undefined, channel: AttributionCollection): void {\n\t\tassert(\n\t\t\tchannel.length === this.length,\n\t\t\t0x5c0 /* AttributionCollection channel update should have consistent segment length */,\n\t\t);\n\t\tif (name === undefined) {\n\t\t\tthis.offsets = [...channel.offsets];\n\t\t\tthis.keys = [...channel.keys];\n\t\t} else {\n\t\t\tthis.channels ??= {};\n\t\t\tif (this.channels[name] === undefined) {\n\t\t\t\tthis.channels[name] = channel;\n\t\t\t} else {\n\t\t\t\tthis.channels[name]?.update(undefined, channel);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Rehydrates attribution information from its serialized form into the provided iterable of consecutive segments.\n\t */\n\tpublic static populateAttributionCollections(\n\t\tsegments: ISegment[],\n\t\tsummary: SerializedAttributionCollection,\n\t): void {\n\t\tconst { channels } = summary;\n\t\tassert(\n\t\t\t// Destructuring here would require renaming the variables, since seqs is declared below\n\t\t\t// eslint-disable-next-line unicorn/consistent-destructuring\n\t\t\tsummary.seqs.length === summary.posBreakpoints.length,\n\t\t\t0x445 /* Invalid attribution summary blob provided */,\n\t\t);\n\n\t\tconst extractOntoSegments = (\n\t\t\t{ seqs, posBreakpoints }: SequenceOffsets,\n\t\t\tassignToSegment: (collection: AttributionCollection, segment: ISegment) => void,\n\t\t): void => {\n\t\t\tif (seqs.length === 0) {\n\t\t\t\tassert(\n\t\t\t\t\tposBreakpoints.length === 0,\n\t\t\t\t\t0x9e1 /* seqs and posBreakpoints length should match */,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet curIndex = 0;\n\t\t\tlet cumulativeSegPos = 0;\n\n\t\t\tfor (const segment of segments) {\n\t\t\t\tconst attribution = new AttributionCollection(segment.cachedLength);\n\t\t\t\t// This function is defined here to allow for the creation of a new collection for each segment.\n\t\t\t\t// eslint-disable-next-line unicorn/consistent-function-scoping\n\t\t\t\tconst pushEntry = (offset: number, seq: AttributionKey | number | null): void => {\n\t\t\t\t\tattribution.offsets.push(offset);\n\t\t\t\t\tattribution.keys.push(\n\t\t\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\t\t\tseq === null ? null : typeof seq === \"object\" ? seq : { type: \"op\", seq },\n\t\t\t\t\t);\n\t\t\t\t};\n\t\t\t\tif (posBreakpoints[curIndex] > cumulativeSegPos) {\n\t\t\t\t\tcurIndex--;\n\t\t\t\t}\n\n\t\t\t\twhile (posBreakpoints[curIndex] < cumulativeSegPos + segment.cachedLength) {\n\t\t\t\t\tconst nextOffset = Math.max(posBreakpoints[curIndex] - cumulativeSegPos, 0);\n\t\t\t\t\tpushEntry(nextOffset, seqs[curIndex]);\n\t\t\t\t\tcurIndex++;\n\t\t\t\t}\n\n\t\t\t\tif (attribution.offsets.length === 0) {\n\t\t\t\t\tpushEntry(0, seqs[curIndex - 1]);\n\t\t\t\t}\n\n\t\t\t\tassignToSegment(attribution, segment);\n\t\t\t\tcumulativeSegPos += segment.cachedLength;\n\t\t\t}\n\t\t};\n\n\t\textractOntoSegments(summary, (collection, segment) => {\n\t\t\tsegment.attribution = collection;\n\t\t});\n\t\tif (channels) {\n\t\t\tfor (const [name, collectionSpec] of Object.entries(channels)) {\n\t\t\t\textractOntoSegments(collectionSpec, (collection, segment) => {\n\t\t\t\t\tif (segment.attribution !== undefined) {\n\t\t\t\t\t\t// Cast is valid as we just assigned this field above\n\t\t\t\t\t\t((segment.attribution as AttributionCollection).channels ??= {})[name] =\n\t\t\t\t\t\t\tcollection;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Condenses attribution information on consecutive segments into a `SerializedAttributionCollection`\n\t *\n\t * Note: this operates on segments rather than attribution collections directly so that it can handle cases\n\t * where only some segments have attribution defined.\n\t */\n\tpublic static serializeAttributionCollections(\n\t\tsegments: Iterable<{\n\t\t\tattribution?: IAttributionCollection<AttributionKey>;\n\t\t\tcachedLength: number;\n\t\t}>,\n\t): SerializedAttributionCollection {\n\t\tconst allCollectionSpecs: IAttributionCollectionSpec<AttributionKey>[] = [];\n\n\t\tconst allChannelNames = new Set<string>();\n\t\tfor (const segment of segments) {\n\t\t\tconst collection =\n\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\tsegment.attribution ?? new AttributionCollection(segment.cachedLength, null);\n\t\t\tconst spec = collection.getAll();\n\t\t\tallCollectionSpecs.push(spec);\n\t\t\tif (spec.channels) {\n\t\t\t\tfor (const name of Object.keys(spec.channels)) {\n\t\t\t\t\tallChannelNames.add(name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst extractSequenceOffsets = (\n\t\t\tgetSpecEntries: (\n\t\t\t\tspec: IAttributionCollectionSpec<AttributionKey>,\n\t\t\t) => Iterable<{ offset: number; key: AttributionKey | null }>,\n\t\t): SerializedAttributionCollection => {\n\t\t\tconst posBreakpoints: number[] = [];\n\t\t\tconst seqs: (number | AttributionKey | null)[] = [];\n\t\t\tlet mostRecentAttributionKey: AttributionKey | null | undefined;\n\t\t\tlet cumulativePos = 0;\n\n\t\t\tfor (const spec of allCollectionSpecs) {\n\t\t\t\tfor (const { offset, key } of getSpecEntries(spec)) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tkey?.type !== \"local\",\n\t\t\t\t\t\t0x5c1 /* local attribution keys should never be put in summaries */,\n\t\t\t\t\t);\n\t\t\t\t\tif (\n\t\t\t\t\t\tmostRecentAttributionKey === undefined ||\n\t\t\t\t\t\t!areEqualAttributionKeys(key, mostRecentAttributionKey)\n\t\t\t\t\t) {\n\t\t\t\t\t\tposBreakpoints.push(offset + cumulativePos);\n\t\t\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\t\t\tseqs.push(key ? (key.type === \"op\" ? key.seq : key) : null);\n\t\t\t\t\t}\n\t\t\t\t\tmostRecentAttributionKey = key;\n\t\t\t\t}\n\n\t\t\t\tcumulativePos += spec.length;\n\t\t\t}\n\n\t\t\treturn { seqs, posBreakpoints, length: cumulativePos };\n\t\t};\n\n\t\tconst blobContents = extractSequenceOffsets((spec) => spec.root);\n\t\tif (allChannelNames.size > 0) {\n\t\t\tconst channels: { [name: string]: SequenceOffsets } = {};\n\t\t\tfor (const name of allChannelNames) {\n\t\t\t\tconst { posBreakpoints, seqs } = extractSequenceOffsets(\n\t\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\t\t(spec) => spec.channels?.[name] ?? [{ offset: 0, key: null }],\n\t\t\t\t);\n\t\t\t\tchannels[name] = { posBreakpoints, seqs };\n\t\t\t}\n\t\t\tblobContents.channels = channels;\n\t\t}\n\n\t\treturn blobContents;\n\t}\n}\n"]}
1
+ {"version":3,"file":"attributionCollection.js","sourceRoot":"","sources":["../src/attributionCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAM9E,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAsItE,gDAAgD;AAChD,MAAM,UAAU,uBAAuB;AACtC,kDAAkD;AAClD,CAAoC;AACpC,kDAAkD;AAClD,CAAoC;IAEpC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACd,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACd,CAAC;IAED,gGAAgG;IAChG,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,IAAI,CAAC,CAAC,CAAC;YACX,OAAO,CAAC,CAAC,GAAG,KAAM,CAAsB,CAAC,GAAG,CAAC;QAC9C,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YACjB,OAAO,CAAC,CAAC,EAAE,KAAM,CAA4B,CAAC,EAAE,CAAC;QAClD,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACd,OAAO,IAAI,CAAC;QACb,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACT,eAAe,CAAC,CAAC,EAAE,+BAA+B,CAAC,CAAC;QACrD,CAAC;IACF,CAAC;AACF,CAAC;AAED,MAAM,OAAO,qBAAqB;IAMjC,IAAY,cAAc;QACzB,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,YACS,OAAe;IACvB,kDAAkD;IAClD,SAAiC;QAFzB,YAAO,GAAP,OAAO,CAAQ;QAVhB,YAAO,GAAa,EAAE,CAAC;QACvB,SAAI,GAA8B,EAAE,CAAC;QAa5C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;IACF,CAAC;IAED,IAAW,YAAY;QACtB,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAIM,WAAW,CAAC,MAAc,EAAE,OAAgB;QAClD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;YAC/C,OAAO,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC;QACD,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC3F,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,CAAC;IAWM,oBAAoB,CAC1B,WAAmB,EACnB,SAAkB,EAClB,OAAgB;QAEhB,IAAI,WAAW,GAAG,CAAC,IAAI,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACpD,MAAM,IAAI,UAAU,CAAC,0CAA0C,CAAC,CAAC;QAClE,CAAC;QACD,IACC,SAAS,KAAK,SAAS;YACvB,CAAC,SAAS,GAAG,CAAC,IAAI,SAAS,IAAI,IAAI,CAAC,OAAO,IAAI,WAAW,GAAG,SAAS,CAAC,EACtE,CAAC;YACF,MAAM,IAAI,UAAU,CAAC,wCAAwC,CAAC,CAAC;QAChE,CAAC;QAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;YAC/C,OAAO,aAAa,EAAE,oBAAoB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,MAAM,GAA8C,EAAE,CAAC;QAC7D,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACxC,IAAI,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,EAAE,CAAC;QACR,MAAM,YAAY,GAAG,SAAS,IAAI,MAAM,CAAC,gBAAgB,CAAC;QAC1D,OAAO,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3E,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACjC,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;gBAClC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC,CAAC;YACnE,CAAC;YACD,KAAK,EAAE,CAAC;QACT,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAEO,SAAS,CAAC,MAAc;QAC/B,8GAA8G;QAC9G,8GAA8G;QAC9G,wGAAwG;QACxG,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5D,CAAC,EAAE,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;IAEO,GAAG,CAAC,KAAa;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO,GAAG,IAAI,SAAS,CAAC;IACzB,CAAC;IAED,IAAW,MAAM;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;OAEG;IACI,OAAO,CAAC,GAAW;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,eAAe,GAAG,IAAI,qBAAqB,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;QACrE,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;YACjE,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,eAAe,CAAC,QAAQ,GAAG,EAAE,CAAC;YAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACrD,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACzD,CAAC;QACF,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACjC,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC;QACnB,OAAO,eAAe,CAAC;IACxB,CAAC;IAEM,MAAM,CAAC,KAA4B;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;gBAClD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,CAAC;QACF,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjE,IAAI,CAAC,QAAQ,KAAK,EAAE,CAAC;YACrB,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;gBACtD,MAAM,cAAc,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,IAAI,qBAAqB,CACvE,IAAI,CAAC,MAAM;gBACX,0GAA0G;gBAC1G,2CAA2C;gBAC3C,IAAI,CACJ,CAAC,CAAC;gBACH,cAAc,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACnC,CAAC;YACD,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACrD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;oBACzC,2CAA2C;oBAC3C,UAAU,CAAC,MAAM,CAAC,IAAI,qBAAqB,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;gBAClE,CAAC;YACF,CAAC;QACF,CAAC;QACD,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC;IAC9B,CAAC;IAEM,MAAM;QAEZ,MAAM,IAAI,GACT,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,CAAC;QACD,MAAM,MAAM,GAA+C;YAC1D,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,MAAM;SACnB,CAAC;QACF,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC;YACrB,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACrD,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;YACjD,CAAC;QACF,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,KAAK;QACX,MAAM,IAAI,GAAG,IAAI,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,YAAY,GAA0C,EAAE,CAAC;YAC/D,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACrD,YAAY,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC;YACxC,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC;QAC9B,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAEM,MAAM,CAAC,IAAwB,EAAE,OAA8B;QACrE,MAAM,CACL,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAC9B,KAAK,CAAC,gFAAgF,CACtF,CAAC;QACF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;YACpC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,QAAQ,KAAK,EAAE,CAAC;YACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;gBACvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACP,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACjD,CAAC;QACF,CAAC;IACF,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,8BAA8B,CAC3C,QAAoB,EACpB,OAAwC;QAExC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAC7B,MAAM;QACL,wFAAwF;QACxF,4DAA4D;QAC5D,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,MAAM,EACrD,KAAK,CAAC,+CAA+C,CACrD,CAAC;QAEF,MAAM,mBAAmB,GAAG,CAC3B,EAAE,IAAI,EAAE,cAAc,EAAmB,EACzC,eAA+E,EACxE,EAAE;YACT,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,CACL,cAAc,CAAC,MAAM,KAAK,CAAC,EAC3B,KAAK,CAAC,iDAAiD,CACvD,CAAC;gBACF,OAAO;YACR,CAAC;YACD,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,IAAI,gBAAgB,GAAG,CAAC,CAAC;YAEzB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAChC,MAAM,WAAW,GAAG,IAAI,qBAAqB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;gBACpE,gGAAgG;gBAChG,+DAA+D;gBAC/D,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,GAAmC,EAAQ,EAAE;oBAC/E,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBACjC,WAAW,CAAC,IAAI,CAAC,IAAI;oBACpB,2CAA2C;oBAC3C,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CACzE,CAAC;gBACH,CAAC,CAAC;gBACF,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,gBAAgB,EAAE,CAAC;oBACjD,QAAQ,EAAE,CAAC;gBACZ,CAAC;gBAED,OAAO,cAAc,CAAC,QAAQ,CAAC,GAAG,gBAAgB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;oBAC3E,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,gBAAgB,EAAE,CAAC,CAAC,CAAC;oBAC5E,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACtC,QAAQ,EAAE,CAAC;gBACZ,CAAC;gBAED,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACtC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;gBAClC,CAAC;gBAED,eAAe,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBACtC,gBAAgB,IAAI,OAAO,CAAC,YAAY,CAAC;YAC1C,CAAC;QACF,CAAC,CAAC;QAEF,mBAAmB,CAAC,OAAO,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE;YACpD,OAAO,CAAC,WAAW,GAAG,UAAU,CAAC;QAClC,CAAC,CAAC,CAAC;QACH,IAAI,QAAQ,EAAE,CAAC;YACd,KAAK,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC/D,mBAAmB,CAAC,cAAc,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE;oBAC3D,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;wBACvC,qDAAqD;wBACrD,CAAE,OAAO,CAAC,WAAqC,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC;4BACrE,UAAU,CAAC;oBACb,CAAC;gBACF,CAAC,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAC,+BAA+B,CAC5C,QAGE;QAEF,MAAM,kBAAkB,GAAiD,EAAE,CAAC;QAE5E,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;QAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAChC,MAAM,UAAU;YACf,2CAA2C;YAC3C,OAAO,CAAC,WAAW,IAAI,IAAI,qBAAqB,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;YAC9E,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;YACjC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC/C,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC3B,CAAC;YACF,CAAC;QACF,CAAC;QAED,MAAM,sBAAsB,GAAG,CAC9B,cAE6D,EAC3B,EAAE;YACpC,MAAM,cAAc,GAAa,EAAE,CAAC;YACpC,MAAM,IAAI,GAAuC,EAAE,CAAC;YACpD,IAAI,wBAA2D,CAAC;YAChE,IAAI,aAAa,GAAG,CAAC,CAAC;YAEtB,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;gBACvC,KAAK,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;oBACpD,MAAM,CACL,GAAG,EAAE,IAAI,KAAK,OAAO,EACrB,KAAK,CAAC,6DAA6D,CACnE,CAAC;oBACF,IACC,wBAAwB,KAAK,SAAS;wBACtC,CAAC,uBAAuB,CAAC,GAAG,EAAE,wBAAwB,CAAC,EACtD,CAAC;wBACF,cAAc,CAAC,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC;wBAC5C,2CAA2C;wBAC3C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBAC7D,CAAC;oBACD,wBAAwB,GAAG,GAAG,CAAC;gBAChC,CAAC;gBAED,aAAa,IAAI,IAAI,CAAC,MAAM,CAAC;YAC9B,CAAC;YAED,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;QACxD,CAAC,CAAC;QAEF,MAAM,YAAY,GAAG,sBAAsB,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,IAAI,eAAe,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAwC,EAAE,CAAC;YACzD,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;gBACpC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,sBAAsB;gBACtD,2CAA2C;gBAC3C,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAC7D,CAAC;gBACF,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;YAC3C,CAAC;YACD,YAAY,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAClC,CAAC;QAED,OAAO,YAAY,CAAC;IACrB,CAAC;CACD","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 {\n\tAttributionKey,\n\tDetachedAttributionKey,\n\tOpAttributionKey,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { UsageError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { ISegment } from \"./mergeTreeNodes.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport interface SequenceOffsets {\n\t/**\n\t * Parallel array with posBreakpoints which tracks the seq of insertion.\n\t *\n\t * @example\n\t *\n\t * If seqs is [45, 46] and posBreakpoints is [0, 3], the section of the string\n\t * between offsets 0 and 3 was inserted at seq 45 and the section of the string between\n\t * 3 and the length of the string was inserted at seq 46.\n\t *\n\t * @remarks We use null here rather than undefined as round-tripping through JSON converts\n\t * undefineds to null anyway\n\t */\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tseqs: (number | AttributionKey | null)[];\n\tposBreakpoints: number[];\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface SerializedAttributionCollection extends SequenceOffsets {\n\tchannels?: { [name: string]: SequenceOffsets };\n\t/* Total length; only necessary for validation */\n\tlength: number;\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface IAttributionCollectionSpec<T> {\n\t// eslint-disable-next-line @rushstack/no-new-null\n\troot: Iterable<{ offset: number; key: T | null }>;\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tchannels?: { [name: string]: Iterable<{ offset: number; key: T | null }> };\n\tlength: number;\n}\n\n/**\n * @legacy\n * @alpha\n * @sealed\n */\nexport interface IAttributionCollectionSerializer {\n\t/***/\n\tserializeAttributionCollections(\n\t\tsegments: Iterable<{\n\t\t\tattribution?: IAttributionCollection<AttributionKey>;\n\t\t\tcachedLength: number;\n\t\t}>,\n\t): SerializedAttributionCollection;\n\n\t/**\n\t * Populates attribution information on segments using the provided summary.\n\t */\n\tpopulateAttributionCollections(\n\t\tsegments: Iterable<ISegment>,\n\t\tsummary: SerializedAttributionCollection,\n\t): void;\n}\n\n/**\n * @legacy\n * @alpha\n */\nexport interface IAttributionCollection<T> {\n\t/**\n\t * Retrieves the attribution key associated with the provided offset.\n\t * @param channel - When specified, gets an attribution key associated with a particular channel.\n\t */\n\tgetAtOffset(offset: number, channel?: string): AttributionKey | undefined;\n\n\t/**\n\t * Retrieves all the [Offset, Attribution key] pairs for the provided offset range. Note:\n\t * The returned array is sorted by offset.\n\t * The first offset in response could be lower than the startOffset as the Attribution Key for the startOffset\n\t * could start at a lower offset than the startOffset in case where Attribution key offset boundaries don't\n\t * align exactly with startOffset.\n\t * Example: If the Attribution Offsets in the segment is [0, 10, 20, 30, 40] and request is for (startOffset: 5, endOffset: 25),\n\t * then result would be [(offset: 0, key: key1), (offset:10, key: key2), (offset:20, key: key3)].\n\t * @param channel - When specified, gets attribution keys associated with a particular channel.\n\t * @returns - undefined if the provided channel is not found or list of attribution keys along with\n\t * the corresponding offset start boundary.\n\t */\n\tgetKeysInOffsetRange(\n\t\tstartOffset: number,\n\t\tendOffset?: number,\n\t\tchannel?: string,\n\t): { offset: number; key: AttributionKey }[] | undefined;\n\n\t/**\n\t * Total length of all attribution keys in this collection.\n\t */\n\treadonly length: number;\n\n\treadonly channelNames: Iterable<string>;\n\n\t/**\n\t * Retrieve all key/offset pairs stored on this segment. Entries should be ordered by offset, such that\n\t * the `i`th result's attribution key applies to offsets in the open range between the `i`th offset and the\n\t * `i+1`th offset.\n\t * The last entry's key applies to the open interval from the last entry's offset to this collection's length.\n\t */\n\tgetAll(): IAttributionCollectionSpec<T>;\n\n\t/***/\n\tsplitAt(pos: number): IAttributionCollection<T>;\n\n\t/***/\n\tappend(other: IAttributionCollection<T>): void;\n\n\t/***/\n\tclone(): IAttributionCollection<T>;\n\n\t/**\n\t * Updates this collection with new attribution data.\n\t * @param name - Name of the channel that requires an update. Undefined signifies the root channel.\n\t * Updates apply only to the individual channel (i.e. if an attribution policy needs to update the root\n\t * channel and 4 other channels, it should call `.update` 5 times).\n\t * @param channel - Updated collection for that channel.\n\t */\n\tupdate(name: string | undefined, channel: IAttributionCollection<T>): void;\n}\n\n// note: treats null and undefined as equivalent\nexport function areEqualAttributionKeys(\n\t// eslint-disable-next-line @rushstack/no-new-null\n\ta: AttributionKey | null | undefined,\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tb: AttributionKey | null | undefined,\n): boolean {\n\tif (!a && !b) {\n\t\treturn true;\n\t}\n\n\tif (!a || !b) {\n\t\treturn false;\n\t}\n\n\tif (a.type !== b.type) {\n\t\treturn false;\n\t}\n\n\t// Note: TS can't narrow the type of b inside this switch statement, hence the need for casting.\n\tswitch (a.type) {\n\t\tcase \"op\": {\n\t\t\treturn a.seq === (b as OpAttributionKey).seq;\n\t\t}\n\t\tcase \"detached\": {\n\t\t\treturn a.id === (b as DetachedAttributionKey).id;\n\t\t}\n\t\tcase \"local\": {\n\t\t\treturn true;\n\t\t}\n\t\tdefault: {\n\t\t\tunreachableCase(a, \"Unhandled AttributionKey type\");\n\t\t}\n\t}\n}\n\nexport class AttributionCollection implements IAttributionCollection<AttributionKey> {\n\tprivate offsets: number[] = [];\n\tprivate keys: (AttributionKey | null)[] = [];\n\n\tprivate channels?: { [name: string]: AttributionCollection };\n\n\tprivate get channelEntries(): [string, AttributionCollection][] {\n\t\treturn Object.entries(this.channels ?? {});\n\t}\n\n\tpublic constructor(\n\t\tprivate _length: number,\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tbaseEntry?: AttributionKey | null,\n\t) {\n\t\tif (baseEntry !== undefined) {\n\t\t\tthis.offsets.push(0);\n\t\t\tthis.keys.push(baseEntry);\n\t\t}\n\t}\n\n\tpublic get channelNames(): string[] {\n\t\treturn Object.keys(this.channels ?? {});\n\t}\n\n\tpublic getAtOffset(offset: number): AttributionKey;\n\tpublic getAtOffset(offset: number, channel: string): AttributionKey | undefined;\n\tpublic getAtOffset(offset: number, channel?: string): AttributionKey | undefined {\n\t\tif (channel !== undefined) {\n\t\t\tconst subCollection = this.channels?.[channel];\n\t\t\treturn subCollection?.getAtOffset(offset);\n\t\t}\n\t\tassert(offset >= 0 && offset < this._length, 0x443 /* Requested offset should be valid */);\n\t\treturn this.get(this.findIndex(offset));\n\t}\n\n\tpublic getKeysInOffsetRange(\n\t\tstartOffset: number,\n\t\tendOffset?: number,\n\t): { offset: number; key: AttributionKey }[];\n\tpublic getKeysInOffsetRange(\n\t\tstartOffset: number,\n\t\tendOffset?: number,\n\t\tchannel?: string,\n\t): { offset: number; key: AttributionKey }[] | undefined;\n\tpublic getKeysInOffsetRange(\n\t\tstartOffset: number,\n\t\tendOffset?: number,\n\t\tchannel?: string,\n\t): { offset: number; key: AttributionKey }[] | undefined {\n\t\tif (startOffset < 0 || startOffset >= this._length) {\n\t\t\tthrow new UsageError(\"startOffset should be valid and in range\");\n\t\t}\n\t\tif (\n\t\t\tendOffset !== undefined &&\n\t\t\t(endOffset < 0 || endOffset >= this._length || startOffset > endOffset)\n\t\t) {\n\t\t\tthrow new UsageError(\"endOffset should be valid and in range\");\n\t\t}\n\n\t\tif (channel !== undefined) {\n\t\t\tconst subCollection = this.channels?.[channel];\n\t\t\treturn subCollection?.getKeysInOffsetRange(startOffset, endOffset);\n\t\t}\n\t\tconst result: { offset: number; key: AttributionKey }[] = [];\n\t\tlet index = this.findIndex(startOffset);\n\t\tlet attributionKey = this.get(index);\n\t\tif (attributionKey !== undefined) {\n\t\t\tresult.push({ offset: this.offsets[index], key: attributionKey });\n\t\t}\n\t\tindex++;\n\t\tconst endOffsetVal = endOffset ?? Number.MAX_SAFE_INTEGER;\n\t\twhile (index < this.offsets.length && endOffsetVal >= this.offsets[index]) {\n\t\t\tattributionKey = this.get(index);\n\t\t\tif (attributionKey !== undefined) {\n\t\t\t\tresult.push({ offset: this.offsets[index], key: attributionKey });\n\t\t\t}\n\t\t\tindex++;\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate findIndex(offset: number): number {\n\t\t// Note: maximum length here is 256 for text segments. Perf testing shows that linear scan beats binary search\n\t\t// for attribution collections with under ~64 entries, and even at maximum size (which would require a maximum\n\t\t// length segment with every offset having different attribution), getAtOffset is on the order of 100ns.\n\t\tlet i = 0;\n\t\twhile (i < this.offsets.length && offset > this.offsets[i]) {\n\t\t\ti++;\n\t\t}\n\t\treturn this.offsets[i] === offset ? i : i - 1;\n\t}\n\n\tprivate get(index: number): AttributionKey | undefined {\n\t\tconst key = this.keys[index];\n\t\treturn key ?? undefined;\n\t}\n\n\tpublic get length(): number {\n\t\treturn this._length;\n\t}\n\n\t/**\n\t * Splits this attribution collection into two with entries for [0, pos) and [pos, length).\n\t */\n\tpublic splitAt(pos: number): AttributionCollection {\n\t\tconst splitIndex = this.findIndex(pos);\n\t\tconst splitCollection = new AttributionCollection(this.length - pos);\n\t\tfor (let i = splitIndex; i < this.keys.length; i++) {\n\t\t\tsplitCollection.offsets.push(Math.max(this.offsets[i] - pos, 0));\n\t\t\tsplitCollection.keys.push(this.keys[i]);\n\t\t}\n\n\t\tif (this.channels) {\n\t\t\tsplitCollection.channels = {};\n\t\t\tfor (const [key, collection] of this.channelEntries) {\n\t\t\t\tsplitCollection.channels[key] = collection.splitAt(pos);\n\t\t\t}\n\t\t}\n\n\t\tconst spliceIndex = this.offsets[splitIndex] === pos ? splitIndex : splitIndex + 1;\n\t\tthis.keys.splice(spliceIndex);\n\t\tthis.offsets.splice(spliceIndex);\n\t\tthis._length = pos;\n\t\treturn splitCollection;\n\t}\n\n\tpublic append(other: AttributionCollection): void {\n\t\tconst lastEntry = this.keys[this.keys.length - 1];\n\t\tfor (let i = 0; i < other.keys.length; i++) {\n\t\t\tif (i !== 0 || !areEqualAttributionKeys(lastEntry, other.keys[i])) {\n\t\t\t\tthis.offsets.push(other.offsets[i] + this.length);\n\t\t\t\tthis.keys.push(other.keys[i]);\n\t\t\t}\n\t\t}\n\n\t\tif (other.channels !== undefined || this.channels !== undefined) {\n\t\t\tthis.channels ??= {};\n\t\t\tfor (const [key, collection] of other.channelEntries) {\n\t\t\t\tconst thisCollection = (this.channels[key] ??= new AttributionCollection(\n\t\t\t\t\tthis.length,\n\t\t\t\t\t// Null is needed as null and undefined have different meanings in the context of attribution collections.\n\t\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\t\tnull,\n\t\t\t\t));\n\t\t\t\tthisCollection.append(collection);\n\t\t\t}\n\t\t\tfor (const [key, collection] of this.channelEntries) {\n\t\t\t\tif (other.channels?.[key] === undefined) {\n\t\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\t\tcollection.append(new AttributionCollection(other.length, null));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis._length += other.length;\n\t}\n\n\tpublic getAll(): IAttributionCollectionSpec<AttributionKey> {\n\t\ttype ExtractGeneric<T> = T extends Iterable<infer Q> ? Q : unknown;\n\t\tconst root: ExtractGeneric<IAttributionCollectionSpec<AttributionKey>[\"root\"]>[] =\n\t\t\tArray.from({ length: this.keys.length });\n\t\tfor (let i = 0; i < this.keys.length; i++) {\n\t\t\troot[i] = { offset: this.offsets[i], key: this.keys[i] };\n\t\t}\n\t\tconst result: IAttributionCollectionSpec<AttributionKey> = {\n\t\t\troot,\n\t\t\tlength: this.length,\n\t\t};\n\t\tif (this.channels !== undefined) {\n\t\t\tresult.channels = {};\n\t\t\tfor (const [key, collection] of this.channelEntries) {\n\t\t\t\tresult.channels[key] = collection.getAll().root;\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tpublic clone(): AttributionCollection {\n\t\tconst copy = new AttributionCollection(this.length);\n\t\tcopy.keys = [...this.keys];\n\t\tcopy.offsets = [...this.offsets];\n\t\tif (this.channels !== undefined) {\n\t\t\tconst channelsCopy: Record<string, AttributionCollection> = {};\n\t\t\tfor (const [key, collection] of this.channelEntries) {\n\t\t\t\tchannelsCopy[key] = collection.clone();\n\t\t\t}\n\t\t\tcopy.channels = channelsCopy;\n\t\t}\n\t\treturn copy;\n\t}\n\n\tpublic update(name: string | undefined, channel: AttributionCollection): void {\n\t\tassert(\n\t\t\tchannel.length === this.length,\n\t\t\t0x5c0 /* AttributionCollection channel update should have consistent segment length */,\n\t\t);\n\t\tif (name === undefined) {\n\t\t\tthis.offsets = [...channel.offsets];\n\t\t\tthis.keys = [...channel.keys];\n\t\t} else {\n\t\t\tthis.channels ??= {};\n\t\t\tif (this.channels[name] === undefined) {\n\t\t\t\tthis.channels[name] = channel;\n\t\t\t} else {\n\t\t\t\tthis.channels[name]?.update(undefined, channel);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Rehydrates attribution information from its serialized form into the provided iterable of consecutive segments.\n\t */\n\tpublic static populateAttributionCollections(\n\t\tsegments: ISegment[],\n\t\tsummary: SerializedAttributionCollection,\n\t): void {\n\t\tconst { channels } = summary;\n\t\tassert(\n\t\t\t// Destructuring here would require renaming the variables, since seqs is declared below\n\t\t\t// eslint-disable-next-line unicorn/consistent-destructuring\n\t\t\tsummary.seqs.length === summary.posBreakpoints.length,\n\t\t\t0x445 /* Invalid attribution summary blob provided */,\n\t\t);\n\n\t\tconst extractOntoSegments = (\n\t\t\t{ seqs, posBreakpoints }: SequenceOffsets,\n\t\t\tassignToSegment: (collection: AttributionCollection, segment: ISegment) => void,\n\t\t): void => {\n\t\t\tif (seqs.length === 0) {\n\t\t\t\tassert(\n\t\t\t\t\tposBreakpoints.length === 0,\n\t\t\t\t\t0x9e1 /* seqs and posBreakpoints length should match */,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet curIndex = 0;\n\t\t\tlet cumulativeSegPos = 0;\n\n\t\t\tfor (const segment of segments) {\n\t\t\t\tconst attribution = new AttributionCollection(segment.cachedLength);\n\t\t\t\t// This function is defined here to allow for the creation of a new collection for each segment.\n\t\t\t\t// eslint-disable-next-line unicorn/consistent-function-scoping\n\t\t\t\tconst pushEntry = (offset: number, seq: AttributionKey | number | null): void => {\n\t\t\t\t\tattribution.offsets.push(offset);\n\t\t\t\t\tattribution.keys.push(\n\t\t\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\t\t\tseq === null ? null : typeof seq === \"object\" ? seq : { type: \"op\", seq },\n\t\t\t\t\t);\n\t\t\t\t};\n\t\t\t\tif (posBreakpoints[curIndex] > cumulativeSegPos) {\n\t\t\t\t\tcurIndex--;\n\t\t\t\t}\n\n\t\t\t\twhile (posBreakpoints[curIndex] < cumulativeSegPos + segment.cachedLength) {\n\t\t\t\t\tconst nextOffset = Math.max(posBreakpoints[curIndex] - cumulativeSegPos, 0);\n\t\t\t\t\tpushEntry(nextOffset, seqs[curIndex]);\n\t\t\t\t\tcurIndex++;\n\t\t\t\t}\n\n\t\t\t\tif (attribution.offsets.length === 0) {\n\t\t\t\t\tpushEntry(0, seqs[curIndex - 1]);\n\t\t\t\t}\n\n\t\t\t\tassignToSegment(attribution, segment);\n\t\t\t\tcumulativeSegPos += segment.cachedLength;\n\t\t\t}\n\t\t};\n\n\t\textractOntoSegments(summary, (collection, segment) => {\n\t\t\tsegment.attribution = collection;\n\t\t});\n\t\tif (channels) {\n\t\t\tfor (const [name, collectionSpec] of Object.entries(channels)) {\n\t\t\t\textractOntoSegments(collectionSpec, (collection, segment) => {\n\t\t\t\t\tif (segment.attribution !== undefined) {\n\t\t\t\t\t\t// Cast is valid as we just assigned this field above\n\t\t\t\t\t\t((segment.attribution as AttributionCollection).channels ??= {})[name] =\n\t\t\t\t\t\t\tcollection;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Condenses attribution information on consecutive segments into a `SerializedAttributionCollection`\n\t *\n\t * Note: this operates on segments rather than attribution collections directly so that it can handle cases\n\t * where only some segments have attribution defined.\n\t */\n\tpublic static serializeAttributionCollections(\n\t\tsegments: Iterable<{\n\t\t\tattribution?: IAttributionCollection<AttributionKey>;\n\t\t\tcachedLength: number;\n\t\t}>,\n\t): SerializedAttributionCollection {\n\t\tconst allCollectionSpecs: IAttributionCollectionSpec<AttributionKey>[] = [];\n\n\t\tconst allChannelNames = new Set<string>();\n\t\tfor (const segment of segments) {\n\t\t\tconst collection =\n\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\tsegment.attribution ?? new AttributionCollection(segment.cachedLength, null);\n\t\t\tconst spec = collection.getAll();\n\t\t\tallCollectionSpecs.push(spec);\n\t\t\tif (spec.channels) {\n\t\t\t\tfor (const name of Object.keys(spec.channels)) {\n\t\t\t\t\tallChannelNames.add(name);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst extractSequenceOffsets = (\n\t\t\tgetSpecEntries: (\n\t\t\t\tspec: IAttributionCollectionSpec<AttributionKey>,\n\t\t\t) => Iterable<{ offset: number; key: AttributionKey | null }>,\n\t\t): SerializedAttributionCollection => {\n\t\t\tconst posBreakpoints: number[] = [];\n\t\t\tconst seqs: (number | AttributionKey | null)[] = [];\n\t\t\tlet mostRecentAttributionKey: AttributionKey | null | undefined;\n\t\t\tlet cumulativePos = 0;\n\n\t\t\tfor (const spec of allCollectionSpecs) {\n\t\t\t\tfor (const { offset, key } of getSpecEntries(spec)) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tkey?.type !== \"local\",\n\t\t\t\t\t\t0x5c1 /* local attribution keys should never be put in summaries */,\n\t\t\t\t\t);\n\t\t\t\t\tif (\n\t\t\t\t\t\tmostRecentAttributionKey === undefined ||\n\t\t\t\t\t\t!areEqualAttributionKeys(key, mostRecentAttributionKey)\n\t\t\t\t\t) {\n\t\t\t\t\t\tposBreakpoints.push(offset + cumulativePos);\n\t\t\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\t\t\tseqs.push(key ? (key.type === \"op\" ? key.seq : key) : null);\n\t\t\t\t\t}\n\t\t\t\t\tmostRecentAttributionKey = key;\n\t\t\t\t}\n\n\t\t\t\tcumulativePos += spec.length;\n\t\t\t}\n\n\t\t\treturn { seqs, posBreakpoints, length: cumulativePos };\n\t\t};\n\n\t\tconst blobContents = extractSequenceOffsets((spec) => spec.root);\n\t\tif (allChannelNames.size > 0) {\n\t\t\tconst channels: { [name: string]: SequenceOffsets } = {};\n\t\t\tfor (const name of allChannelNames) {\n\t\t\t\tconst { posBreakpoints, seqs } = extractSequenceOffsets(\n\t\t\t\t\t// eslint-disable-next-line unicorn/no-null\n\t\t\t\t\t(spec) => spec.channels?.[name] ?? [{ offset: 0, key: null }],\n\t\t\t\t);\n\t\t\t\tchannels[name] = { posBreakpoints, seqs };\n\t\t\t}\n\t\t\tblobContents.channels = channels;\n\t\t}\n\n\t\treturn blobContents;\n\t}\n}\n"]}
@@ -46,7 +46,7 @@ function _validateReferenceType(refType) {
46
46
  */
47
47
  class LocalReference {
48
48
  get trackingCollection() {
49
- return (this._trackingCollection ?? (this._trackingCollection = new TrackingGroupCollection(this)));
49
+ return (this._trackingCollection ??= new TrackingGroupCollection(this));
50
50
  }
51
51
  constructor(refType = ReferenceType.Simple, properties, slidingPreference = SlidingPreference.FORWARD, canSlideToEndpoint) {
52
52
  this.refType = refType;
@@ -157,7 +157,7 @@ export class LocalReferenceCollection {
157
157
  validateRefCount?.(seg2.localRefs);
158
158
  }
159
159
  static setOrGet(segment) {
160
- return (segment.localRefs ?? (segment.localRefs = new LocalReferenceCollection(segment)));
160
+ return (segment.localRefs ??= new LocalReferenceCollection(segment));
161
161
  }
162
162
  constructor(
163
163
  /**
@@ -353,11 +353,10 @@ export class LocalReferenceCollection {
353
353
  * @remarks This method should only be called by mergeTree.
354
354
  */
355
355
  addBeforeTombstones(...refs) {
356
- var _a;
357
356
  const beforeRefs = this.refsByOffset[0]?.before ?? new DoublyLinkedList();
358
357
  if (this.refsByOffset[0]?.before === undefined) {
359
- const refsAtOffset = ((_a = this.refsByOffset)[0] ?? (_a[0] = { before: beforeRefs }));
360
- refsAtOffset.before ?? (refsAtOffset.before = beforeRefs);
358
+ const refsAtOffset = (this.refsByOffset[0] ??= { before: beforeRefs });
359
+ refsAtOffset.before ??= beforeRefs;
361
360
  }
362
361
  let precedingRef;
363
362
  for (const iterable of refs) {
@@ -388,12 +387,11 @@ export class LocalReferenceCollection {
388
387
  * @remarks This method should only be called by mergeTree.
389
388
  */
390
389
  addAfterTombstones(...refs) {
391
- var _a;
392
390
  const lastOffset = this.segment.cachedLength - 1;
393
391
  const afterRefs = this.refsByOffset[lastOffset]?.after ?? new DoublyLinkedList();
394
392
  if (this.refsByOffset[lastOffset]?.after === undefined) {
395
- const refsAtOffset = ((_a = this.refsByOffset)[lastOffset] ?? (_a[lastOffset] = { after: afterRefs }));
396
- refsAtOffset.after ?? (refsAtOffset.after = afterRefs);
393
+ const refsAtOffset = (this.refsByOffset[lastOffset] ??= { after: afterRefs });
394
+ refsAtOffset.after ??= afterRefs;
397
395
  }
398
396
  for (const iterable of refs) {
399
397
  for (const lref of iterable) {