@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.
- package/.eslintrc.cjs +0 -1
- package/CHANGELOG.md +8 -0
- package/README.md +1 -0
- package/dist/attributionCollection.js +5 -7
- package/dist/attributionCollection.js.map +1 -1
- package/dist/localReference.js +6 -8
- package/dist/localReference.js.map +1 -1
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +69 -34
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +15 -4
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +1 -1
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/partialLengths.d.ts +114 -144
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +431 -525
- package/dist/partialLengths.js.map +1 -1
- package/dist/perspective.d.ts +10 -1
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +10 -1
- package/dist/perspective.js.map +1 -1
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +2 -3
- package/dist/properties.js.map +1 -1
- package/dist/revertibles.js +3 -3
- package/dist/revertibles.js.map +1 -1
- package/dist/segmentInfos.d.ts +3 -0
- package/dist/segmentInfos.d.ts.map +1 -1
- package/dist/segmentInfos.js.map +1 -1
- package/dist/segmentPropertiesManager.js +3 -3
- package/dist/segmentPropertiesManager.js.map +1 -1
- package/dist/snapshotLoader.js +2 -2
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts +5 -3
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js +33 -41
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/sortedSet.d.ts +20 -3
- package/dist/sortedSet.d.ts.map +1 -1
- package/dist/sortedSet.js +23 -14
- package/dist/sortedSet.js.map +1 -1
- package/dist/test/Snapshot.perf.spec.js +1 -1
- package/dist/test/Snapshot.perf.spec.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +20 -0
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.js +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/dist/test/client.attributionFarm.spec.js +1 -1
- package/dist/test/client.attributionFarm.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +48 -0
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.obliterateFarm.spec.d.ts +12 -0
- package/dist/test/client.obliterateFarm.spec.d.ts.map +1 -0
- package/dist/test/client.obliterateFarm.spec.js +89 -0
- package/dist/test/client.obliterateFarm.spec.js.map +1 -0
- package/dist/test/client.reconnectFarm.spec.js +1 -1
- package/dist/test/client.reconnectFarm.spec.js.map +1 -1
- package/dist/test/client.searchForMarker.spec.js +2 -2
- package/dist/test/client.searchForMarker.spec.js.map +1 -1
- package/dist/test/mergeTreeOperationRunner.d.ts +7 -2
- package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/dist/test/mergeTreeOperationRunner.js +31 -14
- package/dist/test/mergeTreeOperationRunner.js.map +1 -1
- package/dist/test/obliterate.concurrent.spec.js +45 -1
- package/dist/test/obliterate.concurrent.spec.js.map +1 -1
- package/dist/test/obliterate.rangeExpansion.spec.js +81 -5
- package/dist/test/obliterate.rangeExpansion.spec.js.map +1 -1
- package/dist/test/obliterate.spec.js +3 -3
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/obliterateOperations.d.ts +15 -0
- package/dist/test/obliterateOperations.d.ts.map +1 -0
- package/dist/test/obliterateOperations.js +132 -0
- package/dist/test/obliterateOperations.js.map +1 -0
- package/dist/test/partialSyncHelper.d.ts +42 -0
- package/dist/test/partialSyncHelper.d.ts.map +1 -0
- package/dist/test/partialSyncHelper.js +96 -0
- package/dist/test/partialSyncHelper.js.map +1 -0
- package/dist/test/revertibles.spec.js +3 -3
- package/dist/test/revertibles.spec.js.map +1 -1
- package/dist/test/sortedSegmentSet.spec.js +21 -0
- package/dist/test/sortedSegmentSet.spec.js.map +1 -1
- package/dist/test/testClient.d.ts +1 -1
- package/dist/test/testClient.d.ts.map +1 -1
- package/dist/test/testClient.js +1 -0
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/testUtils.js +2 -2
- package/dist/test/testUtils.js.map +1 -1
- package/lib/attributionCollection.js +5 -7
- package/lib/attributionCollection.js.map +1 -1
- package/lib/localReference.js +6 -8
- package/lib/localReference.js.map +1 -1
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +69 -34
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +15 -4
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +1 -1
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/partialLengths.d.ts +114 -144
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +432 -525
- package/lib/partialLengths.js.map +1 -1
- package/lib/perspective.d.ts +10 -1
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +10 -1
- package/lib/perspective.js.map +1 -1
- package/lib/properties.d.ts.map +1 -1
- package/lib/properties.js +2 -3
- package/lib/properties.js.map +1 -1
- package/lib/revertibles.js +3 -3
- package/lib/revertibles.js.map +1 -1
- package/lib/segmentInfos.d.ts +3 -0
- package/lib/segmentInfos.d.ts.map +1 -1
- package/lib/segmentInfos.js.map +1 -1
- package/lib/segmentPropertiesManager.js +3 -3
- package/lib/segmentPropertiesManager.js.map +1 -1
- package/lib/snapshotLoader.js +2 -2
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts +5 -3
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js +33 -41
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/sortedSet.d.ts +20 -3
- package/lib/sortedSet.d.ts.map +1 -1
- package/lib/sortedSet.js +23 -14
- package/lib/sortedSet.js.map +1 -1
- package/lib/test/Snapshot.perf.spec.js +1 -1
- package/lib/test/Snapshot.perf.spec.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +20 -0
- package/lib/test/client.applyMsg.spec.js.map +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.js +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/lib/test/client.attributionFarm.spec.js +1 -1
- package/lib/test/client.attributionFarm.spec.js.map +1 -1
- package/lib/test/client.localReference.spec.js +48 -0
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.obliterateFarm.spec.d.ts +12 -0
- package/lib/test/client.obliterateFarm.spec.d.ts.map +1 -0
- package/lib/test/client.obliterateFarm.spec.js +88 -0
- package/lib/test/client.obliterateFarm.spec.js.map +1 -0
- package/lib/test/client.reconnectFarm.spec.js +1 -1
- package/lib/test/client.reconnectFarm.spec.js.map +1 -1
- package/lib/test/client.searchForMarker.spec.js +2 -2
- package/lib/test/client.searchForMarker.spec.js.map +1 -1
- package/lib/test/mergeTreeOperationRunner.d.ts +7 -2
- package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/lib/test/mergeTreeOperationRunner.js +31 -14
- package/lib/test/mergeTreeOperationRunner.js.map +1 -1
- package/lib/test/obliterate.concurrent.spec.js +45 -1
- package/lib/test/obliterate.concurrent.spec.js.map +1 -1
- package/lib/test/obliterate.rangeExpansion.spec.js +81 -5
- package/lib/test/obliterate.rangeExpansion.spec.js.map +1 -1
- package/lib/test/obliterate.spec.js +3 -3
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/obliterateOperations.d.ts +15 -0
- package/lib/test/obliterateOperations.d.ts.map +1 -0
- package/lib/test/obliterateOperations.js +123 -0
- package/lib/test/obliterateOperations.js.map +1 -0
- package/lib/test/partialSyncHelper.d.ts +42 -0
- package/lib/test/partialSyncHelper.d.ts.map +1 -0
- package/lib/test/partialSyncHelper.js +92 -0
- package/lib/test/partialSyncHelper.js.map +1 -0
- package/lib/test/revertibles.spec.js +3 -3
- package/lib/test/revertibles.spec.js.map +1 -1
- package/lib/test/sortedSegmentSet.spec.js +21 -0
- package/lib/test/sortedSegmentSet.spec.js.map +1 -1
- package/lib/test/testClient.d.ts +1 -1
- package/lib/test/testClient.d.ts.map +1 -1
- package/lib/test/testClient.js +1 -0
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/testUtils.js +2 -2
- package/lib/test/testUtils.js.map +1 -1
- package/package.json +21 -79
- package/src/mergeTree.ts +80 -28
- package/src/mergeTreeNodes.ts +15 -4
- package/src/partialLengths.ts +559 -776
- package/src/perspective.ts +10 -1
- package/src/properties.ts +2 -3
- package/src/segmentInfos.ts +3 -0
- package/src/snapshotLoader.ts +1 -1
- package/src/sortedSegmentSet.ts +41 -50
- package/src/sortedSet.ts +32 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partialLengths.js","sourceRoot":"","sources":["../src/partialLengths.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport { Property, RedBlackTree } from \"./collections/index.js\";\nimport { UnassignedSequenceNumber } from \"./constants.js\";\nimport { MergeTree } from \"./mergeTree.js\";\nimport {\n\tCollaborationWindow,\n\tIMergeNode,\n\tISegmentPrivate,\n\tcompareNumbers,\n\tseqLTE,\n\ttype MergeBlock,\n} from \"./mergeTreeNodes.js\";\nimport {\n\ttoRemovalInfo,\n\ttoMoveInfo,\n\tIRemovalInfo,\n\tIMoveInfo,\n\tassertInserted,\n\tisRemoved,\n} from \"./segmentInfos.js\";\nimport { SortedSet } from \"./sortedSet.js\";\n\nclass PartialSequenceLengthsSet extends SortedSet<PartialSequenceLength, number> {\n\tprotected getKey(item: PartialSequenceLength): number {\n\t\treturn item.seq;\n\t}\n\n\tpublic addOrUpdate(\n\t\tnewItem: PartialSequenceLength,\n\t\tupdate?: (existingItem: PartialSequenceLength, newItem: PartialSequenceLength) => void,\n\t): void {\n\t\tconst prev = this.latestLeq(newItem.seq);\n\n\t\tif (prev?.seq !== newItem.seq) {\n\t\t\t// new element, update len\n\t\t\tnewItem.len = (prev?.len ?? 0) + newItem.seglen;\n\t\t}\n\n\t\t// update the len of all following elements\n\t\tfor (let i = this.keySortedItems.length - 1; i >= 0; i--) {\n\t\t\tconst element = this.keySortedItems[i];\n\t\t\tif (!element || element.seq <= newItem.seq) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\telement.len += newItem.seglen;\n\t\t}\n\n\t\tsuper.addOrUpdate(newItem, (currentPartial, partialLength) => {\n\t\t\tcurrentPartial.seglen += partialLength.seglen;\n\n\t\t\tif (partialLength.remoteObliteratedLen) {\n\t\t\t\tcurrentPartial.remoteObliteratedLen ??= 0;\n\t\t\t\tcurrentPartial.remoteObliteratedLen += partialLength.remoteObliteratedLen;\n\t\t\t}\n\n\t\t\tcurrentPartial.len += partialLength.seglen;\n\t\t\tcombineOverlapClients(currentPartial, partialLength);\n\t\t});\n\t}\n\n\t/**\n\t * Returns the partial length whose sequence number is the greatest sequence\n\t * number that is less than or equal to key.\n\t * @param key - sequence number\n\t */\n\tlatestLeq(key: number): PartialSequenceLength | undefined {\n\t\treturn this.keySortedItems[this.latestLeqIndex(key)];\n\t}\n\n\t/**\n\t * Returns the partial length whose sequence number is the lowest sequence\n\t * number that is greater than or equal to key.\n\t * @param key - sequence number\n\t */\n\tfirstGte(key: number): PartialSequenceLength | undefined {\n\t\tconst { index } = this.findItemPosition({ seq: key, len: 0, seglen: 0 });\n\t\treturn this.keySortedItems[index];\n\t}\n\n\tprivate latestLeqIndex(key: number): number {\n\t\tconst { exists, index } = this.findItemPosition({ seq: key, len: 0, seglen: 0 });\n\t\treturn exists ? index : index - 1;\n\t}\n\n\tcopyDown(minSeq: number): number {\n\t\tconst mindex = this.latestLeqIndex(minSeq);\n\t\tlet minLength = 0;\n\t\tif (mindex >= 0) {\n\t\t\tminLength = this.keySortedItems[mindex].len;\n\t\t\tconst seqCount = this.size;\n\t\t\tif (mindex <= seqCount - 1) {\n\t\t\t\t// Still some entries remaining\n\t\t\t\tconst remainingCount = seqCount - mindex - 1;\n\t\t\t\t// Copy down\n\t\t\t\tfor (let i = 0; i < remainingCount; i++) {\n\t\t\t\t\tthis.keySortedItems[i] = this.keySortedItems[i + mindex + 1];\n\t\t\t\t\tthis.keySortedItems[i].len -= minLength;\n\t\t\t\t}\n\t\t\t\tthis.keySortedItems.length = remainingCount;\n\t\t\t}\n\t\t}\n\t\treturn minLength;\n\t}\n}\n\ninterface IOverlapClient {\n\tclientId: number;\n\tseglen: number;\n}\n\n/**\n * Tracks length information for a part of a MergeTree (block) at a given time (seq).\n * These objects are associated with internal nodes (i.e. blocks).\n */\nexport interface PartialSequenceLength {\n\t/**\n\t * Sequence number\n\t */\n\tseq: number;\n\t/**\n\t * The length of the associated block.\n\t */\n\tlen: number;\n\t/**\n\t * The delta between the current length of the associated block and its length at the previous seq number.\n\t */\n\tseglen: number;\n\t/**\n\t * clientId for the client that submitted the op with sequence number `seq`.\n\t */\n\tclientId?: number;\n\t/**\n\t * If this partial length obliterated remote segments, this is the length of\n\t * those segments\n\t */\n\tremoteObliteratedLen?: number;\n\t/**\n\t * This field maps each client to the size of the intersection between segments deleted at this seq\n\t * and segments concurrently deleted by that client.\n\t *\n\t * For example, this PartialSequenceLength:\n\t * ```typescript\n\t * {\n\t * seq: 5,\n\t * len: 100,\n\t * seglen: -10,\n\t * clientId: 0,\n\t * overlapRemoveClients: <RedBlack tree with key-values expressed by>{\n\t * 1: { clientId: 1, seglen: -5 },\n\t * 3: { clientId: 3, seglen: -10 }\n\t * }\n\t * }\n\t * ```\n\t *\n\t * corresponds to an op submitted by client 0 which:\n\t * - reduces the length of this block by 10 (it may have deleted a single segment of length 10,\n\t * several segments totalling length 10, or even delete and add content for a total reduction of 10 length)\n\t * - was concurrent to one or more ops submitted by client 1 that also removed some of the same segments,\n\t * whose length totalled 5\n\t * - was concurrent to one or more ops submitted by client 3 that removed some of the same segments,\n\t * whose length totalled 10\n\t */\n\toverlapRemoveClients?: RedBlackTree<number, IOverlapClient>;\n\t/**\n\t * This field is the same as `overlapRemoveClients`, except that it tracks\n\t * overlapping obliterates rather than removes.\n\t */\n\toverlapObliterateClients?: RedBlackTree<number, IOverlapClient>;\n}\n\ninterface UnsequencedPartialLengthInfo {\n\t/**\n\t * Contains entries for all local operations.\n\t * The \"seq\" field of each entry actually corresponds to the delta at that localSeq on the local client.\n\t */\n\tpartialLengths: PartialSequenceLengthsSet;\n\n\t/**\n\t * Only contains entries for segments (or aggregates thereof) which were concurrently deleted\n\t * by another client. Ordered by `seq` of the removing client.\n\t *\n\t * The \"length\" field of these entries is not populated. This is because pre-computing the lengths\n\t * of segments doesn't help given the usage pattern.\n\t *\n\t * These entries need both `seq` and `localSeq`, because a given segment remove is double-counted iff\n\t * the refSeq exceeds the seq of the remote remove AND the localSeq exceeds the localSeq of the local remove.\n\t */\n\toverlappingRemoves: LocalPartialSequenceLength[];\n\n\t/**\n\t * Cached keyed on refSeq which stores length information for the total overlap of removed segments at\n\t * that refSeq.\n\t * This information is derivable from the entries of `overlappingRemoves`.\n\t *\n\t * Like the `partialLengths` field, `seq` on each entry is actually the local seq.\n\t * See `computeOverlappingLocalRemoves` for more information.\n\t */\n\tcachedOverlappingByRefSeq: Map<number, PartialSequenceLengthsSet>;\n}\n\ninterface LocalPartialSequenceLength extends PartialSequenceLength {\n\t/**\n\t * Local sequence number\n\t */\n\tlocalSeq: number;\n}\n\nexport interface PartialSequenceLengthsOptions {\n\tverifier?: (partialLengths: PartialSequenceLengths) => void;\n\tverifyExpected?: (\n\t\tmergeTree: MergeTree,\n\t\tnode: MergeBlock,\n\t\trefSeq: number,\n\t\tclientId: number,\n\t\tlocalSeq?: number,\n\t) => void;\n\tzamboni: boolean;\n}\n\n/**\n * Keeps track of partial sums of segment lengths for all sequence numbers in the current collaboration window.\n * Only used during active collaboration.\n *\n * This class is associated with an internal node (block) of a MergeTree. It efficiently answers queries of the form\n * \"What is the length of `block` from the perspective of some particular seq and clientId?\".\n *\n * It also supports incremental updating of state for newly-sequenced ops that don't affect the structure of the\n * MergeTree.\n *\n * To answer these queries, it pre-builds several lists which track the length of the block at a per-sequence-number\n * level. These lists are:\n *\n * 1. (`partialLengths`): Stores the total length of the block.\n * 2. (`clientSeqNumbers[clientId]`): Stores only the total lengths of segments submitted by `clientId`. [see footnote]\n *\n * The reason both lists are necessary is that resolving the length of the block from the perspective of\n * (clientId, refSeq) requires including both of the following types of segments:\n * 1. Segments sequenced before `refSeq`\n * 2. Segments submitted by `clientId`\n *\n * This is possible with the above bookkeeping, using:\n *\n * (length of the block at the minimum sequence number)\n * + (partialLengths total length at refSeq)\n * + (clientSeqNumbers total length at most recent op)\n * - (clientSeqNumbers total length at refSeq)\n *\n * where the subtraction avoids double-counting segments submitted by clientId sequenced within the collab window.\n *\n * To enable reconnect, if constructed with `computeLocalPartials === true` it also supports querying for the length of\n * the block from the perspective of the local client at a particular `refSeq` and `localSeq`. This computation is\n * similar to the above:\n *\n * (length of the block at the minimum sequence number)\n * + (partialLengths total length at refSeq)\n * + (unsequenced edits' total length submitted before localSeq)\n * - (overlapping remove of the unsequenced edits' total length at refSeq)\n *\n * This algorithm scales roughly linearly with number of editing clients and the size of the collab window.\n * (certain unlikely sequences of operations may introduce log factors on those variables)\n *\n * Note: there is some slight complication with clientSeqNumbers resulting from the possibility of different clients\n * concurrently removing the same segment. See the field's documentation for more details.\n */\nexport class PartialSequenceLengths {\n\tpublic static options: PartialSequenceLengthsOptions = {\n\t\tzamboni: true,\n\t};\n\n\t/**\n\t * Combine the partial lengths of block's children\n\t * @param block - an interior node. If `recur` is false, it is assumed that each interior node child of this block\n\t * has its partials up to date.\n\t * @param collabWindow - segment window of the segment tree containing `block`.\n\t * @param recur - whether to recursively compute partial lengths for internal children of `block`.\n\t * This incurs more work, but gives correct bookkeeping in the case that a descendant in the merge tree has been\n\t * modified without bubbling up the resulting partial length change to this block's partials.\n\t * @param computeLocalPartials - whether to compute partial length information about local unsequenced ops.\n\t * This enables querying for the length of the block at a given localSeq, but incurs extra work.\n\t * Local partial information doesn't support `update`.\n\t */\n\tpublic static combine(\n\t\tblock: MergeBlock,\n\n\t\tcollabWindow: CollaborationWindow,\n\t\trecur = false,\n\t\tcomputeLocalPartials = false,\n\t): PartialSequenceLengths {\n\t\tconst leafPartialLengths = PartialSequenceLengths.fromLeaves(\n\t\t\tblock,\n\t\t\tcollabWindow,\n\t\t\tcomputeLocalPartials,\n\t\t);\n\n\t\tlet hasInternalChild = false;\n\t\tconst childPartials: PartialSequenceLengths[] = [];\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tif (!child.isLeaf()) {\n\t\t\t\thasInternalChild = true;\n\t\t\t\tif (recur) {\n\t\t\t\t\tchild.partialLengths = PartialSequenceLengths.combine(\n\t\t\t\t\t\tchild,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tcomputeLocalPartials,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tchildPartials.push(child.partialLengths!);\n\t\t\t}\n\t\t}\n\n\t\t// If there are no internal children, the PartialSequenceLengths returns from `fromLeaves` is exactly correct.\n\t\t// Otherwise, we must additively combine all of the children partial lengths to get this block's totals.\n\t\tconst combinedPartialLengths = hasInternalChild\n\t\t\t? new PartialSequenceLengths(collabWindow.minSeq, computeLocalPartials)\n\t\t\t: leafPartialLengths;\n\t\tif (hasInternalChild) {\n\t\t\tif (leafPartialLengths.partialLengths.size > 0) {\n\t\t\t\t// Some children were leaves; add combined partials from these segments\n\t\t\t\tchildPartials.push(leafPartialLengths);\n\t\t\t}\n\n\t\t\tconst childPartialsLen = childPartials.length;\n\n\t\t\tconst childPartialLengths: PartialSequenceLength[][] = [];\n\t\t\tconst childUnsequencedPartialLengths: PartialSequenceLength[][] = [];\n\t\t\tconst childOverlapRemoves: LocalPartialSequenceLength[][] = [];\n\t\t\tfor (let i = 0; i < childPartialsLen; i++) {\n\t\t\t\tconst { segmentCount, minLength, partialLengths, unsequencedRecords } =\n\t\t\t\t\tchildPartials[i];\n\t\t\t\tcombinedPartialLengths.segmentCount += segmentCount;\n\t\t\t\tcombinedPartialLengths.minLength += minLength;\n\t\t\t\tchildPartialLengths.push(partialLengths.items as PartialSequenceLength[]);\n\t\t\t\tif (unsequencedRecords) {\n\t\t\t\t\tchildUnsequencedPartialLengths.push(\n\t\t\t\t\t\tunsequencedRecords.partialLengths.items as PartialSequenceLength[],\n\t\t\t\t\t);\n\t\t\t\t\tchildOverlapRemoves.push(unsequencedRecords.overlappingRemoves);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmergePartialLengths(childPartialLengths, combinedPartialLengths.partialLengths);\n\n\t\t\tif (computeLocalPartials) {\n\t\t\t\tcombinedPartialLengths.unsequencedRecords = {\n\t\t\t\t\tpartialLengths: mergePartialLengths(childUnsequencedPartialLengths),\n\t\t\t\t\toverlappingRemoves: [...mergeSortedListsBySeq(childOverlapRemoves)],\n\t\t\t\t\tcachedOverlappingByRefSeq: new Map(),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tfor (const partial of combinedPartialLengths.partialLengths.items) {\n\t\t\t\tcombinedPartialLengths.addClientSeqNumberFromPartial(partial);\n\t\t\t}\n\t\t}\n\t\t// TODO: incremental zamboni during build\n\t\tif (PartialSequenceLengths.options.zamboni) {\n\t\t\tcombinedPartialLengths.zamboni(collabWindow);\n\t\t}\n\n\t\tPartialSequenceLengths.options.verifier?.(combinedPartialLengths);\n\t\treturn combinedPartialLengths;\n\t}\n\n\t/**\n\t * Creates and returns a PartialSequenceLengths structure that tracks the lengths of only the\n\t * leaf children of the provided MergeBlock.\n\t */\n\tprivate static fromLeaves(\n\t\tblock: MergeBlock,\n\n\t\tcollabWindow: CollaborationWindow,\n\t\tcomputeLocalPartials: boolean,\n\t): PartialSequenceLengths {\n\t\tconst combinedPartialLengths = new PartialSequenceLengths(\n\t\t\tcollabWindow.minSeq,\n\t\t\tcomputeLocalPartials,\n\t\t);\n\t\tcombinedPartialLengths.segmentCount = block.childCount;\n\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tif (child.isLeaf()) {\n\t\t\t\t// Leaf segment\n\t\t\t\tconst segment = child;\n\t\t\t\tif (segment.seq !== undefined && seqLTE(segment.seq, collabWindow.minSeq)) {\n\t\t\t\t\tcombinedPartialLengths.minLength += segment.cachedLength;\n\t\t\t\t} else {\n\t\t\t\t\tPartialSequenceLengths.insertSegment(combinedPartialLengths, segment);\n\t\t\t\t}\n\t\t\t\tconst removalInfo = toRemovalInfo(segment);\n\t\t\t\tconst moveInfo = toMoveInfo(segment);\n\t\t\t\tif (\n\t\t\t\t\t(removalInfo?.removedSeq !== undefined &&\n\t\t\t\t\t\tseqLTE(removalInfo.removedSeq, collabWindow.minSeq)) ||\n\t\t\t\t\t(moveInfo?.movedSeq !== undefined && seqLTE(moveInfo.movedSeq, collabWindow.minSeq))\n\t\t\t\t) {\n\t\t\t\t\tcombinedPartialLengths.minLength -= segment.cachedLength;\n\t\t\t\t} else if (removalInfo !== undefined || moveInfo !== undefined) {\n\t\t\t\t\tPartialSequenceLengths.insertSegment(\n\t\t\t\t\t\tcombinedPartialLengths,\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tremovalInfo,\n\t\t\t\t\t\tmoveInfo,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Post-process correctly-ordered partials computing sums and creating\n\t\t// lists for each present client id\n\t\tconst seqPartials = combinedPartialLengths.partialLengths;\n\n\t\tlet prevLen = 0;\n\t\tfor (const partial of seqPartials.items) {\n\t\t\tpartial.len = prevLen + partial.seglen;\n\t\t\tprevLen = partial.len;\n\t\t\tcombinedPartialLengths.addClientSeqNumberFromPartial(partial);\n\t\t}\n\t\tprevLen = 0;\n\n\t\tif (combinedPartialLengths.unsequencedRecords !== undefined) {\n\t\t\tconst localPartials = combinedPartialLengths.unsequencedRecords.partialLengths;\n\t\t\tfor (const partial of localPartials.items) {\n\t\t\t\tpartial.len = prevLen + partial.seglen;\n\t\t\t\tprevLen = partial.len;\n\t\t\t}\n\t\t}\n\n\t\tPartialSequenceLengths.options.verifier?.(combinedPartialLengths);\n\t\treturn combinedPartialLengths;\n\t}\n\n\tprivate static getOverlapClients(\n\t\toverlapClientIds: number[],\n\t\tseglen: number,\n\t): RedBlackTree<number, IOverlapClient> {\n\t\tconst bst = new RedBlackTree<number, IOverlapClient>(compareNumbers);\n\t\tfor (const clientId of overlapClientIds) {\n\t\t\tbst.put(clientId, { clientId, seglen });\n\t\t}\n\t\treturn bst;\n\t}\n\n\tprivate static accumulateRemoveClientOverlap(\n\t\tpartialLength: PartialSequenceLength,\n\t\toverlapRemoveClientIds: number[],\n\t\tseglen: number,\n\t): void {\n\t\tif (partialLength.overlapRemoveClients) {\n\t\t\tfor (const clientId of overlapRemoveClientIds) {\n\t\t\t\tconst overlapClientNode = partialLength.overlapRemoveClients.get(clientId);\n\t\t\t\tif (overlapClientNode) {\n\t\t\t\t\toverlapClientNode.data.seglen += seglen;\n\t\t\t\t} else {\n\t\t\t\t\tpartialLength.overlapRemoveClients.put(clientId, { clientId, seglen });\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tpartialLength.overlapRemoveClients = PartialSequenceLengths.getOverlapClients(\n\t\t\t\toverlapRemoveClientIds,\n\t\t\t\tseglen,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate static accumulateMoveClientOverlap(\n\t\tpartialLength: PartialSequenceLength,\n\t\toverlapMoveClientIds: number[],\n\t\tseglen: number,\n\t): void {\n\t\tif (partialLength.overlapObliterateClients) {\n\t\t\tfor (const clientId of overlapMoveClientIds) {\n\t\t\t\tconst overlapClientNode = partialLength.overlapObliterateClients.get(clientId);\n\t\t\t\tif (overlapClientNode) {\n\t\t\t\t\toverlapClientNode.data.seglen += seglen;\n\t\t\t\t} else {\n\t\t\t\t\tpartialLength.overlapObliterateClients.put(clientId, { clientId, seglen });\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tpartialLength.overlapObliterateClients = PartialSequenceLengths.getOverlapClients(\n\t\t\t\toverlapMoveClientIds,\n\t\t\t\tseglen,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Coalesce overlapping move lengths for a partial length entry that already\n\t * exists\n\t *\n\t * @param segmentLen - Length of segment with overlapping moves\n\t * @param segment - Segment with overlapping moves\n\t * @param firstGte - Existing partial length entry\n\t * @param clientIds - Ids of clients that concurrently obliterated this segment\n\t */\n\tstatic accumulateMoveOverlapForExisting(\n\t\tsegmentLen: number,\n\t\tsegment: ISegmentPrivate,\n\t\tfirstGte: PartialSequenceLength,\n\t\tclientIds: number[],\n\t): void {\n\t\tassertInserted(segment);\n\t\tconst nonInsertingClientIds = clientIds.filter((id) => id !== segment.clientId);\n\n\t\tPartialSequenceLengths.accumulateMoveClientOverlap(\n\t\t\tfirstGte,\n\t\t\tnonInsertingClientIds,\n\t\t\tsegmentLen,\n\t\t);\n\n\t\t// if this segment was obliterated by the client that inserted it,\n\t\t// and if it overlaps with the obliterate of another client, we need to\n\t\t// take into account whether it was obliterated on insert by the other\n\t\t// client\n\t\tif (clientIds.length !== nonInsertingClientIds.length) {\n\t\t\tPartialSequenceLengths.accumulateMoveClientOverlap(\n\t\t\t\tfirstGte,\n\t\t\t\t[segment.clientId],\n\t\t\t\ttoMoveInfo(segment)?.wasMovedOnInsert ? -segment.cachedLength : segmentLen,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Tracks which clients have made concurrent obliterates.\n\t *\n\t * @param obliterateOverlapLen - Length of segment with overlap\n\t * @param clientIds - Ids of clients that have concurrently obliterated this\n\t * segment\n\t */\n\tprivate static getMoveOverlapForExisting(\n\t\tsegment: ISegmentPrivate,\n\t\tobliterateOverlapLen: number,\n\t\tclientIds: number[],\n\t): RedBlackTree<number, IOverlapClient> {\n\t\tassertInserted(segment);\n\t\tconst nonInsertingClientIds = clientIds.filter((id) => id !== segment.clientId);\n\t\tconst overlapObliterateClients = PartialSequenceLengths.getOverlapClients(\n\t\t\tnonInsertingClientIds,\n\t\t\tobliterateOverlapLen,\n\t\t);\n\n\t\tif (clientIds.length !== nonInsertingClientIds.length) {\n\t\t\toverlapObliterateClients.put(segment.clientId, {\n\t\t\t\tclientId: segment.clientId,\n\t\t\t\tseglen: toMoveInfo(segment)?.wasMovedOnInsert\n\t\t\t\t\t? -segment.cachedLength\n\t\t\t\t\t: obliterateOverlapLen,\n\t\t\t});\n\t\t}\n\n\t\treturn overlapObliterateClients;\n\t}\n\n\tprivate static updatePartialsAfterInsertion(\n\t\tsegment: ISegmentPrivate,\n\t\tsegmentLen: number,\n\t\tremoteObliteratedLen: number | undefined,\n\t\tobliterateOverlapLen: number = segmentLen,\n\t\tpartials: PartialSequenceLengthsSet,\n\t\tseq: number,\n\t\tclientId: number,\n\t\tremoveClientOverlap: number[] | undefined,\n\t\tmoveClientOverlap: number[] | undefined,\n\t): void {\n\t\tconst firstGte = partials.firstGte(seq);\n\n\t\tlet partialLengthEntry: PartialSequenceLength;\n\t\tif (firstGte?.seq === seq) {\n\t\t\tpartialLengthEntry = firstGte;\n\t\t\t// Existing entry at this seq--this occurs for ops that insert/delete\n\t\t\t// more than one segment.\n\t\t\tpartialLengthEntry.seglen += segmentLen;\n\t\t\tif (remoteObliteratedLen) {\n\t\t\t\tpartialLengthEntry.remoteObliteratedLen ??= 0;\n\t\t\t\tpartialLengthEntry.remoteObliteratedLen += remoteObliteratedLen;\n\t\t\t}\n\t\t\tif (removeClientOverlap) {\n\t\t\t\tPartialSequenceLengths.accumulateRemoveClientOverlap(\n\t\t\t\t\tfirstGte,\n\t\t\t\t\tremoveClientOverlap,\n\t\t\t\t\tobliterateOverlapLen,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (moveClientOverlap) {\n\t\t\t\tPartialSequenceLengths.accumulateMoveOverlapForExisting(\n\t\t\t\t\tobliterateOverlapLen,\n\t\t\t\t\tsegment,\n\t\t\t\t\tfirstGte,\n\t\t\t\t\tmoveClientOverlap,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tconst overlapObliterateClients = moveClientOverlap\n\t\t\t\t? PartialSequenceLengths.getMoveOverlapForExisting(\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tobliterateOverlapLen,\n\t\t\t\t\t\tmoveClientOverlap,\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\n\t\t\tpartialLengthEntry = {\n\t\t\t\tseq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: segmentLen,\n\t\t\t\tremoteObliteratedLen,\n\t\t\t\toverlapRemoveClients: removeClientOverlap\n\t\t\t\t\t? PartialSequenceLengths.getOverlapClients(removeClientOverlap, obliterateOverlapLen)\n\t\t\t\t\t: undefined,\n\t\t\t\toverlapObliterateClients,\n\t\t\t};\n\n\t\t\tpartials.addOrUpdate(partialLengthEntry);\n\t\t}\n\t}\n\n\t/**\n\t * Inserts length information about the insertion of `segment` into\n\t * `combinedPartialLengths.partialLengths`.\n\t *\n\t * Does not update the clientSeqNumbers field to account for this segment.\n\t *\n\t * If `removalInfo` or `moveInfo` are defined, this operation updates the\n\t * bookkeeping to account for the (re)moval of this segment at the (re)movedSeq\n\t * instead.\n\t *\n\t * When the insertion or (re)moval of the segment is un-acked and\n\t * `combinedPartialLengths` is meant to compute such records, this does the\n\t * analogous addition to the bookkeeping for the local segment in\n\t * `combinedPartialLengths.unsequencedRecords`.\n\t */\n\tprivate static insertSegment(\n\t\tcombinedPartialLengths: PartialSequenceLengths,\n\t\tsegment: ISegmentPrivate,\n\t\tremovalInfo?: IRemovalInfo,\n\t\tmoveInfo?: IMoveInfo,\n\t): void {\n\t\tassertInserted(segment);\n\n\t\tconst removalIsLocal =\n\t\t\t!!removalInfo && removalInfo.removedSeq === UnassignedSequenceNumber;\n\t\tconst moveIsLocal = !!moveInfo && moveInfo.movedSeq === UnassignedSequenceNumber;\n\t\tconst isLocal =\n\t\t\tsegment.seq === UnassignedSequenceNumber ||\n\t\t\t(!!removalInfo && removalIsLocal && (!moveInfo || moveIsLocal)) ||\n\t\t\t(!!moveInfo && moveIsLocal && (!removalInfo || removalIsLocal));\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tlet seqOrLocalSeq = isLocal ? segment.localSeq! : segment.seq;\n\t\tlet segmentLen = segment.cachedLength;\n\t\tlet clientId = segment.clientId;\n\t\tlet removeClientOverlap: number[] | undefined;\n\t\tlet moveClientOverlap: number[] | undefined;\n\t\tlet remoteObliteratedLen: number | undefined;\n\n\t\t// it's not possible to have an overlapping obliterate and remove that are both local\n\t\tassert(\n\t\t\t(!moveIsLocal && !removalIsLocal) || moveIsLocal !== removalIsLocal,\n\t\t\t0x870 /* overlapping local obliterate and remove */,\n\t\t);\n\n\t\tconst removeHappenedFirst =\n\t\t\tremovalInfo &&\n\t\t\t(!moveInfo ||\n\t\t\t\tmoveIsLocal ||\n\t\t\t\t(!removalIsLocal && moveInfo.movedSeq > removalInfo.removedSeq));\n\n\t\tif (removeHappenedFirst) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tseqOrLocalSeq = removalIsLocal ? removalInfo.localRemovedSeq! : removalInfo.removedSeq;\n\t\t\tsegmentLen = -segmentLen;\n\t\t\t// The client who performed the remove is always stored\n\t\t\t// in the first position of removalInfo.\n\t\t\tclientId = removalInfo.removedClientIds[0];\n\t\t\tconst hasOverlap = removalInfo.removedClientIds.length > 1;\n\t\t\tremoveClientOverlap = hasOverlap ? removalInfo.removedClientIds : undefined;\n\t\t} else if (moveInfo) {\n\t\t\t// The client who performed the move is always stored\n\t\t\t// in the first position of moveInfo.\n\t\t\tclientId = moveInfo.movedClientIds[0];\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tseqOrLocalSeq = moveIsLocal ? moveInfo.localMovedSeq! : moveInfo.movedSeq;\n\n\t\t\tif (moveInfo.wasMovedOnInsert) {\n\t\t\t\tassert(\n\t\t\t\t\tmoveInfo.movedSeq !== -1,\n\t\t\t\t\t0x871 /* wasMovedOnInsert should only be set on acked obliterates */,\n\t\t\t\t);\n\t\t\t\tsegmentLen = 0;\n\t\t\t} else {\n\t\t\t\tsegmentLen = -segmentLen;\n\t\t\t}\n\n\t\t\tconst hasOverlap = moveInfo.movedClientIds.length > 1;\n\t\t\tmoveClientOverlap = hasOverlap ? moveInfo.movedClientIds : undefined;\n\t\t} // BUG BUG: something fishy here around how/when move info is passed or not\n\t\t// this condition only hits if it is not passed, so we can't rely on the passed move info\n\t\t// and need to inspect the segment directly. maybe related to AB#15630.\n\t\telse if (toMoveInfo(segment)?.wasMovedOnInsert) {\n\t\t\t// if this segment was obliterated on insert, its length is only\n\t\t\t// visible to the client that inserted it\n\t\t\tsegmentLen = 0;\n\t\t\tremoteObliteratedLen = segment.cachedLength;\n\t\t}\n\n\t\tconst partials = isLocal\n\t\t\t? combinedPartialLengths.unsequencedRecords?.partialLengths\n\t\t\t: combinedPartialLengths.partialLengths;\n\t\tif (partials === undefined) {\n\t\t\t// Local partial but its computation isn't required\n\t\t\treturn;\n\t\t}\n\n\t\t// overlapping move and remove, remove happened first\n\t\tif (moveInfo && removalInfo && removeHappenedFirst && !moveIsLocal) {\n\t\t\t// The client who performed the remove is always stored\n\t\t\t// in the first position of removalInfo.\n\t\t\tconst moveClientId = moveInfo.movedClientIds[0];\n\t\t\tconst hasOverlap = moveInfo.movedClientIds.length > 1;\n\n\t\t\tPartialSequenceLengths.updatePartialsAfterInsertion(\n\t\t\t\tsegment,\n\t\t\t\t0,\n\t\t\t\t-segment.cachedLength,\n\t\t\t\tsegmentLen,\n\t\t\t\tpartials,\n\t\t\t\tmoveInfo.movedSeq,\n\t\t\t\tmoveClientId,\n\t\t\t\tundefined,\n\t\t\t\thasOverlap ? moveInfo.movedClientIds : undefined,\n\t\t\t);\n\t\t}\n\n\t\tif (removalInfo && !removeHappenedFirst && !removalIsLocal) {\n\t\t\tconst removeSeqOrLocalSeq = removalIsLocal\n\t\t\t\t? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tremovalInfo.localRemovedSeq!\n\t\t\t\t: removalInfo.removedSeq;\n\t\t\t// The client who performed the remove is always stored\n\t\t\t// in the first position of removalInfo.\n\t\t\tconst removeClientId = removalInfo.removedClientIds[0];\n\t\t\tconst hasOverlap = removalInfo.removedClientIds.length > 1;\n\n\t\t\tPartialSequenceLengths.updatePartialsAfterInsertion(\n\t\t\t\tsegment,\n\t\t\t\t0,\n\t\t\t\t-segment.cachedLength,\n\t\t\t\tsegmentLen,\n\t\t\t\tpartials,\n\t\t\t\tremoveSeqOrLocalSeq,\n\t\t\t\tremoveClientId,\n\t\t\t\thasOverlap ? removalInfo.removedClientIds : undefined,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t}\n\n\t\tPartialSequenceLengths.updatePartialsAfterInsertion(\n\t\t\tsegment,\n\t\t\tsegmentLen,\n\t\t\tremoteObliteratedLen,\n\t\t\tundefined,\n\t\t\tpartials,\n\t\t\tseqOrLocalSeq,\n\t\t\tclientId,\n\t\t\tremoveClientOverlap,\n\t\t\tmoveClientOverlap,\n\t\t);\n\n\t\t// todo: the below block needs to be changed to handle obliterate, which\n\t\t// doesn't have great support for reconnect at the moment. see ADO #3714\n\t\tconst { unsequencedRecords } = combinedPartialLengths;\n\t\tif (\n\t\t\tunsequencedRecords &&\n\t\t\tremoveClientOverlap &&\n\t\t\tisRemoved(segment) &&\n\t\t\tsegment.localRemovedSeq !== undefined\n\t\t) {\n\t\t\tconst localSeq = segment.localRemovedSeq;\n\t\t\tconst localPartialLengthEntry: LocalPartialSequenceLength = {\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tlocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: segmentLen,\n\t\t\t};\n\t\t\tlet localIndexFirstGTE = 0;\n\t\t\tfor (\n\t\t\t\t;\n\t\t\t\tlocalIndexFirstGTE < unsequencedRecords.overlappingRemoves.length;\n\t\t\t\tlocalIndexFirstGTE++\n\t\t\t) {\n\t\t\t\tif (unsequencedRecords.overlappingRemoves[localIndexFirstGTE].seq >= seqOrLocalSeq) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinsertIntoList(\n\t\t\t\tunsequencedRecords.overlappingRemoves,\n\t\t\t\tlocalIndexFirstGTE,\n\t\t\t\tlocalPartialLengthEntry,\n\t\t\t);\n\n\t\t\tconst tweakedLocalPartialEntry = {\n\t\t\t\t...localPartialLengthEntry,\n\t\t\t\tseq: localSeq,\n\t\t\t};\n\n\t\t\tunsequencedRecords.partialLengths.addOrUpdate(tweakedLocalPartialEntry);\n\t\t}\n\t}\n\n\tprivate static addSeq(\n\t\tpartialLengths: PartialSequenceLengthsSet,\n\t\tseq: number,\n\t\tseqSeglen: number,\n\t\tremoteObliteratedLen?: number,\n\t\tclientId?: number,\n\t): void {\n\t\tlet seqPartialLen: PartialSequenceLength | undefined;\n\t\tlet penultPartialLen: PartialSequenceLength | undefined;\n\t\tlet pLen = partialLengths.latestLeq(seq);\n\t\tif (pLen) {\n\t\t\tif (pLen.seq === seq) {\n\t\t\t\tseqPartialLen = pLen;\n\t\t\t\tpLen = partialLengths.latestLeq(seq - 1);\n\t\t\t\tif (pLen) {\n\t\t\t\t\tpenultPartialLen = pLen;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpenultPartialLen = pLen;\n\t\t\t}\n\t\t}\n\t\tconst len = penultPartialLen === undefined ? seqSeglen : penultPartialLen.len + seqSeglen;\n\t\tif (seqPartialLen === undefined) {\n\t\t\tseqPartialLen = {\n\t\t\t\tclientId,\n\t\t\t\tlen,\n\t\t\t\tseglen: seqSeglen,\n\t\t\t\tseq,\n\t\t\t\tremoteObliteratedLen,\n\t\t\t};\n\t\t\tpartialLengths.addOrUpdate(seqPartialLen);\n\t\t} else {\n\t\t\tseqPartialLen.remoteObliteratedLen = remoteObliteratedLen;\n\t\t\tseqPartialLen.seglen = seqSeglen;\n\t\t\tseqPartialLen.len = len;\n\t\t\t// Assert client id matches\n\t\t}\n\t}\n\n\t/**\n\t * Length of the block this PartialSequenceLength corresponds to when viewed at `minSeq`.\n\t */\n\tprivate minLength = 0;\n\n\t/**\n\t * Total number of segments in the subtree rooted at the block this PartialSequenceLength corresponds to.\n\t */\n\tprivate segmentCount = 0;\n\n\t/**\n\t * List of PartialSequenceLength objects--ordered by increasing seq--giving length information about\n\t * the block associated with this PartialSequenceLengths object.\n\t *\n\t * `partialLengths[i].len` contains the length of this block considering only sequenced segments with\n\t * `sequenceNumber <= partialLengths[i].seq`.\n\t */\n\tprivate readonly partialLengths: PartialSequenceLengthsSet = new PartialSequenceLengthsSet();\n\n\t/**\n\t * clientSeqNumbers[clientId] is a list of partial lengths for sequenced ops which either:\n\t * - were submitted by `clientId`.\n\t * - deleted a range containing segments that were concurrently deleted by `clientId`\n\t *\n\t * The second case is referred to as the \"overlapping delete\" case. It is necessary to avoid double-counting\n\t * the removal of those segments in queries including clientId.\n\t */\n\tprivate readonly clientSeqNumbers: PartialSequenceLengthsSet[] = [];\n\n\t/**\n\t * Contains information required to answer queries for the length of this segment from the perspective of\n\t * the local client but not including all local segments (i.e., `localSeq !== collabWindow.localSeq`).\n\t * This field is only computed if requested in the constructor (i.e. `computeLocalPartials === true`).\n\t */\n\tprivate unsequencedRecords: UnsequencedPartialLengthInfo | undefined;\n\n\tconstructor(\n\t\t/**\n\t\t * The minimumSequenceNumber as defined by the collab window used in the last call to `update`,\n\t\t * or if no such calls have been made, the one used on construction.\n\t\t */\n\t\tpublic minSeq: number,\n\t\tcomputeLocalPartials: boolean,\n\t) {\n\t\tif (computeLocalPartials) {\n\t\t\tthis.unsequencedRecords = {\n\t\t\t\tpartialLengths: new PartialSequenceLengthsSet(),\n\t\t\t\toverlappingRemoves: [],\n\t\t\t\tcachedOverlappingByRefSeq: new Map(),\n\t\t\t};\n\t\t}\n\t}\n\n\t// Assume: seq is latest sequence number; no structural change to sub-tree, but a segment\n\t// with sequence number seq has been added within the sub-tree (and `update` has been called\n\t// on all descendant PartialSequenceLengths)\n\t// TODO: assert client id matches\n\tpublic update(\n\t\tnode: MergeBlock,\n\t\tseq: number,\n\t\tclientId: number,\n\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\tlet seqSeglen = 0;\n\t\tlet remoteObliteratedLen = 0;\n\t\tlet segCount = 0;\n\t\t// Compute length for seq across children\n\t\tfor (let i = 0; i < node.childCount; i++) {\n\t\t\tconst child = node.children[i];\n\t\t\tif (child.isLeaf()) {\n\t\t\t\tconst segment = child;\n\t\t\t\tconst removalInfo = toRemovalInfo(segment);\n\t\t\t\tconst moveInfo = toMoveInfo(segment);\n\n\t\t\t\tconst removalIsLocal =\n\t\t\t\t\t!!removalInfo && removalInfo.removedSeq === UnassignedSequenceNumber;\n\t\t\t\tconst moveIsLocal = !!moveInfo && moveInfo.movedSeq === UnassignedSequenceNumber;\n\n\t\t\t\tconst removeHappenedFirst =\n\t\t\t\t\tremovalInfo &&\n\t\t\t\t\t(!moveInfo ||\n\t\t\t\t\t\tmoveIsLocal ||\n\t\t\t\t\t\t(!removalIsLocal && moveInfo.movedSeq > removalInfo.removedSeq));\n\n\t\t\t\tif (seq === segment.seq) {\n\t\t\t\t\t// if this segment was moved on insert, its length should\n\t\t\t\t\t// only be visible to the inserting client\n\t\t\t\t\tif (\n\t\t\t\t\t\tsegment.seq !== undefined &&\n\t\t\t\t\t\tmoveInfo &&\n\t\t\t\t\t\tmoveInfo.movedSeq < segment.seq &&\n\t\t\t\t\t\tmoveInfo.wasMovedOnInsert\n\t\t\t\t\t) {\n\t\t\t\t\t\tremoteObliteratedLen += segment.cachedLength;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tseqSeglen += segment.cachedLength;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (seq === removalInfo?.removedSeq) {\n\t\t\t\t\t// if the remove op happened before an overlapping obliterate,\n\t\t\t\t\t// all clients can see the remove at this seq. otherwise, only\n\t\t\t\t\t// the removing client is aware of the remove\n\t\t\t\t\tif (removeHappenedFirst) {\n\t\t\t\t\t\tseqSeglen -= segment.cachedLength;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tremoteObliteratedLen -= segment.cachedLength;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (seq === moveInfo?.movedSeq) {\n\t\t\t\t\tif (removeHappenedFirst) {\n\t\t\t\t\t\tremoteObliteratedLen -= segment.cachedLength;\n\t\t\t\t\t} else if (\n\t\t\t\t\t\tmoveInfo.wasMovedOnInsert &&\n\t\t\t\t\t\tsegment.seq !== UnassignedSequenceNumber &&\n\t\t\t\t\t\tsegment.seq !== undefined &&\n\t\t\t\t\t\tmoveInfo.movedSeq > segment.seq\n\t\t\t\t\t) {\n\t\t\t\t\t\tremoteObliteratedLen += segment.cachedLength;\n\t\t\t\t\t\tseqSeglen -= segment.cachedLength;\n\t\t\t\t\t} else if (segment.seq !== UnassignedSequenceNumber) {\n\t\t\t\t\t\tseqSeglen -= segment.cachedLength;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsegCount++;\n\t\t\t} else {\n\t\t\t\tconst childBlock = child;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst branchPartialLengths = childBlock.partialLengths!;\n\t\t\t\tconst partialLengths = branchPartialLengths.partialLengths;\n\t\t\t\tconst leqPartial = partialLengths.latestLeq(seq);\n\t\t\t\tif (leqPartial && leqPartial.seq === seq) {\n\t\t\t\t\tseqSeglen += leqPartial.seglen;\n\t\t\t\t\tremoteObliteratedLen += leqPartial.remoteObliteratedLen ?? 0;\n\t\t\t\t}\n\t\t\t\tsegCount += branchPartialLengths.segmentCount;\n\t\t\t}\n\t\t}\n\t\tthis.segmentCount = segCount;\n\t\tthis.unsequencedRecords = undefined;\n\n\t\tPartialSequenceLengths.addSeq(\n\t\t\tthis.partialLengths,\n\t\t\tseq,\n\t\t\tseqSeglen,\n\t\t\tremoteObliteratedLen,\n\t\t\tclientId,\n\t\t);\n\t\tthis.clientSeqNumbers[clientId] ??= new PartialSequenceLengthsSet();\n\t\tPartialSequenceLengths.addSeq(\n\t\t\tthis.clientSeqNumbers[clientId],\n\t\t\tseq,\n\t\t\tseqSeglen + remoteObliteratedLen,\n\t\t\tundefined,\n\t\t\tclientId,\n\t\t);\n\t\tif (PartialSequenceLengths.options.zamboni) {\n\t\t\tthis.zamboni(collabWindow);\n\t\t}\n\n\t\tPartialSequenceLengths.options.verifier?.(this);\n\t}\n\n\t/**\n\t * Returns the length of this block as viewed from the perspective of `clientId` at `refSeq`.\n\t * This is the total length of all segments sequenced at or before refSeq OR submitted by `clientId`.\n\t * If `clientId` is the local client, `localSeq` can also be provided. In that case, it is the total\n\t * length of all segments submitted at or before `refSeq` in addition to any local, unacked segments\n\t * with `segment.localSeq <= localSeq`.\n\t *\n\t * Note: the local case (where `localSeq !== undefined`) is only supported on a PartialSequenceLength object\n\t * constructed with `computeLocalPartials` set to true and not subsequently updated with `update`.\n\t */\n\tpublic getPartialLength(refSeq: number, clientId: number, localSeq?: number): number {\n\t\tlet pLen = this.minLength;\n\t\tconst cliLatestIndex = this.cliLatest(clientId);\n\t\tconst cliSeq = this.clientSeqNumbers[clientId];\n\t\tpLen += this.partialLengths.latestLeq(refSeq)?.len ?? 0;\n\n\t\tif (localSeq === undefined) {\n\t\t\tif (cliLatestIndex >= 0) {\n\t\t\t\tconst cliLatest = cliSeq.items[cliLatestIndex];\n\t\t\t\tif (cliLatest.seq > refSeq) {\n\t\t\t\t\t// The client has local edits after refSeq, add in the length adjustments\n\t\t\t\t\tpLen += cliLatest.len;\n\t\t\t\t\tconst precedingCli = this.cliLatestLEQ(clientId, refSeq);\n\t\t\t\t\tif (precedingCli) {\n\t\t\t\t\t\t// Subtract out double-counted lengths: segments still in the collab window but before\n\t\t\t\t\t\t// the refSeq submitted by the client we're querying for were counted in each addition above.\n\t\t\t\t\t\tpLen -= precedingCli.len;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tthis.unsequencedRecords !== undefined,\n\t\t\t\t0x39f /* Local getPartialLength invoked without computing local partials. */,\n\t\t\t);\n\t\t\tconst unsequencedPartialLengths = this.unsequencedRecords.partialLengths;\n\t\t\t// Local segments at or before localSeq should also be included\n\t\t\tconst local = unsequencedPartialLengths.latestLeq(localSeq);\n\t\t\tif (local) {\n\t\t\t\tpLen += local.len;\n\n\t\t\t\t// Lastly, we must subtract out any double-counted removes, which occur if a currently un-acked local\n\t\t\t\t// remove overlaps with a remote client's remove that occurred at sequence number <=refSeq.\n\t\t\t\tpLen -= this.computeOverlappingLocalRemoves(refSeq, localSeq);\n\t\t\t}\n\t\t}\n\t\treturn pLen;\n\t}\n\n\t/**\n\t * Computes the seglen for the double-counted removed overlap at (refSeq, localSeq). This logic is equivalent\n\t * to the following:\n\t *\n\t * ```typescript\n\t * let total = 0;\n\t * for (const partialLength of this.unsequencedRecords!.overlappingRemoves) {\n\t * if (partialLength.seq > refSeq) {\n\t * break;\n\t * }\n\t *\n\t * if (partialLength.localSeq <= localSeq) {\n\t * total += partialLength.seglen;\n\t * }\n\t * }\n\t *\n\t * return total;\n\t * ```\n\t *\n\t * Reconnect happens to only need to compute these lengths for two refSeq values: before and\n\t * after the rebase. Since these lists potentially scale with O(collab window * number of local edits)\n\t * and potentially need to be queried for each local op that gets rebased,\n\t * we cache the results for a given refSeq in `this.unsequencedRecords.cachedOverlappingByRefSeq` so\n\t * that they can be binary-searched the same way the usual partialLengths lists are.\n\t */\n\tprivate computeOverlappingLocalRemoves(refSeq: number, localSeq: number): number {\n\t\tif (this.unsequencedRecords === undefined) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tlet cachedOverlapPartials = this.unsequencedRecords.cachedOverlappingByRefSeq.get(refSeq);\n\t\tif (!cachedOverlapPartials) {\n\t\t\tconst partials: PartialSequenceLengthsSet = new PartialSequenceLengthsSet();\n\t\t\tfor (const partial of this.unsequencedRecords.overlappingRemoves) {\n\t\t\t\tif (partial.seq > refSeq) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tpartials.addOrUpdate({ ...partial, seq: partial.localSeq, len: 0 });\n\t\t\t}\n\t\t\t// This coalesces entries with the same localSeq as well as computes overall lengths.\n\t\t\tcachedOverlapPartials = partials;\n\t\t\tthis.unsequencedRecords.cachedOverlappingByRefSeq.set(refSeq, cachedOverlapPartials);\n\t\t}\n\n\t\tconst overlap = cachedOverlapPartials.latestLeq(localSeq);\n\t\treturn overlap?.len ?? 0;\n\t}\n\n\tpublic toString(glc?: (id: number) => string, indentCount = 0): string {\n\t\tlet buf = \"\";\n\t\tfor (const partial of this.partialLengths.items) {\n\t\t\tbuf += `(${partial.seq},${partial.len}) `;\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-for-in-array, no-restricted-syntax\n\t\tfor (const clientId in this.clientSeqNumbers) {\n\t\t\tif (this.clientSeqNumbers[clientId].size > 0) {\n\t\t\t\tbuf += `Client `;\n\t\t\t\tbuf += glc ? `${glc(+clientId)}` : `${clientId}`;\n\t\t\t\tbuf += \"[\";\n\t\t\t\tfor (const partial of this.clientSeqNumbers[clientId].items) {\n\t\t\t\t\tbuf += `(${partial.seq},${partial.len})`;\n\t\t\t\t}\n\t\t\t\tbuf += \"]\";\n\t\t\t}\n\t\t}\n\t\tbuf = `min(seq ${this.minSeq}): ${this.minLength}; sc: ${this.segmentCount};${buf}`;\n\t\treturn buf;\n\t}\n\n\t// Clear away partial sums for sequence numbers earlier than the current window\n\n\tprivate zamboni(segmentWindow: CollaborationWindow): void {\n\t\tthis.minLength += this.partialLengths.copyDown(segmentWindow.minSeq);\n\t\tthis.minSeq = segmentWindow.minSeq;\n\t\t// eslint-disable-next-line @typescript-eslint/no-for-in-array, guard-for-in, no-restricted-syntax\n\t\tfor (const clientId in this.clientSeqNumbers) {\n\t\t\tconst cliPartials = this.clientSeqNumbers[clientId];\n\t\t\tif (cliPartials) {\n\t\t\t\tcliPartials.copyDown(segmentWindow.minSeq);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addClientSeqNumber(clientId: number, seq: number, seglen: number): void {\n\t\tthis.clientSeqNumbers[clientId] ??= new PartialSequenceLengthsSet();\n\t\tconst cli = this.clientSeqNumbers[clientId];\n\t\tcli.addOrUpdate({ seq, len: 0, seglen });\n\t}\n\n\t// Assumes sequence number already coalesced and that this is called in increasing `seq` order.\n\tprivate addClientSeqNumberFromPartial(partialLength: PartialSequenceLength): void {\n\t\tconst seglen = partialLength.seglen + (partialLength.remoteObliteratedLen ?? 0);\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tthis.addClientSeqNumber(partialLength.clientId!, partialLength.seq, seglen);\n\t\tif (partialLength.overlapRemoveClients) {\n\t\t\tpartialLength.overlapRemoveClients.map((oc: Property<number, IOverlapClient>) => {\n\t\t\t\t// Original client entry was handled above\n\t\t\t\tif (partialLength.clientId !== oc.data.clientId) {\n\t\t\t\t\tthis.addClientSeqNumber(oc.data.clientId, partialLength.seq, oc.data.seglen);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\t\t}\n\t\tif (partialLength.overlapObliterateClients) {\n\t\t\tpartialLength.overlapObliterateClients.map((oc: Property<number, IOverlapClient>) => {\n\t\t\t\t// Original client entry was handled above\n\t\t\t\tif (partialLength.clientId !== oc.data.clientId) {\n\t\t\t\t\tthis.addClientSeqNumber(oc.data.clientId, partialLength.seq, oc.data.seglen);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate cliLatestLEQ(clientId: number, refSeq: number): PartialSequenceLength | undefined {\n\t\treturn this.clientSeqNumbers[clientId]?.latestLeq(refSeq);\n\t}\n\n\tprivate cliLatest(clientId: number): number {\n\t\tconst cliSeqs = this.clientSeqNumbers[clientId];\n\t\treturn cliSeqs && cliSeqs.size > 0 ? cliSeqs.size - 1 : -1;\n\t}\n}\n\n/* eslint-disable @typescript-eslint/dot-notation */\nfunction verifyPartialLengthsInner(\n\tpartialSeqLengths: PartialSequenceLengths,\n\tpartialLengths: PartialSequenceLengthsSet,\n\tclientPartials: boolean,\n): number {\n\tif (partialLengths.size === 0) {\n\t\treturn 0;\n\t}\n\n\tlet lastSeqNum = 0;\n\tlet accumSegLen = 0;\n\tlet count = 0;\n\n\tfor (const partialLength of partialLengths.items) {\n\t\t// Count total number of partial length entries\n\t\tcount++;\n\n\t\t// Sequence number should be larger or equal to minseq\n\t\tassert(\n\t\t\tpartialSeqLengths.minSeq <= partialLength.seq,\n\t\t\t0x054 /* \"Sequence number less than minSeq!\" */,\n\t\t);\n\n\t\t// Sequence number should be sorted\n\t\tassert(lastSeqNum < partialLength.seq, 0x055 /* \"Sequence number is not sorted!\" */);\n\t\tlastSeqNum = partialLength.seq;\n\n\t\t// Len is a accumulation of all the seglen adjustments\n\t\taccumSegLen += partialLength.seglen;\n\t\tif (accumSegLen !== partialLength.len) {\n\t\t\tassert(\n\t\t\t\tfalse,\n\t\t\t\t0x056 /* \"Unexpected total for accumulation of all seglen adjustments!\" */,\n\t\t\t);\n\t\t}\n\n\t\tif (clientPartials) {\n\t\t\t// Client partials used to track local edits so we can account for them some refSeq.\n\t\t\t// But the information we keep track of are since minSeq, so we keep track of more history\n\t\t\t// then needed, and some of them doesn't make sense to be used for length calculations\n\t\t\t// e.g. if you have this sequence, where the minSeq is #5 because of other clients\n\t\t\t// seq 10: client 1: insert seg #1\n\t\t\t// seq 11: client 2: delete seg #2 refseq: 10\n\t\t\t// minLength is 0, we would have keep a record of seglen: -1 for clientPartialLengths for client 2\n\t\t\t// So if you ask for partial length for client 2 @ seq 5, we will have return -1.\n\t\t\t// However, that combination is invalid, since we should never see any ops with refseq < 10 for\n\t\t\t// client 2 after seq 11.\n\t\t} else {\n\t\t\t// Len adjustment should not make length negative\n\t\t\tif (partialSeqLengths[\"minLength\"] + partialLength.len < 0) {\n\t\t\t\tassert(false, 0x057 /* \"Negative length after length adjustment!\" */);\n\t\t\t}\n\t\t}\n\n\t\tif (partialLength.overlapRemoveClients) {\n\t\t\t// Only the flat partialLengths can have overlapRemoveClients, the per client view shouldn't\n\t\t\tassert(\n\t\t\t\t!clientPartials,\n\t\t\t\t0x058 /* \"Both overlapRemoveClients and clientPartials are set!\" */,\n\t\t\t);\n\n\t\t\t// Each overlap client counts as one, but the first remove to sequence was already counted.\n\t\t\t// (this aligns with the logic to omit the removing client in `addClientSeqNumberFromPartial`)\n\t\t\tcount += partialLength.overlapRemoveClients.size() - 1;\n\t\t}\n\n\t\tif (partialLength.overlapObliterateClients) {\n\t\t\t// Only the flat partialLengths can have overlapObliterateClients, the per client view shouldn't\n\t\t\tassert(\n\t\t\t\t!clientPartials,\n\t\t\t\t0x872 /* Both overlapObliterateClients and clientPartials are set! */,\n\t\t\t);\n\n\t\t\t// Each overlap client counts as one, but the first move to sequence was already counted.\n\t\t\t// (this aligns with the logic to omit the moving client in `addClientSeqNumberFromPartial`)\n\t\t\tcount += partialLength.overlapObliterateClients.size() - 1;\n\t\t}\n\t}\n\treturn count;\n}\n\nexport function verifyExpectedPartialLengths(\n\tmergeTree: MergeTree,\n\tnode: MergeBlock,\n\trefSeq: number,\n\tclientId: number,\n\tlocalSeq?: number,\n): void {\n\tif (\n\t\t(!mergeTree.collabWindow.collaborating || mergeTree.collabWindow.clientId === clientId) &&\n\t\t(node.isLeaf() || localSeq === undefined)\n\t) {\n\t\treturn;\n\t}\n\n\tconst partialLen = node.partialLengths?.getPartialLength(refSeq, clientId, localSeq);\n\n\tlet expected = 0;\n\tconst nodesToVisit: IMergeNode[] = [node];\n\n\twhile (nodesToVisit.length > 0) {\n\t\tconst thisNode = nodesToVisit.pop();\n\t\tif (!thisNode) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (thisNode.isLeaf()) {\n\t\t\texpected += mergeTree[\"nodeLength\"](thisNode, refSeq, clientId, localSeq) ?? 0;\n\t\t} else {\n\t\t\tnodesToVisit.push(...thisNode.children.slice(0, thisNode.childCount));\n\t\t}\n\t}\n\n\tif (expected !== partialLen) {\n\t\tnode.partialLengths?.getPartialLength(refSeq, clientId, localSeq);\n\t\tthrow new Error(\n\t\t\t`expected partial length of ${expected} but found ${partialLen}. refSeq: ${refSeq}, clientId: ${clientId}`,\n\t\t);\n\t}\n}\n\nexport function verifyPartialLengths(partialSeqLengths: PartialSequenceLengths): void {\n\tif (partialSeqLengths[\"clientSeqNumbers\"]) {\n\t\tfor (const cliSeq of partialSeqLengths[\"clientSeqNumbers\"]) {\n\t\t\tif (cliSeq) {\n\t\t\t\tverifyPartialLengthsInner(partialSeqLengths, cliSeq, true);\n\t\t\t}\n\t\t}\n\n\t\t// If we have client view, we should have the flat view\n\t\tassert(\n\t\t\t!!partialSeqLengths[\"partialLengths\"],\n\t\t\t0x059 /* \"Client view exists but flat view does not!\" */,\n\t\t);\n\n\t\tverifyPartialLengthsInner(partialSeqLengths, partialSeqLengths[\"partialLengths\"], false);\n\t} else {\n\t\t// If we don't have a client view, we shouldn't have the flat view either\n\t\tassert(\n\t\t\t!partialSeqLengths[\"partialLengths\"],\n\t\t\t0x05b /* \"Flat view exists but client view does not!\" */,\n\t\t);\n\t}\n}\n/* eslint-enable @typescript-eslint/dot-notation */\n\n/**\n * Clones an `overlapRemoveClients` red-black tree.\n */\nfunction cloneOverlapRemoveClients(\n\toldTree: RedBlackTree<number, IOverlapClient> | undefined,\n): RedBlackTree<number, IOverlapClient> | undefined {\n\tif (!oldTree) {\n\t\treturn undefined;\n\t}\n\tconst newTree = new RedBlackTree<number, IOverlapClient>(compareNumbers);\n\toldTree.map((bProp: Property<number, IOverlapClient>) => {\n\t\tnewTree.put(bProp.data.clientId, { ...bProp.data });\n\t\treturn true;\n\t});\n\treturn newTree;\n}\n\nfunction combineForOverlapClients(\n\ttreeA: RedBlackTree<number, IOverlapClient> | undefined,\n\ttreeB: RedBlackTree<number, IOverlapClient> | undefined,\n): RedBlackTree<number, IOverlapClient> | undefined {\n\tif (treeA) {\n\t\tif (treeB) {\n\t\t\ttreeB.map((bProp: Property<number, IOverlapClient>) => {\n\t\t\t\tconst aProp = treeA.get(bProp.key);\n\t\t\t\tif (aProp) {\n\t\t\t\t\taProp.data.seglen += bProp.data.seglen;\n\t\t\t\t} else {\n\t\t\t\t\ttreeA.put(bProp.data.clientId, { ...bProp.data });\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\t\t}\n\t} else {\n\t\treturn cloneOverlapRemoveClients(treeB);\n\t}\n}\n\n/**\n * Combines the `overlapRemoveClients` and `overlapObliterateClients` fields of\n * two `PartialSequenceLength` objects, modifying the first PartialSequenceLength's\n * bookkeeping in-place.\n *\n * Combination is performed additively on `seglen` on a per-client basis.\n */\nexport function combineOverlapClients(\n\ta: PartialSequenceLength,\n\tb: PartialSequenceLength,\n): void {\n\tconst overlapRemoveClients = combineForOverlapClients(\n\t\ta.overlapRemoveClients,\n\t\tb.overlapRemoveClients,\n\t);\n\tif (overlapRemoveClients) {\n\t\ta.overlapRemoveClients = overlapRemoveClients;\n\t}\n\n\tconst overlapObliterateClients = combineForOverlapClients(\n\t\ta.overlapObliterateClients,\n\t\tb.overlapObliterateClients,\n\t);\n\tif (overlapObliterateClients) {\n\t\ta.overlapObliterateClients = overlapObliterateClients;\n\t}\n}\n\n/**\n * Given a number of seq-sorted `partialLength` lists, merges them into a combined seq-sorted `partialLength`\n * list. This merge includes coalescing `PartialSequenceLength` entries at the same seq.\n *\n * Ex: merging the following two lists (some information omitted on each PartialSequenceLength):\n * ```typescript\n * [{ seq: 1, seglen: 5 }, { seq: 3, seglen: -1 }]\n * [{ seq: 1, seglen: -3 }, { seq: 2: seglen: 4 }]\n * ```\n * would produce\n * ```typescript\n * [{ seq: 1, seglen: 2 }, { seq: 2, seglen: 4 }, { seq: 3, seglen: -1 }]\n * ```\n */\nfunction mergePartialLengths(\n\tchildPartialLengths: PartialSequenceLength[][],\n\tmergedLengths: PartialSequenceLengthsSet = new PartialSequenceLengthsSet(),\n): PartialSequenceLengthsSet {\n\tfor (const partialLength of mergeSortedListsBySeq(childPartialLengths)) {\n\t\tmergedLengths.addOrUpdate({\n\t\t\t...partialLength,\n\t\t\toverlapRemoveClients: cloneOverlapRemoveClients(partialLength.overlapRemoveClients),\n\t\t\toverlapObliterateClients: cloneOverlapRemoveClients(\n\t\t\t\tpartialLength.overlapObliterateClients,\n\t\t\t),\n\t\t});\n\t}\n\treturn mergedLengths;\n}\n\n/**\n * Given a collection of PartialSequenceLength lists--each sorted by sequence number--returns an iterable that yields\n * each PartialSequenceLength in sequence order.\n *\n * This is equivalent to flattening the input list and sorting it by sequence number. If the number of lists to merge is\n * a constant, however, this approach is advantageous asymptotically.\n */\nfunction mergeSortedListsBySeq<T extends PartialSequenceLength>(lists: T[][]): Iterable<T> {\n\tclass PartialSequenceLengthIterator {\n\t\t/**\n\t\t * nextSmallestIndex[i] is the next element of sublists[i] to check.\n\t\t * In other words, the iterator has already yielded elements of sublists[i] *up through*\n\t\t * sublists[i][nextSmallestIndex[i] - 1].\n\t\t */\n\t\tprivate readonly nextSmallestIndex: number[];\n\n\t\tconstructor(private readonly sublists: T[][]) {\n\t\t\tthis.nextSmallestIndex = Array.from({ length: sublists.length });\n\t\t\tfor (let i = 0; i < sublists.length; i++) {\n\t\t\t\tthis.nextSmallestIndex[i] = 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic next(): { value: T; done: false } | { value: undefined; done: true } {\n\t\t\tconst len = this.sublists.length;\n\t\t\tlet currentMin: T | undefined;\n\t\t\tlet currentMinIndex: number | undefined;\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\tconst candidateIndex = this.nextSmallestIndex[i];\n\t\t\t\tif (candidateIndex < this.sublists[i].length) {\n\t\t\t\t\tconst candidate = this.sublists[i][candidateIndex];\n\t\t\t\t\tif (!currentMin || candidate.seq < currentMin.seq) {\n\t\t\t\t\t\tcurrentMin = candidate;\n\t\t\t\t\t\tcurrentMinIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentMin) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tthis.nextSmallestIndex[currentMinIndex!]++;\n\t\t\t\treturn { value: currentMin, done: false };\n\t\t\t} else {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { [Symbol.iterator]: () => new PartialSequenceLengthIterator(lists) };\n}\n\nfunction insertIntoList<T>(list: T[], index: number, elem: T): void {\n\tif (index < list.length) {\n\t\tfor (let k = list.length; k > index; k--) {\n\t\t\tlist[k] = list[k - 1];\n\t\t}\n\t\tlist[index] = elem;\n\t} else {\n\t\tlist.push(elem);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"partialLengths.js","sourceRoot":"","sources":["../src/partialLengths.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport { UnassignedSequenceNumber } from \"./constants.js\";\nimport { MergeTree } from \"./mergeTree.js\";\nimport {\n\tCollaborationWindow,\n\tIMergeNode,\n\tISegmentPrivate,\n\tseqLTE,\n\ttype MergeBlock,\n} from \"./mergeTreeNodes.js\";\nimport { toRemovalInfo, toMoveInfo, assertInserted } from \"./segmentInfos.js\";\nimport { SortedSet } from \"./sortedSet.js\";\n\nclass PartialSequenceLengthsSet extends SortedSet<PartialSequenceLength> {\n\tprotected compare(a: PartialSequenceLength, b: PartialSequenceLength): number {\n\t\treturn a.seq - b.seq;\n\t}\n\n\tpublic addOrUpdate(\n\t\tnewItem: PartialSequenceLength,\n\t\tupdate?: (existingItem: PartialSequenceLength, newItem: PartialSequenceLength) => void,\n\t): void {\n\t\tif (newItem.seglen === 0) {\n\t\t\t// Don't bother doing any updates for deltas of 0.\n\t\t\treturn;\n\t\t}\n\t\tconst prev = this.latestLeq(newItem.seq);\n\n\t\tif (prev?.seq !== newItem.seq) {\n\t\t\t// new element, update len\n\t\t\tnewItem.len = (prev?.len ?? 0) + newItem.seglen;\n\t\t}\n\n\t\t// update the len of all following elements\n\t\tfor (let i = this.sortedItems.length - 1; i >= 0; i--) {\n\t\t\tconst element = this.sortedItems[i];\n\t\t\tif (!element || element.seq <= newItem.seq) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\telement.len += newItem.seglen;\n\t\t}\n\n\t\tsuper.addOrUpdate(newItem, (currentPartial, partialLength) => {\n\t\t\tassert(\n\t\t\t\tpartialLength.clientId === currentPartial.clientId,\n\t\t\t\t0xab6 /* clientId mismatch */,\n\t\t\t);\n\t\t\tcurrentPartial.seglen += partialLength.seglen;\n\t\t\tcurrentPartial.len += partialLength.seglen;\n\t\t});\n\t}\n\n\t/**\n\t * Returns the partial length whose sequence number is the greatest sequence\n\t * number that is less than or equal to key.\n\t * @param key - sequence number\n\t */\n\tlatestLeq(key: number): PartialSequenceLength | undefined {\n\t\treturn this.sortedItems[this.latestLeqIndex(key)];\n\t}\n\n\t/**\n\t * Returns the partial length whose sequence number is the lowest sequence\n\t * number that is greater than or equal to key.\n\t * @param key - sequence number\n\t */\n\tfirstGte(key: number): PartialSequenceLength | undefined {\n\t\tconst { index } = this.findItemPosition({ seq: key, len: 0, seglen: 0 });\n\t\treturn this.sortedItems[index];\n\t}\n\n\tprivate latestLeqIndex(key: number): number {\n\t\tconst { exists, index } = this.findItemPosition({ seq: key, len: 0, seglen: 0 });\n\t\treturn exists ? index : index - 1;\n\t}\n\n\tcopyDown(minSeq: number): number {\n\t\tconst mindex = this.latestLeqIndex(minSeq);\n\t\tlet minLength = 0;\n\t\tif (mindex >= 0) {\n\t\t\tminLength = this.sortedItems[mindex].len;\n\t\t\tconst seqCount = this.size;\n\t\t\tif (mindex <= seqCount - 1) {\n\t\t\t\t// Still some entries remaining\n\t\t\t\tconst remainingCount = seqCount - mindex - 1;\n\t\t\t\t// Copy down\n\t\t\t\tfor (let i = 0; i < remainingCount; i++) {\n\t\t\t\t\tthis.sortedItems[i] = this.sortedItems[i + mindex + 1];\n\t\t\t\t\tthis.sortedItems[i].len -= minLength;\n\t\t\t\t}\n\t\t\t\tthis.sortedItems.length = remainingCount;\n\t\t\t}\n\t\t}\n\t\treturn minLength;\n\t}\n}\n\n/**\n * Tracks length information for a part of a MergeTree (block) at a given time (seq).\n * These objects are associated with internal nodes (i.e. blocks).\n */\nexport interface PartialSequenceLength {\n\t/**\n\t * Sequence number\n\t */\n\tseq: number;\n\t/**\n\t * The length of the associated block.\n\t */\n\tlen: number;\n\t/**\n\t * The delta between the current length of the associated block and its length at the previous seq number.\n\t */\n\tseglen: number;\n\t/**\n\t * clientId for the client that submitted the op with sequence number `seq`.\n\t */\n\tclientId?: number;\n}\n\ninterface UnsequencedPartialLengthInfo {\n\t/**\n\t * Contains entries for all local operations.\n\t * The \"seq\" field of each entry actually corresponds to the delta at that localSeq on the local client.\n\t *\n\t * The length entries in this set are analogous to `PartialSequenceLengths.partialLengths` in that they represent the delta over the min seq\n\t * that an observer client would see if they were to observe the local client's edits performed from the minSeq.\n\t */\n\tpartialLengths: PartialSequenceLengthsSet;\n\n\t/**\n\t * Like PerClientAdjustments, except we store one set of PartialSequenceLengthsSet for each refSeq. The \"seq\" keys in these sets\n\t * are all local seqs.\n\t *\n\t * These entries are aggregated by {@link PartialSequenceLengths.computeOverallRefSeqAdjustment} when a local perspective for a\n\t * given refSeq is requested.\n\t *\n\t * In general, adjustments in this map are added to avoid double-counting an operation performed by both the local client and some\n\t * remote client, and an adjustment at (refSeq = A, clientSeq = B) takes effect for all perspectives (refSeq = C, clientSeq = D) where\n\t * A \\<= C and B \\<= D.\n\t */\n\tperRefSeqAdjustments: Map<number, PartialSequenceLengthsSet>;\n\n\t/**\n\t * Cache keyed on refSeq which stores length information for the total overlap of removed segments at\n\t * that refSeq.\n\t * This information is derivable from the entries of `perRefSeqAdjustments`.\n\t *\n\t * Like the `partialLengths` field, `seq` on each entry is actually the local seq.\n\t * See `computeOverallRefSeqAdjustment` for more information.\n\t */\n\tcachedAdjustmentByRefSeq: Map<number, PartialSequenceLengthsSet>;\n}\n\nexport interface PartialSequenceLengthsOptions {\n\tverifier?: (partialLengths: PartialSequenceLengths) => void;\n\tverifyExpected?: (\n\t\tmergeTree: MergeTree,\n\t\tnode: MergeBlock,\n\t\trefSeq: number,\n\t\tclientId: number,\n\t\tlocalSeq?: number,\n\t) => void;\n\tzamboni: boolean;\n}\n\n/**\n * Keeps track of partial sums of segment lengths for all sequence numbers in the current collaboration window.\n * Only used during active collaboration.\n *\n * This class is associated with an internal node (block) of a MergeTree. It efficiently answers queries of the form\n * \"What is the length of `block` from the perspective of some particular seq and clientId?\".\n *\n * It also supports incremental updating of state for newly-sequenced ops that don't affect the structure of the\n * MergeTree (in most cases--see AB#31003 or comments on {@link PartialSequenceLengths.update}).\n *\n * To answer these queries, it pre-builds several lists which track the length of the block at a per-sequence-number\n * level. These lists are:\n *\n * 1. (`partialLengths`): Stores the total length of the block.\n * 2. (`perClientAdjustments[clientId]`): Stores adjustments to the base length which account for all changes submitted by `clientId`. [see footnote]\n *\n * The reason both lists are necessary is that resolving the length of the block from the perspective of\n * (clientId, refSeq) requires including both of the following types of segments:\n * 1. Segments sequenced before `refSeq`\n * 2. Segments submitted by `clientId`\n *\n * This is possible with the above bookkeeping, using:\n *\n * (length of the block at the minimum sequence number)\n * + (partialLengths total length at refSeq)\n * + (clientSeqNumbers total length at most recent op)\n * - (clientSeqNumbers total length at refSeq)\n *\n * where the subtraction avoids double-counting segments submitted by clientId sequenced within the collab window.\n *\n * To enable reconnect, if constructed with `computeLocalPartials === true` it also supports querying for the length of\n * the block from the perspective of the local client at a particular `refSeq` and `localSeq`. This computation is\n * similar to the above:\n *\n * (length of the block at the minimum sequence number)\n * + (partialLengths total length at refSeq)\n * + (unsequenced edits' total length submitted before localSeq)\n * + (adjustments for changes double-counted by happening at or before both localSeq and refSeq)\n *\n * This algorithm scales roughly linearly with number of editing clients and the size of the collab window.\n * (certain unlikely sequences of operations may introduce log factors on those variables)\n *\n * @privateRemarks\n * If you are looking to understand this class in more detail, a suggested order of internalization is:\n *\n * 1. The above description and how it relates to the implementation of `getPartialLength` (which implements the above high-level description\n * 2. `PartialSequenceLengthsSet`, which allows binary searching for overall length deltas at a given sequence number and handles updates.\n * 3. The `fromLeaves` method, which is the base case for the [potential] recursion in `combine`\n * 4. The logic in `combine` to aggregate smaller block entries into larger ones\n * 5. The incremental code path of `update`\n */\nexport class PartialSequenceLengths {\n\tpublic static options: PartialSequenceLengthsOptions = {\n\t\tzamboni: true,\n\t};\n\n\t/**\n\t * Length of the block this PartialSequenceLength corresponds to when viewed at `minSeq`.\n\t */\n\tprivate minLength = 0;\n\n\t/**\n\t * Total number of segments in the subtree rooted at the block this PartialSequenceLength corresponds to.\n\t */\n\tprivate segmentCount = 0;\n\n\t/**\n\t * List of PartialSequenceLength objects--ordered by increasing seq--giving length information about\n\t * the block associated with this PartialSequenceLengths object.\n\t *\n\t * `minLength + partialLengths[i].len` gives the length of this block when considering the perspective of an observer\n\t * client who has received edits up to (and including) sequence number `i`.\n\t */\n\tprivate readonly partialLengths: PartialSequenceLengthsSet = new PartialSequenceLengthsSet();\n\n\t/**\n\t * perClientAdjustments[clientId] contains a PartialSequenceLengthsSet of adjustments to the observer client's\n\t * perspective (see {@link PartialSequenceLengths.partialLengths}) necessary to account for changes made by\n\t * that client.\n\t *\n\t * As per doc comment on {@link PartialSequenceLengths}, the overall adjustment performed for the perspective of\n\t * (clientId, refSeq) is given by the sum of length deltas in `perClientAdjustments[clientId]`\n\t * for all sequence numbers S such that S \\>= refSeq.\n\t *\n\t * (since these are ordered by sequence number and we cache cumulative sums, this is implemented using two lookups and a subtraction).\n\t *\n\t * The specific adjustments are roughly categorized as follows:\n\t *\n\t * - Ops submitted by a given client generally receive a partial lengths entry corresponding to their sequence number.\n\t * e.g. insert of \"ABC\" at seq 5 will have a per-client adjustment entry of \\{ seq: 5, seglen: 3 \\}.\n\t *\n\t * - When client A deletes a segment concurrently with client B and loses the race (B's delete is sequenced first),\n\t * A's per-client adjustments will contain an entry with a negative `seglen` corresponding to the length of the segment\n\t * and a sequence number corresponding to that of B's delete. It will *not* receive a per-client adjustment for its own delete.\n\t * This ensures that for perspectives (A, refSeq), the deleted segment will show up as a negative delta for all values of refSeq, since:\n\t * 1. For refSeq \\< B's delete, the per-client adjustment will apply and be added to the total length\n\t * 2. For refSeq \\>= B's delete, B's partial length entry in the overall set will apply, and the per-client adjustment will not apply\n\t *\n\t * - When client A attempts to insert a segment into a location that is concurrently obliterated by client B immediately upon insertion,\n\t * A's per-client adjustments will again not include an entry for its own insert.\n\t * Instead, the entry which would normally contain `seq` equal to that of A's insert would instead have `seq` equal to that of B's obliterate.\n\t * This gives the overall correct behavior: for any perspective which isn't client A, there is no adjustment necessary anywhere (it's as if\n\t * the segment never existed). For client A's perspective, the segment should be considered visible until A has acked B's obliterate.\n\t * This is accomplished as for the perspective (A, refSeq):\n\t * 1. For refSeq \\< B's obliterate, the segment length will be included as part of the per-client adjustment for A\n\t * 2. For refSeq \\>= B's obliterate, the segment will be omitted from the per-client adjustment for A\n\t *\n\t * Note that the special-casing for inserting segments that are immediately obliterated is only necessary for segments that never were visible\n\t * in the tree. If an insert and obliterate are concurrent but the insert is sequenced first, the normal per-client adjustment is fine.\n\t *\n\t * The second case (overlapping removal) applies to any combination of remove / obliterate operations.\n\t */\n\tprivate readonly perClientAdjustments: PartialSequenceLengthsSet[] = [];\n\n\t/**\n\t * Contains information required to answer queries for the length of this segment from the perspective of\n\t * the local client but not including all local segments (i.e., `localSeq !== collabWindow.localSeq`).\n\t * This field is only computed if requested in the constructor (i.e. `computeLocalPartials === true`).\n\t *\n\t * Note that the usage pattern for this list is a bit different from perClientAdjustments: when dealing with perspectives of remote clients,\n\t * we generally want to know what their view of the block was accounting for all changes made by that client as well as all \\<= some refSeq.\n\t *\n\t * However, when dealing with perspectives relevant to the local client, we are still interested in changes made \\<= some refSeq, but instead\n\t * of caring about all changes made by the local client, we additionally want the subset of them that were made \\<= some localSeq.\n\t *\n\t * The PartialSequenceLengthsSets stored in this field therefore track localSeqs rather than seqs (it's still named seq for ease of implementation).\n\t * Furthermore, when computing the length of the block at a given refSeq/localSeq perspective,\n\t * rather than add something like `perClientAdjustments[clientId].latestLeq(latestSeq) - perClientAdjustments[clientId].latestLeq(refSeq)` [to\n\t * get the tail end of adjustments necessary for a remote client client], we instead add `unsequencedRecords.partialLengths.latestLeq(localSeq)`\n\t * [to get the head end of adjustments necessary for the local client].\n\t */\n\tprivate unsequencedRecords: UnsequencedPartialLengthInfo | undefined;\n\n\tconstructor(\n\t\t/**\n\t\t * The minimumSequenceNumber as defined by the collab window used in the last call to `update`,\n\t\t * or if no such calls have been made, the one used on construction.\n\t\t */\n\t\tpublic minSeq: number,\n\t\tcomputeLocalPartials: boolean,\n\t) {\n\t\tif (computeLocalPartials) {\n\t\t\tthis.unsequencedRecords = {\n\t\t\t\tpartialLengths: new PartialSequenceLengthsSet(),\n\t\t\t\tperRefSeqAdjustments: new Map(),\n\t\t\t\tcachedAdjustmentByRefSeq: new Map(),\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Combine the partial lengths of block's children\n\t * @param block - an interior node. If `recur` is false, it is assumed that each interior node child of this block\n\t * has its partials up to date.\n\t * @param collabWindow - segment window of the segment tree containing `block`.\n\t * @param recur - whether to recursively compute partial lengths for internal children of `block`.\n\t * This incurs more work, but gives correct bookkeeping in the case that a descendant in the merge tree has been\n\t * modified without bubbling up the resulting partial length change to this block's partials.\n\t * @param computeLocalPartials - whether to compute partial length information about local unsequenced ops.\n\t * This enables querying for the length of the block at a given localSeq, but incurs extra work.\n\t * Local partial information doesn't support `update`.\n\t */\n\tpublic static combine(\n\t\tblock: MergeBlock,\n\t\tcollabWindow: CollaborationWindow,\n\t\trecur = false,\n\t\tcomputeLocalPartials = false,\n\t): PartialSequenceLengths {\n\t\tconst leafPartialLengths = PartialSequenceLengths.fromLeaves(\n\t\t\tblock,\n\t\t\tcollabWindow,\n\t\t\tcomputeLocalPartials,\n\t\t);\n\n\t\tlet hasInternalChild = false;\n\t\tconst childPartials: PartialSequenceLengths[] = [];\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tif (!child.isLeaf()) {\n\t\t\t\thasInternalChild = true;\n\t\t\t\tif (recur) {\n\t\t\t\t\tchild.partialLengths = PartialSequenceLengths.combine(\n\t\t\t\t\t\tchild,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tcomputeLocalPartials,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tchildPartials.push(child.partialLengths!);\n\t\t\t}\n\t\t}\n\n\t\t// If there are no internal children, the PartialSequenceLengths returns from `fromLeaves` is exactly correct.\n\t\t// Otherwise, we must additively combine all of the children partial lengths to get this block's totals.\n\t\tconst combinedPartialLengths = hasInternalChild\n\t\t\t? new PartialSequenceLengths(collabWindow.minSeq, computeLocalPartials)\n\t\t\t: leafPartialLengths;\n\t\tif (hasInternalChild) {\n\t\t\tif (leafPartialLengths.partialLengths.size > 0) {\n\t\t\t\t// Some children were leaves; add combined partials from these segments\n\t\t\t\tchildPartials.push(leafPartialLengths);\n\t\t\t}\n\n\t\t\tconst childPartialsLen = childPartials.length;\n\n\t\t\tconst childPartialLengths: PartialSequenceLength[][] = [];\n\t\t\tconst childUnsequencedPartialLengths: PartialSequenceLength[][] = [];\n\t\t\tconst childPerRefSeqAdjustments: Map<number, PartialSequenceLengthsSet>[] = [];\n\t\t\tfor (let i = 0; i < childPartialsLen; i++) {\n\t\t\t\tconst { segmentCount, minLength, partialLengths, unsequencedRecords } =\n\t\t\t\t\tchildPartials[i];\n\t\t\t\tcombinedPartialLengths.segmentCount += segmentCount;\n\t\t\t\tcombinedPartialLengths.minLength += minLength;\n\t\t\t\tchildPartialLengths.push(partialLengths.items as PartialSequenceLength[]);\n\t\t\t\tif (unsequencedRecords) {\n\t\t\t\t\tchildUnsequencedPartialLengths.push(\n\t\t\t\t\t\tunsequencedRecords.partialLengths.items as PartialSequenceLength[],\n\t\t\t\t\t);\n\t\t\t\t\tchildPerRefSeqAdjustments.push(unsequencedRecords.perRefSeqAdjustments);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmergePartialLengths(childPartialLengths, combinedPartialLengths.partialLengths);\n\n\t\t\tif (computeLocalPartials) {\n\t\t\t\tcombinedPartialLengths.unsequencedRecords = {\n\t\t\t\t\tpartialLengths: mergePartialLengths(childUnsequencedPartialLengths),\n\t\t\t\t\tcachedAdjustmentByRefSeq: new Map(),\n\t\t\t\t\tperRefSeqAdjustments: new Map(),\n\t\t\t\t};\n\n\t\t\t\tfor (const perRefSeq of childPerRefSeqAdjustments) {\n\t\t\t\t\tfor (const [refSeq, partials] of perRefSeq) {\n\t\t\t\t\t\tlet combinedPartials =\n\t\t\t\t\t\t\tcombinedPartialLengths.unsequencedRecords.perRefSeqAdjustments.get(refSeq);\n\t\t\t\t\t\tif (combinedPartials === undefined) {\n\t\t\t\t\t\t\tcombinedPartials = new PartialSequenceLengthsSet();\n\t\t\t\t\t\t\tcombinedPartialLengths.unsequencedRecords.perRefSeqAdjustments.set(\n\t\t\t\t\t\t\t\trefSeq,\n\t\t\t\t\t\t\t\tcombinedPartials,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const item of partials.items) {\n\t\t\t\t\t\t\tcombinedPartials.addOrUpdate({ ...item });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// could merge these like we do above rather than do out of order like this\n\t\t\tfor (let i = 0; i < childPartialsLen; i++) {\n\t\t\t\tconst { perClientAdjustments } = childPartials[i];\n\t\t\t\tif (perClientAdjustments.length > 0) {\n\t\t\t\t\tfor (let clientId = 0; clientId < perClientAdjustments.length; clientId++) {\n\t\t\t\t\t\tconst clientAdjustment = perClientAdjustments[clientId];\n\t\t\t\t\t\tif (clientAdjustment === undefined) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (const partial of perClientAdjustments[clientId].items) {\n\t\t\t\t\t\t\tcombinedPartialLengths.addClientAdjustment(\n\t\t\t\t\t\t\t\tclientId,\n\t\t\t\t\t\t\t\tpartial.seq,\n\t\t\t\t\t\t\t\tpartial.seglen,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// TODO: incremental zamboni during build\n\t\tif (PartialSequenceLengths.options.zamboni) {\n\t\t\tcombinedPartialLengths.zamboni(collabWindow);\n\t\t}\n\n\t\tPartialSequenceLengths.options.verifier?.(combinedPartialLengths);\n\t\treturn combinedPartialLengths;\n\t}\n\n\t/**\n\t * Create a `PartialSequenceLengths` which tracks only changes incurred by direct child leaves of `block`.\n\t */\n\tprivate static fromLeaves(\n\t\tblock: MergeBlock,\n\n\t\tcollabWindow: CollaborationWindow,\n\t\tcomputeLocalPartials: boolean,\n\t\tretry = true,\n\t): PartialSequenceLengths {\n\t\tconst combinedPartialLengths = new PartialSequenceLengths(\n\t\t\tcollabWindow.minSeq,\n\t\t\tcomputeLocalPartials,\n\t\t);\n\t\tcombinedPartialLengths.segmentCount = block.childCount;\n\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tif (child.isLeaf()) {\n\t\t\t\t// Leaf segment\n\t\t\t\tconst segment = child;\n\t\t\t\tconst moveInfo = toMoveInfo(segment);\n\t\t\t\tif (moveInfo?.wasMovedOnInsert) {\n\t\t\t\t\tPartialSequenceLengths.accountForMoveOnInsert(\n\t\t\t\t\t\tcombinedPartialLengths,\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tPartialSequenceLengths.accountForInsertion(\n\t\t\t\t\t\tcombinedPartialLengths,\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t);\n\n\t\t\t\t\tPartialSequenceLengths.accountForRemoval(\n\t\t\t\t\t\tcombinedPartialLengths,\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tPartialSequenceLengths.options.verifier?.(combinedPartialLengths);\n\t\treturn combinedPartialLengths;\n\t}\n\n\t/**\n\t * Assuming this segment was moved on insertion, inserts length information about that operation\n\t * into the appropriate per-client adjustments (the overall view needs no such adjustment since\n\t * from an observing client's perspective, the segment never exists).\n\t */\n\tprivate static accountForMoveOnInsert(\n\t\tcombinedPartialLengths: PartialSequenceLengths,\n\t\tsegment: ISegmentPrivate,\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\tassertInserted(segment);\n\t\tconst moveInfo = toMoveInfo(segment);\n\t\tassert(moveInfo?.wasMovedOnInsert === true, 0xab7 /* Segment was not moved on insert */);\n\t\tif (moveInfo.movedSeq <= collabWindow.minSeq) {\n\t\t\t// This segment was obliterated as soon as it was inserted, and everyone was aware of the obliterate.\n\t\t\t// Thus every single client treats this segment as length 0 from every perspective, and no adjustments\n\t\t\t// are necessary.\n\t\t\treturn;\n\t\t}\n\n\t\tconst isLocal = segment.seq === UnassignedSequenceNumber;\n\t\tconst clientId = segment.clientId;\n\n\t\tconst partials = isLocal\n\t\t\t? combinedPartialLengths.unsequencedRecords?.partialLengths\n\t\t\t: combinedPartialLengths.partialLengths;\n\t\tif (partials === undefined) {\n\t\t\t// Local partial but its computation isn't required\n\t\t\treturn;\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\t// Implication -> this is a local segment which will be obliterated as soon as it is acked.\n\t\t\t// For refSeqs preceding that movedSeq and localSeqs following the localSeq, it will be visible.\n\t\t\t// For the rest, it will not be visible.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst localSeq = segment.localSeq!;\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: localSeq,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: segment.cachedLength,\n\t\t\t\tclientId,\n\t\t\t});\n\n\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\trefSeq: moveInfo.movedSeq,\n\t\t\t\tlocalSeq,\n\t\t\t\tseglen: -segment.cachedLength,\n\t\t\t});\n\t\t} else {\n\t\t\t// Segment was obliterated on insert. Generally this means it should be visible only to the\n\t\t\t// inserting client (in which case we add an adjustment to only that client's perspective),\n\t\t\t// but if that client has also removed it, we don't need to add anything.\n\t\t\tconst removeInfo = toRemovalInfo(segment);\n\n\t\t\tconst wasRemovedByInsertingClient =\n\t\t\t\tremoveInfo !== undefined && removeInfo.removedClientIds.includes(clientId);\n\t\t\tconst wasMovedByInsertingClient =\n\t\t\t\tmoveInfo !== undefined && moveInfo.movedClientIds.includes(clientId);\n\n\t\t\tif (!wasRemovedByInsertingClient && !wasMovedByInsertingClient) {\n\t\t\t\tconst moveSeq = moveInfo?.movedSeq;\n\t\t\t\tassert(\n\t\t\t\t\tmoveSeq !== undefined,\n\t\t\t\t\t0xab8 /* ObliterateOnInsertion implies moveSeq is defined */,\n\t\t\t\t);\n\t\t\t\tcombinedPartialLengths.addClientAdjustment(clientId, moveSeq, segment.cachedLength);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Inserts length information about the insertion of `segment` into\n\t * `combinedPartialLengths.partialLengths` and the appropriate per-client adjustments.\n\t */\n\tprivate static accountForInsertion(\n\t\tcombinedPartialLengths: PartialSequenceLengths,\n\t\tsegment: ISegmentPrivate,\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\tassertInserted(segment);\n\t\tif (segment.seq !== undefined && seqLTE(segment.seq, collabWindow.minSeq)) {\n\t\t\tcombinedPartialLengths.minLength += segment.cachedLength;\n\t\t\treturn;\n\t\t}\n\n\t\tconst isLocal = segment.seq === UnassignedSequenceNumber;\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst seqOrLocalSeq = isLocal ? segment.localSeq! : segment.seq;\n\t\tconst segmentLen = segment.cachedLength;\n\t\tconst clientId = segment.clientId;\n\n\t\tconst partials = isLocal\n\t\t\t? combinedPartialLengths.unsequencedRecords?.partialLengths\n\t\t\t: combinedPartialLengths.partialLengths;\n\t\tif (!partials) {\n\t\t\t// Local partial but its computation isn't required\n\t\t\treturn;\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: segmentLen,\n\t\t\t});\n\t\t} else {\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: segmentLen,\n\t\t\t});\n\t\t\tcombinedPartialLengths.addClientAdjustment(clientId, seqOrLocalSeq, segmentLen);\n\t\t}\n\t}\n\n\t/**\n\t * Inserts length information about the removal or obliteration of `segment` into\n\t * `combinedPartialLengths.partialLengths` and the appropriate per-client adjustments.\n\t */\n\tprivate static accountForRemoval(\n\t\tcombinedPartialLengths: PartialSequenceLengths,\n\t\tsegment: ISegmentPrivate,\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\tassertInserted(segment);\n\n\t\tconst removalInfo = toRemovalInfo(segment);\n\t\tconst moveInfo = toMoveInfo(segment);\n\t\tif (!removalInfo && !moveInfo) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\t(removalInfo?.removedSeq !== undefined &&\n\t\t\t\tseqLTE(removalInfo.removedSeq, collabWindow.minSeq)) ||\n\t\t\t(moveInfo?.movedSeq !== undefined && seqLTE(moveInfo.movedSeq, collabWindow.minSeq))\n\t\t) {\n\t\t\tcombinedPartialLengths.minLength -= segment.cachedLength;\n\t\t\treturn;\n\t\t}\n\n\t\tconst removalIsLocal =\n\t\t\t!!removalInfo && removalInfo.removedSeq === UnassignedSequenceNumber;\n\t\tconst moveIsLocal = !!moveInfo && moveInfo.movedSeq === UnassignedSequenceNumber;\n\t\tconst isLocalInsertion = segment.seq === UnassignedSequenceNumber;\n\t\tconst isOnlyLocalRemoval = removalIsLocal && (!moveInfo || moveIsLocal);\n\t\tconst isOnlyLocalMove = moveIsLocal && (!removalInfo || removalIsLocal);\n\t\tconst isLocal = isLocalInsertion || isOnlyLocalRemoval || isOnlyLocalMove;\n\n\t\tif (\n\t\t\tsegment.seq === UnassignedSequenceNumber &&\n\t\t\t!(removalIsLocal && (!moveInfo || moveIsLocal)) &&\n\t\t\t!(moveIsLocal && (!removalInfo || removalIsLocal))\n\t\t) {\n\t\t\tthrow new Error(\"Should have handled this codepath in wasMovedOnInsertion\");\n\t\t}\n\n\t\tconst lenDelta = -segment.cachedLength;\n\t\tlet clientId: number;\n\t\tlet seqOrLocalSeq: number;\n\n\t\t// it's not possible to have an overlapping obliterate and remove that are both local\n\t\tassert(\n\t\t\t(!moveIsLocal && !removalIsLocal) || moveIsLocal !== removalIsLocal,\n\t\t\t0x870 /* overlapping local obliterate and remove */,\n\t\t);\n\n\t\tconst clientsWithRemoveOrObliterate = new Set<number>([\n\t\t\t...(removalInfo?.removedClientIds ?? []),\n\t\t\t...(moveInfo?.movedClientIds ?? []),\n\t\t]);\n\n\t\tconst removeHappenedFirst =\n\t\t\tremovalInfo &&\n\t\t\t(!moveInfo ||\n\t\t\t\tmoveIsLocal ||\n\t\t\t\t(!removalIsLocal && moveInfo.movedSeq > removalInfo.removedSeq));\n\n\t\tif (removeHappenedFirst) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tseqOrLocalSeq = removalIsLocal ? removalInfo.localRemovedSeq! : removalInfo.removedSeq;\n\t\t\t// The client who performed the remove is always stored\n\t\t\t// in the first position of removalInfo.\n\t\t\tclientId = removalInfo.removedClientIds[0];\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tmoveInfo !== undefined,\n\t\t\t\t0xab9 /* Expected move to exist if remove either did not exist or didn't happen first */,\n\t\t\t);\n\t\t\t// The client who performed the move is always stored\n\t\t\t// in the first position of moveInfo.\n\t\t\tclientId = moveInfo.movedClientIds[0];\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tseqOrLocalSeq = moveIsLocal ? moveInfo.localMovedSeq! : moveInfo.movedSeq;\n\t\t}\n\n\t\tconst partials = isLocal\n\t\t\t? combinedPartialLengths.unsequencedRecords?.partialLengths\n\t\t\t: combinedPartialLengths.partialLengths;\n\t\tif (partials === undefined) {\n\t\t\t// Local partial but its computation isn't required\n\t\t\treturn;\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\t// The segment is either inserted only locally or removed/moved only locally.\n\t\t\t// We already accounted for the insertion in the accountForInsertion codepath.\n\t\t\t// Only thing left to do is account for the removal.\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: lenDelta,\n\t\t\t});\n\t\t} else {\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: lenDelta,\n\t\t\t});\n\n\t\t\tfor (const id of clientsWithRemoveOrObliterate) {\n\t\t\t\tif (id === collabWindow.clientId) {\n\t\t\t\t\t// The local client also removed or obliterated this segment.\n\t\t\t\t\tconst localSeq = moveInfo?.localMovedSeq ?? removalInfo?.localRemovedSeq;\n\t\t\t\t\tif (localSeq === undefined) {\n\t\t\t\t\t\t// Sure, the local client did it--but that change was already acked.\n\t\t\t\t\t\t// No need to account for it in the unsequenced records.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst { unsequencedRecords } = combinedPartialLengths;\n\t\t\t\t\tif (!unsequencedRecords) {\n\t\t\t\t\t\t// Local partial but its computation isn't required.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tassert(\n\t\t\t\t\t\tlocalSeq !== undefined,\n\t\t\t\t\t\t0xaba /* Local client was in move/removed client ids but segment has no local seq for either */,\n\t\t\t\t\t);\n\n\t\t\t\t\tunsequencedRecords.partialLengths.addOrUpdate({\n\t\t\t\t\t\tseq: localSeq,\n\t\t\t\t\t\tclientId: collabWindow.clientId,\n\t\t\t\t\t\tseglen: lenDelta,\n\t\t\t\t\t\tlen: 0,\n\t\t\t\t\t});\n\n\t\t\t\t\t// Because we've included deltas which take effect when either of localSeq or refSeq are high enough,\n\t\t\t\t\t// we need to offset this with an adjustment that takes effect when both are high enough.\n\t\t\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\t\t\trefSeq: seqOrLocalSeq,\n\t\t\t\t\t\tlocalSeq,\n\t\t\t\t\t\t// combinedPartialLengths.partialLengths has an entry removing this segment from a perspective >= seqOrLocalSeq.\n\t\t\t\t\t\t// combinedPartialLengths.unsequencedRecords.partialLengths now has an entry removing this segment from a perspective\n\t\t\t\t\t\t// with local seq >= `localSeq`.\n\t\t\t\t\t\t// In order to only remove this segment once, we add back in the length (where this entry only takes effect when\n\t\t\t\t\t\t// both above are true due to logic in computeOverallRefSeqAdjustment).\n\t\t\t\t\t\tseglen: segment.cachedLength,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Note that all clients that have a remove or obliterate operation on this segment\n\t\t\t\t\t// use the seq of the winning move/obliterate in their per-client adjustments!\n\t\t\t\t\tcombinedPartialLengths.addClientAdjustment(id, seqOrLocalSeq, lenDelta);\n\n\t\t\t\t\t// Also ensure that all these clients have seen the segment as inserted before being removed\n\t\t\t\t\t// This is technically not necessary for removes (we never ask for the length of this block with\n\t\t\t\t\t// respect to a refSeq which this entry would affect), but it's simpler to just add it here.\n\t\t\t\t\t// We already add this entry as part of the accountForInsertion codepath for the client that\n\t\t\t\t\t// actually did insert the segment, hence not doing so [again] here.\n\t\t\t\t\tif (segment.seq > collabWindow.minSeq && id !== segment.clientId) {\n\t\t\t\t\t\tcombinedPartialLengths.addClientAdjustment(id, segment.seq, segment.cachedLength);\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 * If incremental update of partial lengths fails, this gets set to the seq of the failed update.\n\t * When higher up blocks attempt to incrementally update, they first check if the seq they are updating for\n\t * matches this value. If it does, they propagate a full refresh instead.\n\t */\n\tprivate lastIncrementalInvalidationSeq = Number.NEGATIVE_INFINITY;\n\n\t// Assume: seq is latest sequence number; no structural change to sub-tree, but this partial lengths\n\t// entry needs to account for the change made by the client with `clientId` at sequence number `seq`.\n\t// (and `update` has been called on all descendant PartialSequenceLengths).\n\t// This implementation does not support overlapping removes: callers should recompute partial lengths\n\t// using `combine` when the change that has just been applied involves such an operation.\n\t// TODO: assert client id matches\n\tpublic update(\n\t\tnode: MergeBlock,\n\t\tseq: number,\n\t\tclientId: number,\n\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\t// In the current implementation, this method gets invoked multiple times for the same sequence number (i.e. mid-operation).\n\t\t// We counter this by first zeroing out existing entries from previous updates, but it isn't ideal.\n\t\t// Even if we fix this at the merge-tree level, the same type of issue can crop up with grouped batching enabled.\n\t\tconst latest = this.partialLengths.latestLeq(seq);\n\t\tif (latest?.seq === seq) {\n\t\t\tthis.partialLengths.addOrUpdate({ seq, len: 0, seglen: -latest.seglen, clientId });\n\t\t}\n\n\t\t// .forEach natively ignores undefined entries.\n\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\tthis.perClientAdjustments.forEach((clientAdjustments) => {\n\t\t\tconst leqPartial = clientAdjustments.latestLeq(seq);\n\t\t\tif (leqPartial && leqPartial.seq === seq) {\n\t\t\t\tthis.addClientAdjustment(clientId, seq, -leqPartial.seglen);\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * If any of the changes made by the client at `seq` necessitate partial length entries at sequence numbers other than `seq`,\n\t\t * this flag is set to true. This propagates upwards when aggregating parents as well.\n\t\t *\n\t\t * Note: it seems feasible to update parents more incrementally by tracking the changes made to child blocks for a given update.\n\t\t * There isn't a great place for this information to flow today.\n\t\t */\n\t\tlet failIncrementalPropagation = false;\n\n\t\tlet seqSeglen = 0;\n\t\tlet segCount = 0;\n\t\t// Compute length for seq across children\n\t\tfor (let i = 0; i < node.childCount; i++) {\n\t\t\tconst child = node.children[i];\n\t\t\tif (child.isLeaf()) {\n\t\t\t\tconst segment = child;\n\t\t\t\tconst removalInfo = toRemovalInfo(segment);\n\t\t\t\tconst moveInfo = toMoveInfo(segment);\n\t\t\t\tif (seq === segment.seq) {\n\t\t\t\t\t// if this segment was moved on insert, its length should\n\t\t\t\t\t// only be visible to the inserting client\n\t\t\t\t\tif (\n\t\t\t\t\t\tsegment.seq !== undefined &&\n\t\t\t\t\t\tmoveInfo &&\n\t\t\t\t\t\tmoveInfo.movedSeq < segment.seq &&\n\t\t\t\t\t\tmoveInfo.wasMovedOnInsert\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, moveInfo.movedSeq, segment.cachedLength);\n\t\t\t\t\t\tfailIncrementalPropagation = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tseqSeglen += segment.cachedLength;\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, seq, segment.cachedLength);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst earlierDeletion = Math.min(\n\t\t\t\t\tremovalInfo?.removedSeq ?? Number.MAX_VALUE,\n\t\t\t\t\tmoveInfo?.movedSeq ?? Number.MAX_VALUE,\n\t\t\t\t);\n\t\t\t\tif (segment.seq !== UnassignedSequenceNumber && seq === earlierDeletion) {\n\t\t\t\t\tseqSeglen -= segment.cachedLength;\n\t\t\t\t\tif (clientId !== collabWindow.clientId) {\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, seq, -segment.cachedLength);\n\t\t\t\t\t\tif (segment.seq > collabWindow.minSeq && segment.clientId !== clientId) {\n\t\t\t\t\t\t\tthis.addClientAdjustment(clientId, segment.seq, segment.cachedLength);\n\t\t\t\t\t\t\tfailIncrementalPropagation = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsegCount++;\n\t\t\t} else {\n\t\t\t\tconst childBlock = child;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst branchPartialLengths = childBlock.partialLengths!;\n\t\t\t\tif (branchPartialLengths.lastIncrementalInvalidationSeq === seq) {\n\t\t\t\t\t// Bail out.\n\t\t\t\t\tconst newPartials = PartialSequenceLengths.combine(node, collabWindow, false);\n\t\t\t\t\tnewPartials.lastIncrementalInvalidationSeq = seq;\n\t\t\t\t\tnode.partialLengths = newPartials;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst partialLengths = branchPartialLengths.partialLengths;\n\t\t\t\tconst leqPartial = partialLengths.latestLeq(seq);\n\t\t\t\tif (leqPartial && leqPartial.seq === seq) {\n\t\t\t\t\tseqSeglen += leqPartial.seglen;\n\t\t\t\t}\n\t\t\t\tsegCount += branchPartialLengths.segmentCount;\n\n\t\t\t\t// .forEach natively ignores undefined entries.\n\t\t\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\t\t\tbranchPartialLengths.perClientAdjustments.forEach((clientAdjustments) => {\n\t\t\t\t\tconst leqBranchPartial = clientAdjustments.latestLeq(seq);\n\t\t\t\t\tif (leqBranchPartial && leqBranchPartial.seq === seq) {\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, seq, leqBranchPartial.seglen);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (failIncrementalPropagation) {\n\t\t\tthis.lastIncrementalInvalidationSeq = seq;\n\t\t}\n\t\tthis.segmentCount = segCount;\n\t\tthis.unsequencedRecords = undefined;\n\t\tthis.partialLengths.addOrUpdate({ seq, seglen: seqSeglen, len: 0, clientId });\n\n\t\tif (PartialSequenceLengths.options.zamboni) {\n\t\t\tthis.zamboni(collabWindow);\n\t\t}\n\t\tPartialSequenceLengths.options.verifier?.(this);\n\t}\n\n\t/**\n\t * Returns the length of this block as viewed from the perspective of `clientId` at `refSeq`.\n\t * This is the total length of all segments sequenced at or before refSeq OR submitted by `clientId`.\n\t * If `clientId` is the local client, `localSeq` can also be provided. In that case, it is the total\n\t * length of all segments submitted at or before `refSeq` in addition to any local, unacked segments\n\t * with `segment.localSeq <= localSeq`.\n\t *\n\t * Note: the local case (where `localSeq !== undefined`) is only supported on a PartialSequenceLength object\n\t * constructed with `computeLocalPartials` set to true and not subsequently updated with `update`.\n\t */\n\tpublic getPartialLength(refSeq: number, clientId: number, localSeq?: number): number {\n\t\tlet length = this.minLength;\n\t\tlength += this.partialLengths.latestLeq(refSeq)?.len ?? 0;\n\n\t\tif (localSeq === undefined) {\n\t\t\tconst latestClientEntry = this.latestClientEntry(clientId);\n\t\t\tif (latestClientEntry !== undefined && latestClientEntry.seq > refSeq) {\n\t\t\t\t// The client has local edits after refSeq, add in the length adjustments\n\t\t\t\tlength += latestClientEntry.len;\n\t\t\t\tconst precedingCli = this.latestClientEntryLEQ(clientId, refSeq);\n\t\t\t\tif (precedingCli) {\n\t\t\t\t\t// Subtract out double-counted lengths: segments still in the collab window but before\n\t\t\t\t\t// the refSeq submitted by the client we're querying for were counted in each addition above.\n\t\t\t\t\tlength -= precedingCli.len;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tthis.unsequencedRecords !== undefined,\n\t\t\t\t0x39f /* Local getPartialLength invoked without computing local partials. */,\n\t\t\t);\n\t\t\tconst unsequencedPartialLengths = this.unsequencedRecords.partialLengths;\n\t\t\t// Local segments at or before localSeq should also be included\n\t\t\tconst local = unsequencedPartialLengths.latestLeq(localSeq);\n\t\t\tif (local) {\n\t\t\t\tlength += local.len;\n\n\t\t\t\t// Lastly, we must add in any additional adjustment due to double-counting removes and obliterations\n\t\t\t\t// removing local-only segments.\n\t\t\t\tlength += this.computeOverallRefSeqAdjustment(refSeq, localSeq);\n\t\t\t}\n\t\t}\n\t\treturn length;\n\t}\n\n\t/**\n\t * Computes the seglen for the double-counted removed overlap at (refSeq, localSeq).\n\t *\n\t * Reconnect happens to only need to compute these lengths for two refSeq values: before and\n\t * after the rebase. Since these lists potentially scale with O(collab window * number of local edits)\n\t * and potentially need to be queried for each local op that gets rebased,\n\t * we cache the results for a given refSeq in `this.unsequencedRecords.cachedOverlappingByRefSeq` so\n\t * that they can be binary-searched the same way the usual partialLengths lists are.\n\t */\n\tprivate computeOverallRefSeqAdjustment(refSeq: number, localSeq: number): number {\n\t\tif (this.unsequencedRecords === undefined) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tlet cachedAdjustment = this.unsequencedRecords.cachedAdjustmentByRefSeq.get(refSeq);\n\t\tif (!cachedAdjustment) {\n\t\t\tconst partials: PartialSequenceLengthsSet = new PartialSequenceLengthsSet();\n\t\t\tfor (const [\n\t\t\t\tseq,\n\t\t\t\tadjustments,\n\t\t\t] of this.unsequencedRecords.perRefSeqAdjustments.entries()) {\n\t\t\t\tif (seq > refSeq) {\n\t\t\t\t\t// TODO: Prior code path got away with an early exit here by sorting the entries by refSeq.\n\t\t\t\t\t// We could do the same here if we wanted.\n\t\t\t\t\t// Old codepath basically flattened the 2d array into a 1d array with both dimensions listed.\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfor (const partial of adjustments.items) {\n\t\t\t\t\t// This coalesces entries with the same localSeq as well as computes overall lengths.\n\t\t\t\t\tpartials.addOrUpdate({ ...partial });\n\t\t\t\t}\n\t\t\t}\n\t\t\tcachedAdjustment = partials;\n\t\t\tthis.unsequencedRecords.cachedAdjustmentByRefSeq.set(refSeq, cachedAdjustment);\n\t\t}\n\n\t\tconst overlap = cachedAdjustment.latestLeq(localSeq);\n\t\treturn overlap?.len ?? 0;\n\t}\n\n\tpublic toString(glc?: (id: number) => string, indentCount = 0): string {\n\t\tlet buf = \"\";\n\t\tfor (const partial of this.partialLengths.items) {\n\t\t\tbuf += `(${partial.seq},${partial.len}) `;\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-for-in-array, no-restricted-syntax\n\t\tfor (const clientId in this.perClientAdjustments) {\n\t\t\tif (this.perClientAdjustments[clientId].size > 0) {\n\t\t\t\tbuf += `Client `;\n\t\t\t\tbuf += glc ? `${glc(+clientId)}` : `${clientId}`;\n\t\t\t\tbuf += \"[\";\n\t\t\t\tfor (const partial of this.perClientAdjustments[clientId].items) {\n\t\t\t\t\tbuf += `(${partial.seq},${partial.len})`;\n\t\t\t\t}\n\t\t\t\tbuf += \"]\";\n\t\t\t}\n\t\t}\n\t\tbuf = `min(seq ${this.minSeq}): ${this.minLength}; sc: ${this.segmentCount};${buf}`;\n\t\treturn buf;\n\t}\n\n\t// Clear away partial sums for sequence numbers earlier than the current window\n\n\tprivate zamboni(segmentWindow: CollaborationWindow): void {\n\t\tthis.minLength += this.partialLengths.copyDown(segmentWindow.minSeq);\n\t\tthis.minSeq = segmentWindow.minSeq;\n\t\t// eslint-disable-next-line @typescript-eslint/no-for-in-array, guard-for-in, no-restricted-syntax\n\t\tfor (const clientId in this.perClientAdjustments) {\n\t\t\tconst cliPartials = this.perClientAdjustments[clientId];\n\t\t\tif (cliPartials) {\n\t\t\t\tcliPartials.copyDown(segmentWindow.minSeq);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addClientAdjustment(clientId: number, seq: number, seglen: number): void {\n\t\tthis.perClientAdjustments[clientId] ??= new PartialSequenceLengthsSet();\n\t\tconst cli = this.perClientAdjustments[clientId];\n\t\tcli.addOrUpdate({ seq, len: 0, seglen });\n\t}\n\n\tprivate addLocalAdjustment({\n\t\trefSeq,\n\t\tlocalSeq,\n\t\tseglen,\n\t}: { refSeq: number; localSeq: number; seglen: number }): void {\n\t\tassert(\n\t\t\tthis.unsequencedRecords !== undefined,\n\t\t\t0xabb /* Local adjustment computed without partials */,\n\t\t);\n\t\tconst adjustments =\n\t\t\tthis.unsequencedRecords.perRefSeqAdjustments.get(refSeq) ??\n\t\t\tnew PartialSequenceLengthsSet();\n\t\tthis.unsequencedRecords.perRefSeqAdjustments.set(refSeq, adjustments);\n\t\tadjustments.addOrUpdate({ seq: localSeq, len: 0, seglen });\n\t}\n\n\t/**\n\t * Returns the partial lengths associated with the latest change associated with `clientId` at or before `refSeq`.\n\t * Returns undefined if no such change exists.\n\t */\n\tprivate latestClientEntryLEQ(\n\t\tclientId: number,\n\t\trefSeq: number,\n\t): PartialSequenceLength | undefined {\n\t\treturn this.perClientAdjustments[clientId]?.latestLeq(refSeq);\n\t}\n\n\t/**\n\t * Get the partial lengths associated with the most recent change received by `clientId`, or undefined\n\t * if this client has made no changes in this block within the collab window.\n\t */\n\tprivate latestClientEntry(clientId: number): PartialSequenceLength | undefined {\n\t\tconst cliSeqs = this.perClientAdjustments[clientId];\n\t\treturn cliSeqs && cliSeqs.size > 0 ? cliSeqs.items[cliSeqs.size - 1] : undefined;\n\t}\n}\n\n/* eslint-disable @typescript-eslint/dot-notation */\nfunction verifyPartialLengthsInner(\n\tpartialSeqLengths: PartialSequenceLengths,\n\tpartialLengths: PartialSequenceLengthsSet,\n\tclientPartials: boolean,\n): number {\n\tif (partialLengths.size === 0) {\n\t\treturn 0;\n\t}\n\n\tlet lastSeqNum = 0;\n\tlet accumSegLen = 0;\n\tlet count = 0;\n\n\tfor (const partialLength of partialLengths.items) {\n\t\t// Count total number of partial length entries\n\t\tcount++;\n\n\t\t// Sequence number should be larger or equal to minseq\n\t\tassert(\n\t\t\tpartialSeqLengths.minSeq <= partialLength.seq,\n\t\t\t0x054 /* \"Sequence number less than minSeq!\" */,\n\t\t);\n\n\t\t// Sequence number should be sorted\n\t\tassert(lastSeqNum < partialLength.seq, 0x055 /* \"Sequence number is not sorted!\" */);\n\t\tlastSeqNum = partialLength.seq;\n\n\t\t// Len is a accumulation of all the seglen adjustments\n\t\taccumSegLen += partialLength.seglen;\n\t\tif (accumSegLen !== partialLength.len) {\n\t\t\tassert(\n\t\t\t\tfalse,\n\t\t\t\t0x056 /* \"Unexpected total for accumulation of all seglen adjustments!\" */,\n\t\t\t);\n\t\t}\n\n\t\tif (clientPartials) {\n\t\t\t// Client partials used to track local edits so we can account for them some refSeq.\n\t\t\t// But the information we keep track of are since minSeq, so we keep track of more history\n\t\t\t// then needed, and some of them doesn't make sense to be used for length calculations\n\t\t\t// e.g. if you have this sequence, where the minSeq is #5 because of other clients\n\t\t\t// seq 10: client 1: insert seg #1\n\t\t\t// seq 11: client 2: delete seg #2 refseq: 10\n\t\t\t// minLength is 0, we would have keep a record of seglen: -1 for clientPartialLengths for client 2\n\t\t\t// So if you ask for partial length for client 2 @ seq 5, we will have return -1.\n\t\t\t// However, that combination is invalid, since we should never see any ops with refseq < 10 for\n\t\t\t// client 2 after seq 11.\n\t\t} else {\n\t\t\t// Len adjustment should not make length negative\n\t\t\tif (partialSeqLengths[\"minLength\"] + partialLength.len < 0) {\n\t\t\t\tassert(false, 0x057 /* \"Negative length after length adjustment!\" */);\n\t\t\t}\n\t\t}\n\t}\n\treturn count;\n}\n\nexport function verifyExpectedPartialLengths(\n\tmergeTree: MergeTree,\n\tnode: MergeBlock,\n\trefSeq: number,\n\tclientId: number,\n\tlocalSeq?: number,\n): void {\n\tif (\n\t\t(!mergeTree.collabWindow.collaborating || mergeTree.collabWindow.clientId === clientId) &&\n\t\t(node.isLeaf() || localSeq === undefined)\n\t) {\n\t\treturn;\n\t}\n\n\tconst partialLen = node.partialLengths?.getPartialLength(refSeq, clientId, localSeq);\n\n\tlet expected = 0;\n\tconst nodesToVisit: IMergeNode[] = [node];\n\n\twhile (nodesToVisit.length > 0) {\n\t\tconst thisNode = nodesToVisit.pop();\n\t\tif (!thisNode) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (thisNode.isLeaf()) {\n\t\t\texpected += mergeTree[\"nodeLength\"](thisNode, refSeq, clientId, localSeq) ?? 0;\n\t\t} else {\n\t\t\tnodesToVisit.push(...thisNode.children.slice(0, thisNode.childCount));\n\t\t}\n\t}\n\n\tif (expected !== partialLen) {\n\t\tconst nonIncrementalPartials = PartialSequenceLengths.combine(\n\t\t\tnode,\n\t\t\tmergeTree.collabWindow,\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t);\n\t\tconst nonIncrementalLength = nonIncrementalPartials.getPartialLength(\n\t\t\trefSeq,\n\t\t\tclientId,\n\t\t\tlocalSeq,\n\t\t);\n\t\tnode.partialLengths?.getPartialLength(refSeq, clientId, localSeq);\n\n\t\tthrow new Error(\n\t\t\t`expected partial length of ${expected} but found ${partialLen}. refSeq: ${refSeq}, clientId: ${clientId}. (non-incremental codepath returned ${nonIncrementalLength})`,\n\t\t);\n\t}\n}\n\nexport function verifyPartialLengths(partialSeqLengths: PartialSequenceLengths): void {\n\tif (partialSeqLengths[\"perClientAdjustments\"]) {\n\t\tfor (const cliSeq of partialSeqLengths[\"perClientAdjustments\"]) {\n\t\t\tif (cliSeq) {\n\t\t\t\tverifyPartialLengthsInner(partialSeqLengths, cliSeq, true);\n\t\t\t}\n\t\t}\n\n\t\t// If we have client view, we should have the flat view\n\t\tassert(\n\t\t\t!!partialSeqLengths[\"partialLengths\"],\n\t\t\t0x059 /* \"Client view exists but flat view does not!\" */,\n\t\t);\n\n\t\tverifyPartialLengthsInner(partialSeqLengths, partialSeqLengths[\"partialLengths\"], false);\n\t} else {\n\t\t// If we don't have a client view, we shouldn't have the flat view either\n\t\tassert(\n\t\t\t!partialSeqLengths[\"partialLengths\"],\n\t\t\t0x05b /* \"Flat view exists but client view does not!\" */,\n\t\t);\n\t}\n}\n/* eslint-enable @typescript-eslint/dot-notation */\n\n/**\n * Given a number of seq-sorted `partialLength` lists, merges them into a combined seq-sorted `partialLength`\n * list. This merge includes coalescing `PartialSequenceLength` entries at the same seq.\n *\n * Ex: merging the following two lists (some information omitted on each PartialSequenceLength):\n * ```typescript\n * [{ seq: 1, seglen: 5 }, { seq: 3, seglen: -1 }]\n * [{ seq: 1, seglen: -3 }, { seq: 2: seglen: 4 }]\n * ```\n * would produce\n * ```typescript\n * [{ seq: 1, seglen: 2 }, { seq: 2, seglen: 4 }, { seq: 3, seglen: -1 }]\n * ```\n */\nfunction mergePartialLengths(\n\tchildPartialLengths: PartialSequenceLength[][],\n\tmergedLengths: PartialSequenceLengthsSet = new PartialSequenceLengthsSet(),\n): PartialSequenceLengthsSet {\n\tfor (const partialLength of mergeSortedListsBySeq(childPartialLengths)) {\n\t\tmergedLengths.addOrUpdate({\n\t\t\t...partialLength,\n\t\t});\n\t}\n\treturn mergedLengths;\n}\n\n/**\n * Given a collection of PartialSequenceLength lists--each sorted by sequence number--returns an iterable that yields\n * each PartialSequenceLength in sequence order.\n *\n * This is equivalent to flattening the input list and sorting it by sequence number. If the number of lists to merge is\n * a constant, however, this approach is advantageous asymptotically.\n */\nfunction mergeSortedListsBySeq<T extends PartialSequenceLength>(lists: T[][]): Iterable<T> {\n\tclass PartialSequenceLengthIterator {\n\t\t/**\n\t\t * nextSmallestIndex[i] is the next element of sublists[i] to check.\n\t\t * In other words, the iterator has already yielded elements of sublists[i] *up through*\n\t\t * sublists[i][nextSmallestIndex[i] - 1].\n\t\t */\n\t\tprivate readonly nextSmallestIndex: number[];\n\n\t\tconstructor(private readonly sublists: T[][]) {\n\t\t\tthis.nextSmallestIndex = Array.from({ length: sublists.length });\n\t\t\tfor (let i = 0; i < sublists.length; i++) {\n\t\t\t\tthis.nextSmallestIndex[i] = 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic next(): { value: T; done: false } | { value: undefined; done: true } {\n\t\t\tconst len = this.sublists.length;\n\t\t\tlet currentMin: T | undefined;\n\t\t\tlet currentMinIndex: number | undefined;\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\tconst candidateIndex = this.nextSmallestIndex[i];\n\t\t\t\tif (candidateIndex < this.sublists[i].length) {\n\t\t\t\t\tconst candidate = this.sublists[i][candidateIndex];\n\t\t\t\t\tif (!currentMin || candidate.seq < currentMin.seq) {\n\t\t\t\t\t\tcurrentMin = candidate;\n\t\t\t\t\t\tcurrentMinIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentMin) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tthis.nextSmallestIndex[currentMinIndex!]++;\n\t\t\t\treturn { value: currentMin, done: false };\n\t\t\t} else {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { [Symbol.iterator]: () => new PartialSequenceLengthIterator(lists) };\n}\n"]}
|
package/lib/perspective.d.ts
CHANGED
|
@@ -21,7 +21,8 @@ export interface SeqTime {
|
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* Implementation of {@link Perspective}.
|
|
24
|
-
*
|
|
24
|
+
* @privateRemarks
|
|
25
|
+
* TODO:AB#29765: This class does not support non-local-client perspectives, but should.
|
|
25
26
|
*/
|
|
26
27
|
export declare class PerspectiveImpl implements Perspective {
|
|
27
28
|
private readonly _mergeTree;
|
|
@@ -55,6 +56,8 @@ export declare class PerspectiveImpl implements Perspective {
|
|
|
55
56
|
* @param seq - The latest sequence number to consider.
|
|
56
57
|
* @param localSeq - The latest local sequence number to consider.
|
|
57
58
|
* @returns true iff this segment was removed in the given perspective.
|
|
59
|
+
* @privateRemarks
|
|
60
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
58
61
|
*/
|
|
59
62
|
export declare function wasRemovedBefore(seg: SegmentWithInfo<IInsertionInfo & IRemovalInfo>, { refSeq, localSeq }: SeqTime): boolean;
|
|
60
63
|
/**
|
|
@@ -63,10 +66,14 @@ export declare function wasRemovedBefore(seg: SegmentWithInfo<IInsertionInfo & I
|
|
|
63
66
|
* @param refSeq - The latest sequence number to consider.
|
|
64
67
|
* @param localSeq - The latest local sequence number to consider.
|
|
65
68
|
* @returns true iff this segment was moved (aka obliterated) in the given perspective.
|
|
69
|
+
* @privateRemarks
|
|
70
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
66
71
|
*/
|
|
67
72
|
export declare function wasMovedBefore(seg: SegmentWithInfo<IInsertionInfo & IMoveInfo>, { refSeq, localSeq }: SeqTime): boolean;
|
|
68
73
|
/**
|
|
69
74
|
* See {@link wasRemovedBefore} and {@link wasMovedBefore}.
|
|
75
|
+
* @privateRemarks
|
|
76
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
70
77
|
*/
|
|
71
78
|
export declare function wasRemovedOrMovedBefore(seg: ISegmentLeaf, seqTime: SeqTime): boolean;
|
|
72
79
|
/**
|
|
@@ -75,6 +82,8 @@ export declare function wasRemovedOrMovedBefore(seg: ISegmentLeaf, seqTime: SeqT
|
|
|
75
82
|
* @param seqTime - The latest sequence number and local sequence number to consider.
|
|
76
83
|
* @returns true iff this segment was inserted before the given perspective,
|
|
77
84
|
* and it was not removed or moved in the given perspective.
|
|
85
|
+
* @privateRemarks
|
|
86
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
78
87
|
*/
|
|
79
88
|
export declare function isSegmentPresent(seg: ISegmentLeaf, seqTime: SeqTime): boolean;
|
|
80
89
|
//# sourceMappingURL=perspective.d.ts.map
|
package/lib/perspective.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perspective.d.ts","sourceRoot":"","sources":["../src/perspective.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAIN,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;IACpE,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED
|
|
1
|
+
{"version":3,"file":"perspective.d.ts","sourceRoot":"","sources":["../src/perspective.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAIN,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;IACpE,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,WAAW;IAMjD,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAN1B;;;OAGG;gBAEe,UAAU,EAAE,SAAS,EACrB,QAAQ,EAAE,OAAO;IAGnC;;;;;;;;OAQG;IACI,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,GAAE,OAAc,GAAG,YAAY;IAYhF;;;;;OAKG;IACI,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY;CAG3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,eAAe,CAAC,cAAc,GAAG,YAAY,CAAC,EACnD,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,GAC3B,OAAO,CAST;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,eAAe,CAAC,cAAc,GAAG,SAAS,CAAC,EAChD,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,GAC3B,OAAO,CAST;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAMpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAsB7E"}
|
package/lib/perspective.js
CHANGED
|
@@ -8,7 +8,8 @@ import { seqLTE } from "./mergeTreeNodes.js";
|
|
|
8
8
|
import { isInserted, isMoved, isRemoved, } from "./segmentInfos.js";
|
|
9
9
|
/**
|
|
10
10
|
* Implementation of {@link Perspective}.
|
|
11
|
-
*
|
|
11
|
+
* @privateRemarks
|
|
12
|
+
* TODO:AB#29765: This class does not support non-local-client perspectives, but should.
|
|
12
13
|
*/
|
|
13
14
|
export class PerspectiveImpl {
|
|
14
15
|
/**
|
|
@@ -55,6 +56,8 @@ export class PerspectiveImpl {
|
|
|
55
56
|
* @param seq - The latest sequence number to consider.
|
|
56
57
|
* @param localSeq - The latest local sequence number to consider.
|
|
57
58
|
* @returns true iff this segment was removed in the given perspective.
|
|
59
|
+
* @privateRemarks
|
|
60
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
58
61
|
*/
|
|
59
62
|
export function wasRemovedBefore(seg, { refSeq, localSeq }) {
|
|
60
63
|
if (seg.removedSeq === UnassignedSequenceNumber &&
|
|
@@ -70,6 +73,8 @@ export function wasRemovedBefore(seg, { refSeq, localSeq }) {
|
|
|
70
73
|
* @param refSeq - The latest sequence number to consider.
|
|
71
74
|
* @param localSeq - The latest local sequence number to consider.
|
|
72
75
|
* @returns true iff this segment was moved (aka obliterated) in the given perspective.
|
|
76
|
+
* @privateRemarks
|
|
77
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
73
78
|
*/
|
|
74
79
|
export function wasMovedBefore(seg, { refSeq, localSeq }) {
|
|
75
80
|
if (seg.movedSeq === UnassignedSequenceNumber &&
|
|
@@ -81,6 +86,8 @@ export function wasMovedBefore(seg, { refSeq, localSeq }) {
|
|
|
81
86
|
}
|
|
82
87
|
/**
|
|
83
88
|
* See {@link wasRemovedBefore} and {@link wasMovedBefore}.
|
|
89
|
+
* @privateRemarks
|
|
90
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
84
91
|
*/
|
|
85
92
|
export function wasRemovedOrMovedBefore(seg, seqTime) {
|
|
86
93
|
return (isInserted(seg) &&
|
|
@@ -93,6 +100,8 @@ export function wasRemovedOrMovedBefore(seg, seqTime) {
|
|
|
93
100
|
* @param seqTime - The latest sequence number and local sequence number to consider.
|
|
94
101
|
* @returns true iff this segment was inserted before the given perspective,
|
|
95
102
|
* and it was not removed or moved in the given perspective.
|
|
103
|
+
* @privateRemarks
|
|
104
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
96
105
|
*/
|
|
97
106
|
export function isSegmentPresent(seg, seqTime) {
|
|
98
107
|
const { refSeq, localSeq } = seqTime;
|
package/lib/perspective.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perspective.js","sourceRoot":"","sources":["../src/perspective.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,MAAM,EAAqB,MAAM,qBAAqB,CAAC;AAChE,OAAO,EACN,UAAU,EACV,OAAO,EACP,SAAS,GAKT,MAAM,mBAAmB,CAAC;AAkB3B
|
|
1
|
+
{"version":3,"file":"perspective.js","sourceRoot":"","sources":["../src/perspective.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 { UnassignedSequenceNumber } from \"./constants.js\";\nimport { type MergeTree } from \"./mergeTree.js\";\nimport { LeafAction, backwardExcursion, forwardExcursion } from \"./mergeTreeNodeWalk.js\";\nimport { seqLTE, type ISegmentLeaf } from \"./mergeTreeNodes.js\";\nimport {\n\tisInserted,\n\tisMoved,\n\tisRemoved,\n\ttype IInsertionInfo,\n\ttype IMoveInfo,\n\ttype IRemovalInfo,\n\ttype SegmentWithInfo,\n} from \"./segmentInfos.js\";\n\n/**\n * Provides a view of a MergeTree from the perspective of a specific client at a specific sequence number.\n */\nexport interface Perspective {\n\tnextSegment(segment: ISegmentLeaf, forward?: boolean): ISegmentLeaf;\n\tpreviousSegment(segment: ISegmentLeaf): ISegmentLeaf;\n}\n\n/**\n * Represents a point in time inside the collaboration window.\n */\nexport interface SeqTime {\n\trefSeq: number;\n\tlocalSeq?: number;\n}\n\n/**\n * Implementation of {@link Perspective}.\n * @privateRemarks\n * TODO:AB#29765: This class does not support non-local-client perspectives, but should.\n */\nexport class PerspectiveImpl implements Perspective {\n\t/**\n\t * @param _mergeTree - The {@link MergeTree} to view.\n\t * @param _seqTime - The latest sequence number and local sequence number to consider.\n\t */\n\tpublic constructor(\n\t\tprivate readonly _mergeTree: MergeTree,\n\t\tprivate readonly _seqTime: SeqTime,\n\t) {}\n\n\t/**\n\t * Returns the immediately adjacent segment in the specified direction from this perspective.\n\t * There may actually be multiple segments between the given segment and the returned segment,\n\t * but they were either inserted after this perspective, or have been removed or moved before this perspective.\n\t *\n\t * @param segment - The segment to start from.\n\t * @param forward - The direction to search.\n\t * @returns the next segment in the specified direction, or the start or end of the tree if there is no next segment.\n\t */\n\tpublic nextSegment(segment: ISegmentLeaf, forward: boolean = true): ISegmentLeaf {\n\t\tlet next: ISegmentLeaf | undefined;\n\t\tconst action = (seg: ISegmentLeaf): boolean | undefined => {\n\t\t\tif (isSegmentPresent(seg, this._seqTime)) {\n\t\t\t\tnext = seg;\n\t\t\t\treturn LeafAction.Exit;\n\t\t\t}\n\t\t};\n\t\t(forward ? forwardExcursion : backwardExcursion)(segment, action);\n\t\treturn next ?? (forward ? this._mergeTree.endOfTree : this._mergeTree.startOfTree);\n\t}\n\n\t/**\n\t * Finds the segment prior to the given segment.\n\t * @param segment - The segment to start from.\n\t * @returns the previous segment, or the start of the tree if there is no previous segment.\n\t * @remarks This is a convenient equivalent to calling `nextSegment(segment, false)`.\n\t */\n\tpublic previousSegment(segment: ISegmentLeaf): ISegmentLeaf {\n\t\treturn this.nextSegment(segment, false);\n\t}\n}\n\n/**\n * Determines if the given segment was removed before the given perspective.\n * @param seg - The segment to check.\n * @param seq - The latest sequence number to consider.\n * @param localSeq - The latest local sequence number to consider.\n * @returns true iff this segment was removed in the given perspective.\n * @privateRemarks\n * TODO:AB#29765: This function does not support non-local-client perspectives, but should.\n */\nexport function wasRemovedBefore(\n\tseg: SegmentWithInfo<IInsertionInfo & IRemovalInfo>,\n\t{ refSeq, localSeq }: SeqTime,\n): boolean {\n\tif (\n\t\tseg.removedSeq === UnassignedSequenceNumber &&\n\t\tlocalSeq !== undefined &&\n\t\tseg.localRemovedSeq !== undefined\n\t) {\n\t\treturn seg.localRemovedSeq <= localSeq;\n\t}\n\treturn seg.removedSeq !== undefined && seqLTE(seg.removedSeq, refSeq);\n}\n\n/**\n * Determines if the given segment was moved before the given perspective.\n * @param seg - The segment to check.\n * @param refSeq - The latest sequence number to consider.\n * @param localSeq - The latest local sequence number to consider.\n * @returns true iff this segment was moved (aka obliterated) in the given perspective.\n * @privateRemarks\n * TODO:AB#29765: This function does not support non-local-client perspectives, but should.\n */\nexport function wasMovedBefore(\n\tseg: SegmentWithInfo<IInsertionInfo & IMoveInfo>,\n\t{ refSeq, localSeq }: SeqTime,\n): boolean {\n\tif (\n\t\tseg.movedSeq === UnassignedSequenceNumber &&\n\t\tlocalSeq !== undefined &&\n\t\tseg.localMovedSeq !== undefined\n\t) {\n\t\treturn seg.localMovedSeq <= localSeq;\n\t}\n\treturn seg.movedSeq !== undefined && seqLTE(seg.movedSeq, refSeq);\n}\n\n/**\n * See {@link wasRemovedBefore} and {@link wasMovedBefore}.\n * @privateRemarks\n * TODO:AB#29765: This function does not support non-local-client perspectives, but should.\n */\nexport function wasRemovedOrMovedBefore(seg: ISegmentLeaf, seqTime: SeqTime): boolean {\n\treturn (\n\t\tisInserted(seg) &&\n\t\t((isRemoved(seg) && wasRemovedBefore(seg, seqTime)) ||\n\t\t\t(isMoved(seg) && wasMovedBefore(seg, seqTime)))\n\t);\n}\n\n/**\n * Determines if the given segment is present in the given perspective.\n * @param seg - The segment to check.\n * @param seqTime - The latest sequence number and local sequence number to consider.\n * @returns true iff this segment was inserted before the given perspective,\n * and it was not removed or moved in the given perspective.\n * @privateRemarks\n * TODO:AB#29765: This function does not support non-local-client perspectives, but should.\n */\nexport function isSegmentPresent(seg: ISegmentLeaf, seqTime: SeqTime): boolean {\n\tconst { refSeq, localSeq } = seqTime;\n\t// If seg.seq is undefined, then this segment has existed since minSeq.\n\t// It may have been moved or removed since.\n\tif (isInserted(seg)) {\n\t\tif (seg.seq !== UnassignedSequenceNumber) {\n\t\t\tif (!seqLTE(seg.seq, refSeq)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if (\n\t\t\tseg.localSeq !== undefined && // seg.seq === UnassignedSequenceNumber\n\t\t\t// If the current perspective does not include local sequence numbers,\n\t\t\t// then this segment does not exist yet.\n\t\t\t(localSeq === undefined || seg.localSeq > localSeq)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t}\n\tif (wasRemovedOrMovedBefore(seg, seqTime)) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n"]}
|
package/lib/properties.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,WAAW,OAAO,CAAC,CAAC;IACzB,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;AAEvC;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,CAAC,EAAE,WAAW,GAAG,SAAS,EAC1B,CAAC,EAAE,WAAW,GAAG,SAAS,GACxB,OAAO,CA0BT;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,CAczF;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAMlF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,QAAQ,EAAE,WAAW,GACnB,WAAW,CAEb;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAClC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAChB,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAC/B,OAAO,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,MAAM,WAAW,OAAO,CAAC,CAAC;IACzB,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;AAEvC;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,CAAC,EAAE,WAAW,GAAG,SAAS,EAC1B,CAAC,EAAE,WAAW,GAAG,SAAS,GACxB,OAAO,CA0BT;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,CAczF;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAMlF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,QAAQ,EAAE,WAAW,GACnB,WAAW,CAEb;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAClC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAChB,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAC/B,OAAO,CAAC,CAAC,CAAC,CASZ;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAEzC"}
|
package/lib/properties.js
CHANGED
|
@@ -82,10 +82,9 @@ export function addProperties(oldProps, newProps) {
|
|
|
82
82
|
*/
|
|
83
83
|
export function extendIfUndefined(base, extension) {
|
|
84
84
|
if (extension !== undefined) {
|
|
85
|
-
|
|
86
|
-
for (const key in extension) {
|
|
85
|
+
for (const [key, value] of Object.entries(extension)) {
|
|
87
86
|
if (base[key] === undefined) {
|
|
88
|
-
base[key] =
|
|
87
|
+
base[key] = value;
|
|
89
88
|
}
|
|
90
89
|
}
|
|
91
90
|
}
|
package/lib/properties.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"properties.js","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAyBH;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC9B,CAA0B,EAC1B,CAA0B;IAE1B,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEtC,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACd,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC;QACd,CAAC;aAAM,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC;YACvC,iEAAiE;YACjE,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBACxC,OAAO,KAAK,CAAC;YACd,CAAC;QACF,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAI,IAAgB,EAAE,SAAiC;IAC5E,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7B,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;gBACrB,SAAS;YACV,CAAC;iBAAM,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;gBACvB,gEAAgE;gBAChE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACP,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACf,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAI,SAAiC;IACzD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,QAAQ,GAAG,SAAS,EAAK,CAAC;IAChC,OAAO,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC5B,QAAiC,EACjC,QAAqB;IAErB,OAAO,MAAM,CAAC,QAAQ,IAAI,SAAS,EAAW,EAAE,QAAQ,CAAC,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAChC,IAAgB,EAChB,SAAiC;IAEjC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7B,
|
|
1
|
+
{"version":3,"file":"properties.js","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Any mapping from a string to values of type `T`\n * @legacy\n * @alpha\n */\nexport interface MapLike<T> {\n\t[index: string]: T;\n}\n\n/**\n * A loosely-typed mapping from strings to any value.\n *\n * @remarks Property sets are expected to be JSON-stringify-able.\n *\n * @privateRemarks PropertySet is typed using `any` because when you include\n * custom methods such as toJSON(), JSON.stringify accepts most types other than\n * functions\n * @legacy\n * @alpha\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PropertySet = MapLike<any>;\n\n/**\n * Compares two PropertySets for equality.\n *\n * @internal\n */\nexport function matchProperties(\n\ta: PropertySet | undefined,\n\tb: PropertySet | undefined,\n): boolean {\n\tif (!a && !b) {\n\t\treturn true;\n\t}\n\n\tconst keysA = a ? Object.keys(a) : [];\n\tconst keysB = b ? Object.keys(b) : [];\n\n\tif (keysA.length !== keysB.length) {\n\t\treturn false;\n\t}\n\n\tfor (const key of keysA) {\n\t\tif (b?.[key] === undefined) {\n\t\t\treturn false;\n\t\t} else if (typeof b[key] === \"object\") {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tif (!matchProperties(a?.[key], b[key])) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if (b[key] !== a?.[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Adds properties from one PropertySet to another.\n *\n * @internal\n */\nexport function extend<T>(base: MapLike<T>, extension: MapLike<T> | undefined): MapLike<T> {\n\tif (extension !== undefined) {\n\t\tfor (const [key, v] of Object.entries(extension)) {\n\t\t\tif (v === undefined) {\n\t\t\t\tcontinue;\n\t\t\t} else if (v === null) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete base[key];\n\t\t\t} else {\n\t\t\t\tbase[key] = v;\n\t\t\t}\n\t\t}\n\t}\n\treturn base;\n}\n\n/**\n * Clones properties in a given PropertySet into a new PropertySet.\n *\n * @internal\n */\nexport function clone<T>(extension: MapLike<T> | undefined): MapLike<T> | undefined {\n\tif (extension === undefined) {\n\t\treturn undefined;\n\t}\n\tconst cloneMap = createMap<T>();\n\treturn extend(cloneMap, extension);\n}\n\n/**\n * Add properties in one PropertySet to another PropertySet. If the PropertySet we are adding\n * to does not exist, create one.\n *\n * @internal\n */\nexport function addProperties(\n\toldProps: PropertySet | undefined,\n\tnewProps: PropertySet,\n): PropertySet {\n\treturn extend(oldProps ?? createMap<unknown>(), newProps);\n}\n\n/**\n * Replace values of undefined in one PropertySet with values for the same key from another PropertySet.\n *\n * @internal\n */\nexport function extendIfUndefined<T>(\n\tbase: MapLike<T>,\n\textension: MapLike<T> | undefined,\n): MapLike<T> {\n\tif (extension !== undefined) {\n\t\tfor (const [key, value] of Object.entries(extension)) {\n\t\t\tif (base[key] === undefined) {\n\t\t\t\tbase[key] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn base;\n}\n\n/**\n * Create a MapLike with good performance.\n *\n * @internal\n */\nexport function createMap<T>(): MapLike<T> {\n\treturn Object.create(null) as MapLike<T>;\n}\n"]}
|