@fluidframework/merge-tree 2.23.0-323641 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/mergeTree.d.ts.map +1 -1
  3. package/dist/mergeTree.js +47 -15
  4. package/dist/mergeTree.js.map +1 -1
  5. package/dist/mergeTreeNodes.d.ts.map +1 -1
  6. package/dist/mergeTreeNodes.js +0 -2
  7. package/dist/mergeTreeNodes.js.map +1 -1
  8. package/dist/partialLengths.d.ts.map +1 -1
  9. package/dist/partialLengths.js +3 -4
  10. package/dist/partialLengths.js.map +1 -1
  11. package/dist/segmentInfos.d.ts +10 -18
  12. package/dist/segmentInfos.d.ts.map +1 -1
  13. package/dist/segmentInfos.js +22 -3
  14. package/dist/segmentInfos.js.map +1 -1
  15. package/dist/snapshotLoader.d.ts.map +1 -1
  16. package/dist/snapshotLoader.js +0 -2
  17. package/dist/snapshotLoader.js.map +1 -1
  18. package/dist/test/obliterate.concurrent.spec.js +53 -1
  19. package/dist/test/obliterate.concurrent.spec.js.map +1 -1
  20. package/lib/mergeTree.d.ts.map +1 -1
  21. package/lib/mergeTree.js +48 -16
  22. package/lib/mergeTree.js.map +1 -1
  23. package/lib/mergeTreeNodes.d.ts.map +1 -1
  24. package/lib/mergeTreeNodes.js +0 -2
  25. package/lib/mergeTreeNodes.js.map +1 -1
  26. package/lib/partialLengths.d.ts.map +1 -1
  27. package/lib/partialLengths.js +4 -5
  28. package/lib/partialLengths.js.map +1 -1
  29. package/lib/segmentInfos.d.ts +10 -18
  30. package/lib/segmentInfos.d.ts.map +1 -1
  31. package/lib/segmentInfos.js +20 -2
  32. package/lib/segmentInfos.js.map +1 -1
  33. package/lib/snapshotLoader.d.ts.map +1 -1
  34. package/lib/snapshotLoader.js +0 -2
  35. package/lib/snapshotLoader.js.map +1 -1
  36. package/lib/test/obliterate.concurrent.spec.js +53 -1
  37. package/lib/test/obliterate.concurrent.spec.js.map +1 -1
  38. package/package.json +17 -17
  39. package/src/mergeTree.ts +57 -15
  40. package/src/mergeTreeNodes.ts +0 -2
  41. package/src/partialLengths.ts +12 -5
  42. package/src/segmentInfos.ts +23 -21
  43. package/src/snapshotLoader.ts +0 -2
@@ -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 { 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"]}
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 {\n\ttoRemovalInfo,\n\ttoMoveInfo,\n\tassertInserted,\n\twasMovedOnInsert,\n} 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\tif (wasMovedOnInsert(segment)) {\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(\n\t\t\tmoveInfo !== undefined && wasMovedOnInsert(segment),\n\t\t\t0xab7 /* Segment was not moved on insert */,\n\t\t);\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\twasMovedOnInsert(segment)\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"]}
@@ -200,24 +200,6 @@ export interface IMoveInfo {
200
200
  * list have all issued concurrent ops to move the segment.
201
201
  */
202
202
  movedClientIds: number[];
203
- /**
204
- * If this segment was inserted into a concurrently moved range and
205
- * the move op was sequenced before the insertion op. In this case,
206
- * the segment is visible only to the inserting client
207
- *
208
- * `wasMovedOnInsert` only applies for acked obliterates. That is, if
209
- * a segment inserted by a remote client is moved on insertion by a local
210
- * and unacked obliterate, we do not consider it as having been moved
211
- * on insert
212
- *
213
- * If a segment is moved on insertion, its length is only ever visible to
214
- * the client that inserted the segment. This is relevant in partial length
215
- * calculations
216
- *
217
- * @privateRemarks
218
- * TODO:AB#29553: This property is not persisted in the summary, but it should be.
219
- */
220
- wasMovedOnInsert: boolean;
221
203
  }
222
204
  export declare const toMoveInfo: (segmentLike: unknown) => IMoveInfo | undefined;
223
205
  /**
@@ -228,6 +210,16 @@ export declare const toMoveInfo: (segmentLike: unknown) => IMoveInfo | undefined
228
210
  * @returns True if the segment has move info, otherwise false.
229
211
  */
230
212
  export declare const isMoved: (segmentLike: unknown) => segmentLike is IMoveInfo;
213
+ /**
214
+ * Returns whether this segment was marked moved as soon as its insertion was acked.
215
+ *
216
+ * This can happen when an an insert occurs concurrent to an obliterate over the range the segment was inserted into,
217
+ * and the obliterate was sequenced first.
218
+ *
219
+ * When this happens, the segment is only ever visible to the client that inserted the segment
220
+ * (and only until that client has seen the obliterate which removed their segment).
221
+ */
222
+ export declare function wasMovedOnInsert(segment: IInsertionInfo & ISegmentPrivate): boolean;
231
223
  /**
232
224
  * Asserts that the segment has move info. Usage of this function should not produce a user facing error.
233
225
  *
@@ -1 +1 @@
1
- {"version":3,"file":"segmentInfos.d.ts","sourceRoot":"","sources":["../src/segmentInfos.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,EAAE,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAC1C,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,CAAC,GACL,KAAK,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAE7B;AAED,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,YAAY,EACrE,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,CAAC,GACL,KAAK,IAAI,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,OAAO,IAAI,CAAC,CAAC,CAK/C;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EACjD,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAC7B,KAAK,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAEvB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,gBAAiB,OAAO,KAAG,cAAc,GAAG,SAG3D,CAAC;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,gBAAiB,OAAO,kCACJ,CAAC;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,CAAC,CAAC,SAAS,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,EAC1E,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,KACvD,OAAO,CAAC,WAAW,IAAI,cAAc,GAAG,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAM7E,CAAC;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,MAAM,EAAE,UAAU,CAAC;IAEnB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,aAAc,OAAO,KAAG,cAAc,GAAG,SAKxD,CAAC;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,aAAc,OAAO,+BACT,CAAC;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,CAAC,CAAC,SAAS,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,EAC3E,QAAQ,EAAE,gBAAgB,GAAG,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,KACtE,OAAO,CAAC,QAAQ,IAAI,cAAc,GAAG,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAM1E,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,QAAQ,IAAI,KAOjF,CAAC;AAEJ;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,gBAAiB,OAAO,KAAG,YAAY,GAAG,SAIvD,CAAC;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,gBAAiB,OAAO,gCACL,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,CAAC,CAAC,SAAS,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,EACvE,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,KACrD,OAAO,CAAC,WAAW,IAAI,YAAY,GAAG,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CACkB,CAAC;AAE9F;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,OAAO,CAAC,QAAQ,IAAI,KAO7E,CAAC;AAEJ;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACzB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAE5B;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IAEzB;;;;;;;;;;;;;;;;OAgBG;IACH,gBAAgB,EAAE,OAAO,CAAC;CAC1B;AACD,eAAO,MAAM,UAAU,gBAAiB,OAAO,KAAG,SAAS,GAAG,SAMjD,CAAC;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,gBAAiB,OAAO,6BACN,CAAC;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,CAAC,CAAC,SAAS,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,EAClE,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,KAClD,OAAO,CAAC,WAAW,IAAI,SAAS,GAAG,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CACmB,CAAC;AAEzF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,GAAG,SAAS,GAAG,YAAY,CAAC;AAErF;;GAEG;AACH,MAAM,MAAM,eAAe,CAC1B,CAAC,SAAS,WAAW,EACrB,CAAC,SAAS,eAAe,GAAG,eAAe,IACxC,CAAC,GAAG,CAAC,CAAC;AAEV;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,oFAIZ,CAAC,QACR,CAAC,KACL,gBAAgB,CAAC,EAAE,CAAC,CAAqC,CAAC"}
1
+ {"version":3,"file":"segmentInfos.d.ts","sourceRoot":"","sources":["../src/segmentInfos.ts"],"names":[],"mappings":"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"}
@@ -4,8 +4,9 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.overwriteInfo = exports.assertMoved = exports.isMoved = exports.toMoveInfo = exports.removeRemovalInfo = exports.assertRemoved = exports.isRemoved = exports.toRemovalInfo = exports.removeMergeNodeInfo = exports.assertMergeNode = exports.isMergeNodeInfo = exports.toMergeNodeInfo = exports.assertInserted = exports.isInserted = exports.toInsertionInfo = exports.propInstanceOf = exports.hasProp = exports.propExists = void 0;
7
+ exports.overwriteInfo = exports.assertMoved = exports.wasMovedOnInsert = exports.isMoved = exports.toMoveInfo = exports.removeRemovalInfo = exports.assertRemoved = exports.isRemoved = exports.toRemovalInfo = exports.removeMergeNodeInfo = exports.assertMergeNode = exports.isMergeNodeInfo = exports.toMergeNodeInfo = exports.assertInserted = exports.isInserted = exports.toInsertionInfo = exports.propInstanceOf = exports.hasProp = exports.propExists = void 0;
8
8
  const internal_1 = require("@fluidframework/core-utils/internal");
9
+ const constants_js_1 = require("./constants.js");
9
10
  const mergeTreeNodes_js_1 = require("./mergeTreeNodes.js");
10
11
  function propExists(thing, prop) {
11
12
  return (0, internal_1.isObject)(thing) && prop in thing;
@@ -132,8 +133,7 @@ const removeRemovalInfo = (nodeLike) => Object.assign(nodeLike, {
132
133
  exports.removeRemovalInfo = removeRemovalInfo;
133
134
  const toMoveInfo = (segmentLike) => hasProp(segmentLike, "movedClientIds", "array") &&
134
135
  hasProp(segmentLike, "movedSeq", "number") &&
135
- hasProp(segmentLike, "movedSeqs", "array") &&
136
- hasProp(segmentLike, "wasMovedOnInsert", "boolean")
136
+ hasProp(segmentLike, "movedSeqs", "array")
137
137
  ? segmentLike
138
138
  : undefined;
139
139
  exports.toMoveInfo = toMoveInfo;
@@ -146,6 +146,25 @@ exports.toMoveInfo = toMoveInfo;
146
146
  */
147
147
  const isMoved = (segmentLike) => (0, exports.toMoveInfo)(segmentLike) !== undefined;
148
148
  exports.isMoved = isMoved;
149
+ /**
150
+ * Returns whether this segment was marked moved as soon as its insertion was acked.
151
+ *
152
+ * This can happen when an an insert occurs concurrent to an obliterate over the range the segment was inserted into,
153
+ * and the obliterate was sequenced first.
154
+ *
155
+ * When this happens, the segment is only ever visible to the client that inserted the segment
156
+ * (and only until that client has seen the obliterate which removed their segment).
157
+ */
158
+ function wasMovedOnInsert(segment) {
159
+ const moveInfo = (0, exports.toMoveInfo)(segment);
160
+ const movedSeq = moveInfo?.movedSeq;
161
+ if (movedSeq === undefined || movedSeq === constants_js_1.UnassignedSequenceNumber) {
162
+ return false;
163
+ }
164
+ const insertSeq = segment.seq;
165
+ return insertSeq === constants_js_1.UnassignedSequenceNumber || insertSeq > movedSeq;
166
+ }
167
+ exports.wasMovedOnInsert = wasMovedOnInsert;
149
168
  /**
150
169
  * Asserts that the segment has move info. Usage of this function should not produce a user facing error.
151
170
  *
@@ -1 +1 @@
1
- {"version":3,"file":"segmentInfos.js","sourceRoot":"","sources":["../src/segmentInfos.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, isObject } from \"@fluidframework/core-utils/internal\";\n\nimport { ISegmentInternal, ISegmentPrivate, MergeBlock } from \"./mergeTreeNodes.js\";\nimport type { ReferencePosition } from \"./referencePositions.js\";\n\nexport interface StringToType {\n\t\"string\": string;\n\t\"number\": number;\n\t\"object\": object;\n\t\"array\": [];\n\t\"boolean\": boolean;\n}\n\nexport function propExists<P extends string>(\n\tthing: unknown,\n\tprop: P,\n): thing is Record<P, unknown> {\n\treturn isObject(thing) && prop in thing;\n}\n\nexport function hasProp<P extends string, T extends keyof StringToType>(\n\tthing: unknown,\n\tprop: P,\n\ttype: T,\n): thing is Record<P, StringToType[typeof type]> {\n\treturn (\n\t\tpropExists(thing, prop) &&\n\t\t(type === \"array\" ? Array.isArray(thing[prop]) : typeof thing[prop] === type)\n\t);\n}\n\nexport function propInstanceOf<P extends string, T>(\n\tthing: unknown,\n\tprop: P,\n\ttype: new (...args: any[]) => T,\n): thing is Record<P, T> {\n\treturn propExists(thing, prop) && thing[prop] instanceof type;\n}\n\n/**\n * Contains insertion information associated to an {@link ISegment}.\n */\nexport interface IInsertionInfo {\n\t/**\n\t * Short clientId for the client that inserted this segment.\n\t */\n\tclientId: number;\n\t/**\n\t * Local seq at which this segment was inserted.\n\t * This is defined if and only if the insertion of the segment is pending ack, i.e. `seq` is UnassignedSequenceNumber.\n\t * Once the segment is acked, this field is cleared.\n\t *\n\t * @privateRemarks\n\t * See {@link CollaborationWindow.localSeq} for more information on the semantics of localSeq.\n\t */\n\tlocalSeq?: number;\n\t/**\n\t * Seq at which this segment was inserted.\n\t * If undefined, it is assumed the segment was inserted prior to the collab window's minimum sequence number.\n\t */\n\tseq: number;\n}\n\n/**\n * Converts a segment-like object to an insertion info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The insertion info object if the conversion is possible, otherwise undefined.\n */\nexport const toInsertionInfo = (segmentLike: unknown): IInsertionInfo | undefined =>\n\thasProp(segmentLike, \"clientId\", \"number\") && hasProp(segmentLike, \"seq\", \"number\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has insertion info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has insertion info, otherwise false.\n */\nexport const isInserted = (segmentLike: unknown): segmentLike is IInsertionInfo =>\n\ttoInsertionInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has insertion info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have insertion info.\n */\nexport const assertInserted: <T extends Partial<IInsertionInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IInsertionInfo> | T,\n) => asserts segmentLike is IInsertionInfo | Exclude<T, Partial<IInsertionInfo>> = (\n\tsegmentLike,\n) =>\n\tassert(\n\t\tsegmentLike === undefined || isInserted(segmentLike),\n\t\t0xaa0 /* must be insertionInfo */,\n\t);\n\n/**\n * Common properties for a node in a merge tree.\n */\nexport interface IMergeNodeInfo {\n\t/**\n\t * The parent merge block if the node is parented\n\t */\n\tparent: MergeBlock;\n\n\t/**\n\t * The index of this node in its parent's list of children.\n\t */\n\tindex: number;\n\n\t/**\n\t * A string that can be used for comparing the location of this node to other `MergeNode`s in the same tree.\n\t * `a.ordinal < b.ordinal` if and only if `a` comes before `b` in a pre-order traversal of the tree.\n\t */\n\tordinal: string;\n}\n\n/**\n * Converts a segment-like object to a merge node info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The merge node info object if the conversion is possible, otherwise undefined.\n */\nexport const toMergeNodeInfo = (nodeLike: unknown): IMergeNodeInfo | undefined =>\n\tpropInstanceOf(nodeLike, \"parent\", MergeBlock) &&\n\thasProp(nodeLike, \"ordinal\", \"string\") &&\n\thasProp(nodeLike, \"index\", \"number\")\n\t\t? nodeLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has merge node info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param nodeLike - The segment-like object to check.\n * @returns True if the segment has merge node info, otherwise false.\n */\nexport const isMergeNodeInfo = (nodeLike: unknown): nodeLike is IMergeNodeInfo =>\n\ttoMergeNodeInfo(nodeLike) !== undefined;\n\n/**\n * Asserts that the segment has merge node info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have merge node info.\n */\nexport const assertMergeNode: <T extends Partial<IMergeNodeInfo> | undefined>(\n\tnodeLike: ISegmentInternal | ISegmentPrivate | Partial<IMergeNodeInfo> | T,\n) => asserts nodeLike is IMergeNodeInfo | Exclude<T, Partial<IMergeNodeInfo>> = (\n\tsegmentLike,\n) =>\n\tassert(\n\t\tsegmentLike === undefined || isMergeNodeInfo(segmentLike),\n\t\t0xaa1 /* must be MergeNodeInfo */,\n\t);\n\n/**\n * Removes the merge node info. This is used to remove nodes from the merge-tree.\n * @param segmentLike - The segment-like object to check.\n * @returns This function will change the type of the provided node like to never via an assertion. This\n * ensures no further usage of the removed merge node info is allowed. if continued use is required other\n * type coercion methods should be used to correctly re-type the variable.\n */\nexport const removeMergeNodeInfo: (nodeLike: IMergeNodeInfo) => asserts nodeLike is never = (\n\tnodeLike,\n) =>\n\tObject.assign<IMergeNodeInfo, Record<keyof IMergeNodeInfo, undefined>>(nodeLike, {\n\t\tparent: undefined,\n\t\tindex: undefined,\n\t\tordinal: undefined,\n\t});\n\n/**\n * Contains removal information associated to an {@link ISegment}.\n */\nexport interface IRemovalInfo {\n\t/**\n\t * Local seq at which this segment was removed, if the removal is yet-to-be acked.\n\t */\n\tlocalRemovedSeq?: number;\n\t/**\n\t * Seq at which this segment was removed.\n\t */\n\tremovedSeq: number;\n\t/**\n\t * List of client IDs that have removed this segment.\n\t * The client that actually removed the segment (i.e. whose removal op was sequenced first) is stored as the first\n\t * client in this list. Other clients in the list have all issued concurrent ops to remove the segment.\n\t * @remarks When this list has length \\> 1, this is referred to as the \"overlapping remove\" case.\n\t */\n\tremovedClientIds: number[];\n}\n\n/**\n * Converts a segment-like object to a removal info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The removal info object if the conversion is possible, otherwise undefined.\n */\nexport const toRemovalInfo = (segmentLike: unknown): IRemovalInfo | undefined =>\n\thasProp(segmentLike, \"removedClientIds\", \"array\") &&\n\thasProp(segmentLike, \"removedSeq\", \"number\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has removal info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has removal info, otherwise false.\n */\nexport const isRemoved = (segmentLike: unknown): segmentLike is IRemovalInfo =>\n\ttoRemovalInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has removal info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have removal info.\n */\nexport const assertRemoved: <T extends Partial<IRemovalInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IRemovalInfo> | T,\n) => asserts segmentLike is IRemovalInfo | Exclude<T, Partial<IRemovalInfo>> = (segmentLike) =>\n\tassert(segmentLike === undefined || isRemoved(segmentLike), 0xaa2 /* must be removalInfo */);\n\n/**\n * Removes the removal info. This is used in rollback.\n * @param segmentLike - The segment-like object to check.\n * @returns This function will change the type of the provided node like to never via an assertion. This\n * ensures no further usage of the removed removal info is allowed. if continued use is required other\n * type coercion methods should be use to correctly re-type the variable.\n */\nexport const removeRemovalInfo: (nodeLike: IRemovalInfo) => asserts nodeLike is never = (\n\tnodeLike,\n) =>\n\tObject.assign<IRemovalInfo, Record<keyof IRemovalInfo, undefined>>(nodeLike, {\n\t\tlocalRemovedSeq: undefined,\n\t\tremovedClientIds: undefined,\n\t\tremovedSeq: undefined,\n\t});\n\n/**\n * Tracks information about when and where this segment was moved to.\n *\n * Note that merge-tree does not currently support moving and only supports\n * obliterate. The fields below include \"move\" in their names to avoid renaming\n * in the future, when moves _are_ supported.\n */\nexport interface IMoveInfo {\n\t/**\n\t * Local seq at which this segment was moved if the move is yet-to-be\n\t * acked.\n\t */\n\tlocalMovedSeq?: number;\n\n\t/**\n\t * The first seq at which this segment was moved.\n\t */\n\tmovedSeq: number;\n\n\t/**\n\t * All seqs at which this segment was moved. In the case of overlapping,\n\t * concurrent moves this array will contain multiple seqs.\n\t *\n\t * The seq at `movedSeqs[i]` corresponds to the client id at `movedClientIds[i]`.\n\t *\n\t * The first element corresponds to the seq of the first move\n\t */\n\tmovedSeqs: number[];\n\n\t/**\n\t * A reference to the inserted destination segment corresponding to this\n\t * segment's move.\n\t *\n\t * If undefined, the move was an obliterate.\n\t *\n\t * Currently this field is unused, as we only support obliterate operations\n\t */\n\tmoveDst?: ReferencePosition;\n\n\t/**\n\t * List of client IDs that have moved this segment.\n\t *\n\t * The client that actually moved the segment (i.e. whose move op was sequenced\n\t * first) is stored as the first client in this list. Other clients in the\n\t * list have all issued concurrent ops to move the segment.\n\t */\n\tmovedClientIds: number[];\n\n\t/**\n\t * If this segment was inserted into a concurrently moved range and\n\t * the move op was sequenced before the insertion op. In this case,\n\t * the segment is visible only to the inserting client\n\t *\n\t * `wasMovedOnInsert` only applies for acked obliterates. That is, if\n\t * a segment inserted by a remote client is moved on insertion by a local\n\t * and unacked obliterate, we do not consider it as having been moved\n\t * on insert\n\t *\n\t * If a segment is moved on insertion, its length is only ever visible to\n\t * the client that inserted the segment. This is relevant in partial length\n\t * calculations\n\t *\n\t * @privateRemarks\n\t * TODO:AB#29553: This property is not persisted in the summary, but it should be.\n\t */\n\twasMovedOnInsert: boolean;\n}\nexport const toMoveInfo = (segmentLike: unknown): IMoveInfo | undefined =>\n\thasProp(segmentLike, \"movedClientIds\", \"array\") &&\n\thasProp(segmentLike, \"movedSeq\", \"number\") &&\n\thasProp(segmentLike, \"movedSeqs\", \"array\") &&\n\thasProp(segmentLike, \"wasMovedOnInsert\", \"boolean\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has move info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has move info, otherwise false.\n */\nexport const isMoved = (segmentLike: unknown): segmentLike is IMoveInfo =>\n\ttoMoveInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has move info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have move info.\n */\nexport const assertMoved: <T extends Partial<IMoveInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IMoveInfo> | T,\n) => asserts segmentLike is IMoveInfo | Exclude<T, Partial<IMoveInfo>> = (segmentLike) =>\n\tassert(segmentLike === undefined || isMoved(segmentLike), 0xaa3 /* must be moveInfo */);\n\n/**\n * A union type representing any segment info.\n */\nexport type SegmentInfo = IMergeNodeInfo | IInsertionInfo | IMoveInfo | IRemovalInfo;\n\n/**\n * A type representing a segment with additional info.\n */\nexport type SegmentWithInfo<\n\tT extends SegmentInfo,\n\tS extends ISegmentPrivate = ISegmentPrivate,\n> = S & T;\n\n/**\n * Overwrites the segment info on a segment-like object.\n *\n * @param segmentLike - The segment-like object to set the info on.\n * @param info - The segment info to overwrite.\n * @returns The segment-like object with the info set.\n */\nexport const overwriteInfo = <\n\tT extends SegmentInfo,\n\tS extends ISegmentPrivate = ISegmentPrivate,\n>(\n\tsegmentLike: S,\n\tinfo: T,\n): SegmentWithInfo<T, S> => Object.assign(segmentLike, info);\n"]}
1
+ {"version":3,"file":"segmentInfos.js","sourceRoot":"","sources":["../src/segmentInfos.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, isObject } from \"@fluidframework/core-utils/internal\";\n\nimport { UnassignedSequenceNumber } from \"./constants.js\";\nimport { ISegmentInternal, ISegmentPrivate, MergeBlock } from \"./mergeTreeNodes.js\";\nimport type { ReferencePosition } from \"./referencePositions.js\";\n\nexport interface StringToType {\n\t\"string\": string;\n\t\"number\": number;\n\t\"object\": object;\n\t\"array\": [];\n\t\"boolean\": boolean;\n}\n\nexport function propExists<P extends string>(\n\tthing: unknown,\n\tprop: P,\n): thing is Record<P, unknown> {\n\treturn isObject(thing) && prop in thing;\n}\n\nexport function hasProp<P extends string, T extends keyof StringToType>(\n\tthing: unknown,\n\tprop: P,\n\ttype: T,\n): thing is Record<P, StringToType[typeof type]> {\n\treturn (\n\t\tpropExists(thing, prop) &&\n\t\t(type === \"array\" ? Array.isArray(thing[prop]) : typeof thing[prop] === type)\n\t);\n}\n\nexport function propInstanceOf<P extends string, T>(\n\tthing: unknown,\n\tprop: P,\n\ttype: new (...args: any[]) => T,\n): thing is Record<P, T> {\n\treturn propExists(thing, prop) && thing[prop] instanceof type;\n}\n\n/**\n * Contains insertion information associated to an {@link ISegment}.\n */\nexport interface IInsertionInfo {\n\t/**\n\t * Short clientId for the client that inserted this segment.\n\t */\n\tclientId: number;\n\t/**\n\t * Local seq at which this segment was inserted.\n\t * This is defined if and only if the insertion of the segment is pending ack, i.e. `seq` is UnassignedSequenceNumber.\n\t * Once the segment is acked, this field is cleared.\n\t *\n\t * @privateRemarks\n\t * See {@link CollaborationWindow.localSeq} for more information on the semantics of localSeq.\n\t */\n\tlocalSeq?: number;\n\t/**\n\t * Seq at which this segment was inserted.\n\t * If undefined, it is assumed the segment was inserted prior to the collab window's minimum sequence number.\n\t */\n\tseq: number;\n}\n\n/**\n * Converts a segment-like object to an insertion info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The insertion info object if the conversion is possible, otherwise undefined.\n */\nexport const toInsertionInfo = (segmentLike: unknown): IInsertionInfo | undefined =>\n\thasProp(segmentLike, \"clientId\", \"number\") && hasProp(segmentLike, \"seq\", \"number\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has insertion info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has insertion info, otherwise false.\n */\nexport const isInserted = (segmentLike: unknown): segmentLike is IInsertionInfo =>\n\ttoInsertionInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has insertion info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have insertion info.\n */\nexport const assertInserted: <T extends Partial<IInsertionInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IInsertionInfo> | T,\n) => asserts segmentLike is IInsertionInfo | Exclude<T, Partial<IInsertionInfo>> = (\n\tsegmentLike,\n) =>\n\tassert(\n\t\tsegmentLike === undefined || isInserted(segmentLike),\n\t\t0xaa0 /* must be insertionInfo */,\n\t);\n\n/**\n * Common properties for a node in a merge tree.\n */\nexport interface IMergeNodeInfo {\n\t/**\n\t * The parent merge block if the node is parented\n\t */\n\tparent: MergeBlock;\n\n\t/**\n\t * The index of this node in its parent's list of children.\n\t */\n\tindex: number;\n\n\t/**\n\t * A string that can be used for comparing the location of this node to other `MergeNode`s in the same tree.\n\t * `a.ordinal < b.ordinal` if and only if `a` comes before `b` in a pre-order traversal of the tree.\n\t */\n\tordinal: string;\n}\n\n/**\n * Converts a segment-like object to a merge node info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The merge node info object if the conversion is possible, otherwise undefined.\n */\nexport const toMergeNodeInfo = (nodeLike: unknown): IMergeNodeInfo | undefined =>\n\tpropInstanceOf(nodeLike, \"parent\", MergeBlock) &&\n\thasProp(nodeLike, \"ordinal\", \"string\") &&\n\thasProp(nodeLike, \"index\", \"number\")\n\t\t? nodeLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has merge node info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param nodeLike - The segment-like object to check.\n * @returns True if the segment has merge node info, otherwise false.\n */\nexport const isMergeNodeInfo = (nodeLike: unknown): nodeLike is IMergeNodeInfo =>\n\ttoMergeNodeInfo(nodeLike) !== undefined;\n\n/**\n * Asserts that the segment has merge node info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have merge node info.\n */\nexport const assertMergeNode: <T extends Partial<IMergeNodeInfo> | undefined>(\n\tnodeLike: ISegmentInternal | ISegmentPrivate | Partial<IMergeNodeInfo> | T,\n) => asserts nodeLike is IMergeNodeInfo | Exclude<T, Partial<IMergeNodeInfo>> = (\n\tsegmentLike,\n) =>\n\tassert(\n\t\tsegmentLike === undefined || isMergeNodeInfo(segmentLike),\n\t\t0xaa1 /* must be MergeNodeInfo */,\n\t);\n\n/**\n * Removes the merge node info. This is used to remove nodes from the merge-tree.\n * @param segmentLike - The segment-like object to check.\n * @returns This function will change the type of the provided node like to never via an assertion. This\n * ensures no further usage of the removed merge node info is allowed. if continued use is required other\n * type coercion methods should be used to correctly re-type the variable.\n */\nexport const removeMergeNodeInfo: (nodeLike: IMergeNodeInfo) => asserts nodeLike is never = (\n\tnodeLike,\n) =>\n\tObject.assign<IMergeNodeInfo, Record<keyof IMergeNodeInfo, undefined>>(nodeLike, {\n\t\tparent: undefined,\n\t\tindex: undefined,\n\t\tordinal: undefined,\n\t});\n\n/**\n * Contains removal information associated to an {@link ISegment}.\n */\nexport interface IRemovalInfo {\n\t/**\n\t * Local seq at which this segment was removed, if the removal is yet-to-be acked.\n\t */\n\tlocalRemovedSeq?: number;\n\t/**\n\t * Seq at which this segment was removed.\n\t */\n\tremovedSeq: number;\n\t/**\n\t * List of client IDs that have removed this segment.\n\t * The client that actually removed the segment (i.e. whose removal op was sequenced first) is stored as the first\n\t * client in this list. Other clients in the list have all issued concurrent ops to remove the segment.\n\t * @remarks When this list has length \\> 1, this is referred to as the \"overlapping remove\" case.\n\t */\n\tremovedClientIds: number[];\n}\n\n/**\n * Converts a segment-like object to a removal info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The removal info object if the conversion is possible, otherwise undefined.\n */\nexport const toRemovalInfo = (segmentLike: unknown): IRemovalInfo | undefined =>\n\thasProp(segmentLike, \"removedClientIds\", \"array\") &&\n\thasProp(segmentLike, \"removedSeq\", \"number\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has removal info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has removal info, otherwise false.\n */\nexport const isRemoved = (segmentLike: unknown): segmentLike is IRemovalInfo =>\n\ttoRemovalInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has removal info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have removal info.\n */\nexport const assertRemoved: <T extends Partial<IRemovalInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IRemovalInfo> | T,\n) => asserts segmentLike is IRemovalInfo | Exclude<T, Partial<IRemovalInfo>> = (segmentLike) =>\n\tassert(segmentLike === undefined || isRemoved(segmentLike), 0xaa2 /* must be removalInfo */);\n\n/**\n * Removes the removal info. This is used in rollback.\n * @param segmentLike - The segment-like object to check.\n * @returns This function will change the type of the provided node like to never via an assertion. This\n * ensures no further usage of the removed removal info is allowed. if continued use is required other\n * type coercion methods should be use to correctly re-type the variable.\n */\nexport const removeRemovalInfo: (nodeLike: IRemovalInfo) => asserts nodeLike is never = (\n\tnodeLike,\n) =>\n\tObject.assign<IRemovalInfo, Record<keyof IRemovalInfo, undefined>>(nodeLike, {\n\t\tlocalRemovedSeq: undefined,\n\t\tremovedClientIds: undefined,\n\t\tremovedSeq: undefined,\n\t});\n\n/**\n * Tracks information about when and where this segment was moved to.\n *\n * Note that merge-tree does not currently support moving and only supports\n * obliterate. The fields below include \"move\" in their names to avoid renaming\n * in the future, when moves _are_ supported.\n */\nexport interface IMoveInfo {\n\t/**\n\t * Local seq at which this segment was moved if the move is yet-to-be\n\t * acked.\n\t */\n\tlocalMovedSeq?: number;\n\n\t/**\n\t * The first seq at which this segment was moved.\n\t */\n\tmovedSeq: number;\n\n\t/**\n\t * All seqs at which this segment was moved. In the case of overlapping,\n\t * concurrent moves this array will contain multiple seqs.\n\t *\n\t * The seq at `movedSeqs[i]` corresponds to the client id at `movedClientIds[i]`.\n\t *\n\t * The first element corresponds to the seq of the first move\n\t */\n\tmovedSeqs: number[];\n\n\t/**\n\t * A reference to the inserted destination segment corresponding to this\n\t * segment's move.\n\t *\n\t * If undefined, the move was an obliterate.\n\t *\n\t * Currently this field is unused, as we only support obliterate operations\n\t */\n\tmoveDst?: ReferencePosition;\n\n\t/**\n\t * List of client IDs that have moved this segment.\n\t *\n\t * The client that actually moved the segment (i.e. whose move op was sequenced\n\t * first) is stored as the first client in this list. Other clients in the\n\t * list have all issued concurrent ops to move the segment.\n\t */\n\tmovedClientIds: number[];\n}\n\nexport const toMoveInfo = (segmentLike: unknown): IMoveInfo | undefined =>\n\thasProp(segmentLike, \"movedClientIds\", \"array\") &&\n\thasProp(segmentLike, \"movedSeq\", \"number\") &&\n\thasProp(segmentLike, \"movedSeqs\", \"array\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has move info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has move info, otherwise false.\n */\nexport const isMoved = (segmentLike: unknown): segmentLike is IMoveInfo =>\n\ttoMoveInfo(segmentLike) !== undefined;\n\n/**\n * Returns whether this segment was marked moved as soon as its insertion was acked.\n *\n * This can happen when an an insert occurs concurrent to an obliterate over the range the segment was inserted into,\n * and the obliterate was sequenced first.\n *\n * When this happens, the segment is only ever visible to the client that inserted the segment\n * (and only until that client has seen the obliterate which removed their segment).\n */\nexport function wasMovedOnInsert(segment: IInsertionInfo & ISegmentPrivate): boolean {\n\tconst moveInfo = toMoveInfo(segment);\n\tconst movedSeq = moveInfo?.movedSeq;\n\tif (movedSeq === undefined || movedSeq === UnassignedSequenceNumber) {\n\t\treturn false;\n\t}\n\n\tconst insertSeq = segment.seq;\n\treturn insertSeq === UnassignedSequenceNumber || insertSeq > movedSeq;\n}\n\n/**\n * Asserts that the segment has move info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have move info.\n */\nexport const assertMoved: <T extends Partial<IMoveInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IMoveInfo> | T,\n) => asserts segmentLike is IMoveInfo | Exclude<T, Partial<IMoveInfo>> = (segmentLike) =>\n\tassert(segmentLike === undefined || isMoved(segmentLike), 0xaa3 /* must be moveInfo */);\n\n/**\n * A union type representing any segment info.\n */\nexport type SegmentInfo = IMergeNodeInfo | IInsertionInfo | IMoveInfo | IRemovalInfo;\n\n/**\n * A type representing a segment with additional info.\n */\nexport type SegmentWithInfo<\n\tT extends SegmentInfo,\n\tS extends ISegmentPrivate = ISegmentPrivate,\n> = S & T;\n\n/**\n * Overwrites the segment info on a segment-like object.\n *\n * @param segmentLike - The segment-like object to set the info on.\n * @param info - The segment info to overwrite.\n * @returns The segment-like object with the info set.\n */\nexport const overwriteInfo = <\n\tT extends SegmentInfo,\n\tS extends ISegmentPrivate = ISegmentPrivate,\n>(\n\tsegmentLike: S,\n\tinfo: T,\n): SegmentWithInfo<T, S> => Object.assign(segmentLike, info);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"snapshotLoader.d.ts","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,EACN,mBAAmB,EAGnB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAkB3C,qBAAa,cAAc;IAIzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAG3B,OAAO,EAAE,sBAAsB,EAE/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACrC,MAAM,EAAE,mBAAmB,EACV,UAAU,EAAE,gBAAgB;IAKjC,UAAU,CACtB,QAAQ,EAAE,sBAAsB,GAC9B,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAA;KAAE,CAAC;YAiBnD,qBAAqB;IA2BnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAmD5B;IAEF,OAAO,CAAC,UAAU;YAsCJ,QAAQ;IAwFtB,OAAO,CAAC,kBAAkB;IAsB1B;;;;;OAKG;YACW,cAAc;CAQ5B"}
1
+ {"version":3,"file":"snapshotLoader.d.ts","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,EACN,mBAAmB,EAGnB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAkB3C,qBAAa,cAAc;IAIzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAG3B,OAAO,EAAE,sBAAsB,EAE/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACrC,MAAM,EAAE,mBAAmB,EACV,UAAU,EAAE,gBAAgB;IAKjC,UAAU,CACtB,QAAQ,EAAE,sBAAsB,GAC9B,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAA;KAAE,CAAC;YAiBnD,qBAAqB;IA2BnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAiD5B;IAEF,OAAO,CAAC,UAAU;YAsCJ,QAAQ;IAwFtB,OAAO,CAAC,kBAAkB;IAsB1B;;;;;OAKG;YACW,cAAc;CAQ5B"}
@@ -50,8 +50,6 @@ class SnapshotLoader {
50
50
  movedSeq: spec.movedSeq,
51
51
  movedSeqs: spec.movedSeqs,
52
52
  movedClientIds: spec.movedClientIds.map((id) => this.client.getOrAddShortClientId(id)),
53
- // TODO:AB#29553: This property should be derived from segment data, not hard-coded.
54
- wasMovedOnInsert: false,
55
53
  });
56
54
  }
57
55
  return seg;