@fluid-experimental/tree 2.0.0-internal.8.0.0 → 2.0.0-rc.1.0.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 (215) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/api-extractor-lint.json +1 -10
  3. package/api-extractor.json +0 -9
  4. package/api-report/experimental-tree.api.md +131 -130
  5. package/dist/ChangeTypes.d.ts +15 -15
  6. package/dist/ChangeTypes.js +4 -4
  7. package/dist/ChangeTypes.js.map +1 -1
  8. package/dist/Checkout.d.ts +4 -4
  9. package/dist/Checkout.js +3 -3
  10. package/dist/Checkout.js.map +1 -1
  11. package/dist/Common.d.ts +1 -1
  12. package/dist/Common.d.ts.map +1 -1
  13. package/dist/Common.js.map +1 -1
  14. package/dist/EagerCheckout.d.ts +1 -1
  15. package/dist/EagerCheckout.js +1 -1
  16. package/dist/EagerCheckout.js.map +1 -1
  17. package/dist/EditLog.d.ts +3 -2
  18. package/dist/EditLog.d.ts.map +1 -1
  19. package/dist/EditLog.js +3 -5
  20. package/dist/EditLog.js.map +1 -1
  21. package/dist/EditUtilities.d.ts +5 -5
  22. package/dist/EditUtilities.js +2 -2
  23. package/dist/EditUtilities.js.map +1 -1
  24. package/dist/EventTypes.d.ts +1 -1
  25. package/dist/EventTypes.js +1 -1
  26. package/dist/EventTypes.js.map +1 -1
  27. package/dist/Forest.d.ts +4 -4
  28. package/dist/Forest.js +3 -6
  29. package/dist/Forest.js.map +1 -1
  30. package/dist/Identifiers.d.ts +14 -14
  31. package/dist/Identifiers.js.map +1 -1
  32. package/dist/InitialTree.d.ts +1 -1
  33. package/dist/InitialTree.js +1 -1
  34. package/dist/InitialTree.js.map +1 -1
  35. package/dist/LogViewer.d.ts +2 -2
  36. package/dist/LogViewer.js +1 -1
  37. package/dist/LogViewer.js.map +1 -1
  38. package/dist/NodeIdUtilities.d.ts +3 -3
  39. package/dist/NodeIdUtilities.js.map +1 -1
  40. package/dist/PayloadUtilities.d.ts +1 -1
  41. package/dist/PayloadUtilities.js +1 -1
  42. package/dist/PayloadUtilities.js.map +1 -1
  43. package/dist/ReconciliationPath.d.ts +3 -3
  44. package/dist/ReconciliationPath.js.map +1 -1
  45. package/dist/RevisionValueCache.d.ts +1 -1
  46. package/dist/RevisionValueCache.js +2 -2
  47. package/dist/RevisionValueCache.js.map +1 -1
  48. package/dist/RevisionView.d.ts +2 -2
  49. package/dist/RevisionView.js +2 -2
  50. package/dist/RevisionView.js.map +1 -1
  51. package/dist/SharedTree.d.ts +14 -14
  52. package/dist/SharedTree.js +2 -2
  53. package/dist/SharedTree.js.map +1 -1
  54. package/dist/Transaction.d.ts +3 -3
  55. package/dist/Transaction.js +2 -2
  56. package/dist/Transaction.js.map +1 -1
  57. package/dist/TransactionInternal.d.ts +17 -17
  58. package/dist/TransactionInternal.js +3 -3
  59. package/dist/TransactionInternal.js.map +1 -1
  60. package/dist/TreeView.d.ts +7 -7
  61. package/dist/TreeView.js +1 -1
  62. package/dist/TreeView.js.map +1 -1
  63. package/dist/id-compressor/IdCompressor.js +2 -5
  64. package/dist/id-compressor/IdCompressor.js.map +1 -1
  65. package/dist/migration-shim/migrationShim.d.ts +3 -3
  66. package/dist/migration-shim/migrationShim.d.ts.map +1 -1
  67. package/dist/migration-shim/migrationShim.js +9 -5
  68. package/dist/migration-shim/migrationShim.js.map +1 -1
  69. package/dist/migration-shim/migrationShimFactory.d.ts +2 -2
  70. package/dist/migration-shim/migrationShimFactory.d.ts.map +1 -1
  71. package/dist/migration-shim/migrationShimFactory.js.map +1 -1
  72. package/dist/migration-shim/sharedTreeShim.d.ts +4 -4
  73. package/dist/migration-shim/sharedTreeShim.d.ts.map +1 -1
  74. package/dist/migration-shim/sharedTreeShim.js +1 -1
  75. package/dist/migration-shim/sharedTreeShim.js.map +1 -1
  76. package/dist/migration-shim/sharedTreeShimFactory.d.ts +1 -2
  77. package/dist/migration-shim/sharedTreeShimFactory.d.ts.map +1 -1
  78. package/dist/migration-shim/sharedTreeShimFactory.js.map +1 -1
  79. package/dist/migration-shim/shimDeltaConnection.d.ts +16 -0
  80. package/dist/migration-shim/shimDeltaConnection.d.ts.map +1 -1
  81. package/dist/migration-shim/shimDeltaConnection.js +16 -2
  82. package/dist/migration-shim/shimDeltaConnection.js.map +1 -1
  83. package/dist/migration-shim/types.d.ts +1 -1
  84. package/dist/migration-shim/types.d.ts.map +1 -1
  85. package/dist/migration-shim/types.js.map +1 -1
  86. package/dist/persisted-types/0.0.2.d.ts +24 -24
  87. package/dist/persisted-types/0.0.2.js +5 -5
  88. package/dist/persisted-types/0.0.2.js.map +1 -1
  89. package/dist/persisted-types/0.1.1.d.ts +14 -14
  90. package/dist/persisted-types/0.1.1.js +3 -3
  91. package/dist/persisted-types/0.1.1.js.map +1 -1
  92. package/dist/tree-alpha.d.ts +2674 -119
  93. package/dist/tree-beta.d.ts +1 -50
  94. package/dist/tree-public.d.ts +1 -52
  95. package/dist/tree-untrimmed.d.ts +142 -143
  96. package/lib/ChangeTypes.d.ts +15 -15
  97. package/lib/ChangeTypes.js +4 -4
  98. package/lib/ChangeTypes.js.map +1 -1
  99. package/lib/Checkout.d.ts +4 -4
  100. package/lib/Checkout.js +3 -3
  101. package/lib/Checkout.js.map +1 -1
  102. package/lib/Common.d.ts +1 -1
  103. package/lib/Common.d.ts.map +1 -1
  104. package/lib/Common.js.map +1 -1
  105. package/lib/EagerCheckout.d.ts +1 -1
  106. package/lib/EagerCheckout.js +1 -1
  107. package/lib/EagerCheckout.js.map +1 -1
  108. package/lib/EditLog.d.ts +3 -2
  109. package/lib/EditLog.d.ts.map +1 -1
  110. package/lib/EditLog.js +2 -1
  111. package/lib/EditLog.js.map +1 -1
  112. package/lib/EditUtilities.d.ts +5 -5
  113. package/lib/EditUtilities.js +2 -2
  114. package/lib/EditUtilities.js.map +1 -1
  115. package/lib/EventTypes.d.ts +1 -1
  116. package/lib/EventTypes.js +1 -1
  117. package/lib/EventTypes.js.map +1 -1
  118. package/lib/Forest.d.ts +4 -4
  119. package/lib/Forest.js +2 -2
  120. package/lib/Forest.js.map +1 -1
  121. package/lib/Identifiers.d.ts +14 -14
  122. package/lib/Identifiers.js.map +1 -1
  123. package/lib/InitialTree.d.ts +1 -1
  124. package/lib/InitialTree.js +1 -1
  125. package/lib/InitialTree.js.map +1 -1
  126. package/lib/LogViewer.d.ts +2 -2
  127. package/lib/LogViewer.js +1 -1
  128. package/lib/LogViewer.js.map +1 -1
  129. package/lib/NodeIdUtilities.d.ts +3 -3
  130. package/lib/NodeIdUtilities.js.map +1 -1
  131. package/lib/PayloadUtilities.d.ts +1 -1
  132. package/lib/PayloadUtilities.js +1 -1
  133. package/lib/PayloadUtilities.js.map +1 -1
  134. package/lib/ReconciliationPath.d.ts +3 -3
  135. package/lib/ReconciliationPath.js.map +1 -1
  136. package/lib/RevisionValueCache.d.ts +1 -1
  137. package/lib/RevisionValueCache.js +1 -1
  138. package/lib/RevisionValueCache.js.map +1 -1
  139. package/lib/RevisionView.d.ts +2 -2
  140. package/lib/RevisionView.js +2 -2
  141. package/lib/RevisionView.js.map +1 -1
  142. package/lib/SharedTree.d.ts +14 -14
  143. package/lib/SharedTree.js +2 -2
  144. package/lib/SharedTree.js.map +1 -1
  145. package/lib/Transaction.d.ts +3 -3
  146. package/lib/Transaction.js +2 -2
  147. package/lib/Transaction.js.map +1 -1
  148. package/lib/TransactionInternal.d.ts +17 -17
  149. package/lib/TransactionInternal.js +3 -3
  150. package/lib/TransactionInternal.js.map +1 -1
  151. package/lib/TreeView.d.ts +7 -7
  152. package/lib/TreeView.js +1 -1
  153. package/lib/TreeView.js.map +1 -1
  154. package/lib/id-compressor/IdCompressor.js +1 -1
  155. package/lib/id-compressor/IdCompressor.js.map +1 -1
  156. package/lib/migration-shim/migrationShim.d.ts +3 -3
  157. package/lib/migration-shim/migrationShim.d.ts.map +1 -1
  158. package/lib/migration-shim/migrationShim.js +9 -5
  159. package/lib/migration-shim/migrationShim.js.map +1 -1
  160. package/lib/migration-shim/migrationShimFactory.d.ts +2 -2
  161. package/lib/migration-shim/migrationShimFactory.d.ts.map +1 -1
  162. package/lib/migration-shim/migrationShimFactory.js.map +1 -1
  163. package/lib/migration-shim/sharedTreeShim.d.ts +4 -4
  164. package/lib/migration-shim/sharedTreeShim.d.ts.map +1 -1
  165. package/lib/migration-shim/sharedTreeShim.js +1 -1
  166. package/lib/migration-shim/sharedTreeShim.js.map +1 -1
  167. package/lib/migration-shim/sharedTreeShimFactory.d.ts +1 -2
  168. package/lib/migration-shim/sharedTreeShimFactory.d.ts.map +1 -1
  169. package/lib/migration-shim/sharedTreeShimFactory.js.map +1 -1
  170. package/lib/migration-shim/shimDeltaConnection.d.ts +16 -0
  171. package/lib/migration-shim/shimDeltaConnection.d.ts.map +1 -1
  172. package/lib/migration-shim/shimDeltaConnection.js +16 -2
  173. package/lib/migration-shim/shimDeltaConnection.js.map +1 -1
  174. package/lib/migration-shim/types.d.ts +1 -1
  175. package/lib/migration-shim/types.d.ts.map +1 -1
  176. package/lib/migration-shim/types.js.map +1 -1
  177. package/lib/persisted-types/0.0.2.d.ts +24 -24
  178. package/lib/persisted-types/0.0.2.js +5 -5
  179. package/lib/persisted-types/0.0.2.js.map +1 -1
  180. package/lib/persisted-types/0.1.1.d.ts +14 -14
  181. package/lib/persisted-types/0.1.1.js +3 -3
  182. package/lib/persisted-types/0.1.1.js.map +1 -1
  183. package/lib/test/utilities/TestUtilities.d.ts +1 -2
  184. package/lib/test/utilities/TestUtilities.d.ts.map +1 -1
  185. package/lib/test/utilities/TestUtilities.js.map +1 -1
  186. package/package.json +25 -25
  187. package/src/ChangeTypes.ts +15 -15
  188. package/src/Checkout.ts +4 -4
  189. package/src/Common.ts +1 -1
  190. package/src/EagerCheckout.ts +1 -1
  191. package/src/EditLog.ts +4 -3
  192. package/src/EditUtilities.ts +5 -5
  193. package/src/EventTypes.ts +1 -1
  194. package/src/Forest.ts +5 -5
  195. package/src/Identifiers.ts +14 -14
  196. package/src/InitialTree.ts +1 -1
  197. package/src/LogViewer.ts +2 -2
  198. package/src/NodeIdUtilities.ts +3 -3
  199. package/src/PayloadUtilities.ts +1 -1
  200. package/src/ReconciliationPath.ts +3 -3
  201. package/src/RevisionValueCache.ts +2 -2
  202. package/src/RevisionView.ts +2 -2
  203. package/src/SharedTree.ts +14 -14
  204. package/src/Transaction.ts +3 -3
  205. package/src/TransactionInternal.ts +17 -17
  206. package/src/TreeView.ts +7 -7
  207. package/src/id-compressor/IdCompressor.ts +1 -1
  208. package/src/migration-shim/migrationShim.ts +17 -9
  209. package/src/migration-shim/migrationShimFactory.ts +2 -2
  210. package/src/migration-shim/sharedTreeShim.ts +6 -5
  211. package/src/migration-shim/sharedTreeShimFactory.ts +1 -2
  212. package/src/migration-shim/shimDeltaConnection.ts +16 -2
  213. package/src/migration-shim/types.ts +1 -1
  214. package/src/persisted-types/0.0.2.ts +24 -24
  215. package/src/persisted-types/0.1.1.ts +14 -14
@@ -1 +1 @@
1
- {"version":3,"file":"Forest.js","sourceRoot":"","sources":["../src/Forest.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 BTree from 'sorted-btree';\nimport { assert } from '@fluidframework/core-utils';\nimport { fail, copyPropertyIfDefined, compareBtrees, compareFiniteNumbers } from './Common';\nimport { NodeId, TraitLabel } from './Identifiers';\nimport { comparePayloads } from './PayloadUtilities';\nimport { NodeData, Payload } from './persisted-types';\n\n/**\n * A node that can be contained within a Forest\n * @internal\n */\nexport interface ForestNode extends NodeData<NodeId> {\n\treadonly traits: ReadonlyMap<TraitLabel, readonly NodeId[]>;\n}\n\n/**\n * A node within a Forest that has a parent (and is therefore not the root node)\n *\n * @public\n */\nexport interface ParentedForestNode extends ForestNode, ParentData {}\n\n/**\n * Check whether or not the given node in a forest is parented\n *\n * @public\n */\nexport function isParentedForestNode(node: ForestNode): node is ParentedForestNode {\n\tconst parentedNode = node as ForestNode & Partial<ParentedForestNode>;\n\tconst hasParent = parentedNode.parentId !== undefined;\n\tconst hasTraitParent = parentedNode.traitParent !== undefined;\n\tassert(hasParent === hasTraitParent, 0x610 /* node must have either both parent and traitParent set or neither */);\n\treturn hasParent;\n}\n\n/**\n * Information about a ForestNode's parent\n * @internal\n */\nexport interface ParentData {\n\treadonly parentId: NodeId;\n\treadonly traitParent: TraitLabel;\n}\n\n/**\n * Differences from one forest to another.\n * @internal\n */\nexport interface Delta<NodeId> {\n\t/**\n\t * Nodes whose content changed.\n\t */\n\treadonly changed: readonly NodeId[];\n\t/**\n\t * Nodes that were added.\n\t */\n\treadonly added: readonly NodeId[];\n\t/**\n\t * Nodes that were removed.\n\t */\n\treadonly removed: readonly NodeId[];\n}\n\ninterface ForestState {\n\tnodes: BTree<NodeId, ForestNode>;\n\texpensiveValidation: boolean;\n}\n\n/**\n * An immutable forest of ForestNode.\n * Enforces single parenting, and allows querying the parent.\n * @internal\n */\nexport class Forest {\n\t/**\n\t * Contains the nodes in the forest.\n\t * Used as an immutable data-structure: must not be modified.\n\t */\n\tprivate readonly nodes: BTree<NodeId, ForestNode>;\n\n\t/**\n\t * If true, consistency checks will be applied after forest operations.\n\t */\n\tprivate readonly expensiveValidation: boolean;\n\n\t/**\n\t * Caller must ensure provided BTrees are not modified.\n\t * Will not modify the BTrees.\n\t */\n\tprivate constructor(data: ForestState);\n\n\t/**\n\t * Construct a new forest without reusing nodes from a previous one.\n\t */\n\tprivate constructor(expensiveValidation: boolean);\n\n\tprivate constructor(data?: ForestState | boolean) {\n\t\tif (typeof data === 'object') {\n\t\t\tthis.nodes = data.nodes;\n\t\t\tthis.expensiveValidation = data.expensiveValidation;\n\t\t} else {\n\t\t\tthis.nodes = new BTree<NodeId, ForestNode>(undefined, compareFiniteNumbers);\n\t\t\tthis.expensiveValidation = data ?? false;\n\t\t}\n\t\tif (this.expensiveValidation) {\n\t\t\tthis.assertConsistent();\n\t\t}\n\t}\n\n\t/**\n\t * Creates a new Forest.\n\t */\n\tpublic static create(expensiveValidation = false): Forest {\n\t\treturn new Forest(expensiveValidation);\n\t}\n\n\t/**\n\t * Returns the number of nodes in the forest.\n\t */\n\tpublic get size(): number {\n\t\treturn this.nodes.size;\n\t}\n\n\t/**\n\t * Adds the supplied nodes to the forest. The nodes' IDs must be unique in the forest.\n\t * @param nodes - the sequence of nodes to add to the forest. If any of them have children which exist in the forest already, those\n\t * children will be parented. Any trait arrays present in a node must be non-empty. The nodes may be provided in any order.\n\t */\n\tpublic add(nodes: Iterable<ForestNode>): Forest {\n\t\tconst newNodes = [...nodes];\n\t\tconst mutableNodes = this.nodes.clone();\n\n\t\t// This method iterates through the supplied nodes in two passes, first looking only at children and second actually adding the\n\t\t// nodes. This allows nodes to be passed in any order, e.g. a parent followed by a child or a child followed by a parent.\n\n\t\tconst childToParent = new Map<NodeId, ParentData>(); // Temporarily records the parentage of children that don't exist yet\n\n\t\t// First, inspect the children of each node. If the child is already in the forest, update its parentage. If it is not in the\n\t\t// forest, it may be about to be added in the second loop below so record its parentage temporarily for when that happens.\n\t\tfor (const node of newNodes) {\n\t\t\tconst { identifier } = node;\n\t\t\tfor (const [traitLabel, trait] of node.traits) {\n\t\t\t\tassert(trait.length > 0, 0x611 /* any trait arrays present in a node must be non-empty */);\n\t\t\t\tfor (const childId of trait) {\n\t\t\t\t\tconst child = mutableNodes.get(childId);\n\t\t\t\t\tif (child !== undefined) {\n\t\t\t\t\t\t// A child already exists in the forest, and its parent is now being added\n\t\t\t\t\t\tassert(!isParentedForestNode(child), 0x612 /* can not give a child multiple parents */);\n\t\t\t\t\t\tconst parentedChild = {\n\t\t\t\t\t\t\tdefinition: child.definition,\n\t\t\t\t\t\t\tidentifier: child.identifier,\n\t\t\t\t\t\t\ttraits: child.traits,\n\t\t\t\t\t\t\tparentId: identifier,\n\t\t\t\t\t\t\ttraitParent: traitLabel,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tcopyPropertyIfDefined(child, parentedChild, 'payload');\n\t\t\t\t\t\t// Overwrite the existing child with its parented version\n\t\t\t\t\t\tmutableNodes.set(childId, parentedChild);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// The child hasn't been added yet, so record its parentage to use when it is added below\n\t\t\t\t\t\tchildToParent.set(childId, { parentId: identifier, traitParent: traitLabel });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Now add each node to the forest and apply any parentage information that was recorded above\n\t\tfor (const node of newNodes) {\n\t\t\tconst parentData = childToParent.get(node.identifier);\n\t\t\tassert(!mutableNodes.has(node.identifier), 0x613 /* can not add node with already existing id */);\n\t\t\tif (parentData !== undefined) {\n\t\t\t\t// This is a child whom we haven't added yet, but whose parent we already added above. Supply the recorded parentage info.\n\t\t\t\tconst child = {\n\t\t\t\t\tdefinition: node.definition,\n\t\t\t\t\tidentifier: node.identifier,\n\t\t\t\t\ttraits: node.traits,\n\t\t\t\t\t...parentData,\n\t\t\t\t};\n\t\t\t\tcopyPropertyIfDefined(node, child, 'payload');\n\t\t\t\tmutableNodes.set(node.identifier, child);\n\t\t\t} else {\n\t\t\t\t// This is a node that has no parent. Add it with no parentage information.\n\t\t\t\tmutableNodes.set(node.identifier, node);\n\t\t\t}\n\t\t}\n\n\t\treturn new Forest({\n\t\t\tnodes: mutableNodes,\n\t\t\texpensiveValidation: this.expensiveValidation,\n\t\t});\n\t}\n\n\t/**\n\t * Parents a set of nodes already in the forest at a specified location within a trait.\n\t * @param parentId - the id of the parent under which to insert the new nodes\n\t * @param label - the label of the trait under which to insert the new nodes\n\t * @param index - the index in the trait after which to insert the new nodes\n\t * @param childIds - the ids of the nodes to insert\n\t */\n\tpublic attachRangeOfChildren(\n\t\tparentId: NodeId,\n\t\tlabel: TraitLabel,\n\t\tindex: number,\n\t\tchildIds: readonly NodeId[]\n\t): Forest {\n\t\tassert(index >= 0, 0x614 /* invalid attach index */);\n\t\tconst parentNode = this.nodes.get(parentId);\n\t\tassert(parentNode !== undefined, 0x615 /* can not insert children under node that does not exist */);\n\t\tconst mutableNodes = this.nodes.clone();\n\t\tconst traits = new Map(parentNode.traits);\n\t\tconst trait = traits.get(label) ?? [];\n\t\tassert(index <= trait.length, 0x616 /* invalid attach index */);\n\n\t\t// If there is nothing to insert, return early.\n\t\t// This is good for performance, but also avoids an edge case where an empty trait could be created (which is an error).\n\t\tif (childIds.length === 0) {\n\t\t\treturn this;\n\t\t}\n\t\tconst newChildren = [...trait.slice(0, index), ...childIds, ...trait.slice(index)];\n\t\ttraits.set(label, newChildren);\n\t\tmutableNodes.set(parentId, { ...parentNode, traits });\n\n\t\tfor (const childId of childIds) {\n\t\t\tmutableNodes.editRange(childId, childId, true, (_, n) => {\n\t\t\t\tassert(!isParentedForestNode(n), 0x617 /* can not attach node that already has a parent */);\n\t\t\t\tconst breakVal: { value: ParentedForestNode } = {\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\t...n,\n\t\t\t\t\t\tparentId,\n\t\t\t\t\t\ttraitParent: label,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\treturn breakVal;\n\t\t\t});\n\t\t}\n\n\t\treturn new Forest({\n\t\t\tnodes: mutableNodes,\n\t\t\texpensiveValidation: this.expensiveValidation,\n\t\t});\n\t}\n\n\t/**\n\t * Detaches a range of nodes from their parent. The detached nodes remain in the `Forest`.\n\t * @param parentId - the id of the parent from which to detach the nodes\n\t * @param label - the label of the trait from which to detach the nodes\n\t * @param startIndex - the index of the first node in the range to detach\n\t * @param endIndex - the index after the last node in the range to detach\n\t * @returns a new `Forest` with the nodes detached, and a list of the ids of the nodes that were detached\n\t */\n\tpublic detachRangeOfChildren(\n\t\tparentId: NodeId,\n\t\tlabel: TraitLabel,\n\t\tstartIndex: number,\n\t\tendIndex: number\n\t): { forest: Forest; detached: readonly NodeId[] } {\n\t\tassert(startIndex >= 0 && endIndex >= startIndex, 0x618 /* invalid detach index range */);\n\t\tconst parentNode = this.nodes.get(parentId);\n\t\tassert(parentNode !== undefined, 0x619 /* can not detach children under node that does not exist */);\n\t\tif (startIndex === endIndex) {\n\t\t\treturn { forest: this, detached: [] };\n\t\t}\n\n\t\tconst mutableNodes = this.nodes.clone();\n\t\tconst traits = new Map(parentNode.traits);\n\t\tconst trait = traits.get(label) ?? [];\n\t\tassert(endIndex <= trait.length, 0x61a /* invalid detach index range */);\n\t\tconst detached: NodeId[] = trait.slice(startIndex, endIndex);\n\t\tconst newChildren = [...trait.slice(0, startIndex), ...trait.slice(endIndex)];\n\t\tconst deleteTrait = newChildren.length === 0;\n\t\tif (deleteTrait) {\n\t\t\ttraits.delete(label);\n\t\t} else {\n\t\t\ttraits.set(label, newChildren);\n\t\t}\n\n\t\tmutableNodes.set(parentId, { ...parentNode, traits });\n\t\tfor (const childId of detached) {\n\t\t\tmutableNodes.editRange(childId, childId, true, (_, n) => {\n\t\t\t\tconst breakVal: { value: ForestNode } = {\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tdefinition: n.definition,\n\t\t\t\t\t\tidentifier: n.identifier,\n\t\t\t\t\t\ttraits: n.traits,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tcopyPropertyIfDefined(n, breakVal.value, 'payload');\n\t\t\t\treturn breakVal;\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\tforest: new Forest({\n\t\t\t\tnodes: mutableNodes,\n\t\t\t\texpensiveValidation: this.expensiveValidation,\n\t\t\t}),\n\t\t\tdetached,\n\t\t};\n\t}\n\n\t/**\n\t * Replaces a node's value. The node must exist in this `Forest`.\n\t * @param nodeId - the id of the node\n\t * @param value - the new value\n\t */\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic setValue(nodeId: NodeId, value: Payload | null): Forest {\n\t\tconst node = this.nodes.get(nodeId);\n\t\tassert(node !== undefined, 0x61b /* can not replace payload for node that does not exist */);\n\t\tconst mutableNodes = this.nodes.clone();\n\t\tconst newNode = { ...node };\n\t\tif (value !== null) {\n\t\t\tnewNode.payload = value;\n\t\t} else {\n\t\t\tdelete newNode.payload;\n\t\t}\n\t\tmutableNodes.set(nodeId, newNode);\n\t\treturn new Forest({\n\t\t\tnodes: mutableNodes,\n\t\t\texpensiveValidation: this.expensiveValidation,\n\t\t});\n\t}\n\n\t/**\n\t * @returns true if the node associated with `id` exists in this forest, otherwise false\n\t */\n\tpublic has(id: NodeId): boolean {\n\t\treturn this.nodes.has(id);\n\t}\n\n\t/**\n\t * @returns the node associated with `id`. Should not be used if there is no node with the provided id.\n\t */\n\tpublic get(id: NodeId): ForestNode {\n\t\treturn this.nodes.get(id) ?? fail('NodeId not found');\n\t}\n\n\t/**\n\t * @returns the node associated with `id`, or undefined if there is none\n\t */\n\tpublic tryGet(id: NodeId): ForestNode | undefined {\n\t\treturn this.nodes.get(id);\n\t}\n\n\t/**\n\t * Deletes every node in ids (each of which must be unparented)\n\t * @param ids - The IDs of the nodes to delete.\n\t * @param deleteChildren - If true, recursively deletes descendants. Otherwise, leaves children unparented.\n\t */\n\tpublic delete(ids: Iterable<NodeId>, deleteChildren: boolean): Forest {\n\t\tconst mutableNodes = this.nodes.clone();\n\t\tfor (const id of ids) {\n\t\t\tthis.deleteRecursive(mutableNodes, id, deleteChildren);\n\t\t}\n\n\t\treturn new Forest({\n\t\t\tnodes: mutableNodes,\n\t\t\texpensiveValidation: this.expensiveValidation,\n\t\t});\n\t}\n\n\tprivate deleteRecursive(mutableNodes: BTree<NodeId, ForestNode>, id: NodeId, deleteChildren: boolean): void {\n\t\tconst node = mutableNodes.get(id) ?? fail('node to delete must exist');\n\t\tassert(!isParentedForestNode(node), 0x61c /* deleted nodes must be unparented */);\n\t\tmutableNodes.delete(id);\n\t\tfor (const trait of node.traits.values()) {\n\t\t\tfor (const childId of trait) {\n\t\t\t\tmutableNodes.editRange(childId, childId, true, (_, n) => {\n\t\t\t\t\tconst breakVal: { value: ForestNode } = {\n\t\t\t\t\t\tvalue: {\n\t\t\t\t\t\t\tdefinition: n.definition,\n\t\t\t\t\t\t\tidentifier: n.identifier,\n\t\t\t\t\t\t\ttraits: n.traits,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t\tcopyPropertyIfDefined(n, breakVal.value, 'payload');\n\t\t\t\t\treturn breakVal;\n\t\t\t\t});\n\n\t\t\t\tif (deleteChildren) {\n\t\t\t\t\tthis.deleteRecursive(mutableNodes, childId, deleteChildren);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks that the metadata is correct, and the items form a forest.\n\t * This is an expensive O(map size) operation.\n\t */\n\tpublic assertConsistent(): void {\n\t\tconst checkedChildren = new Set<NodeId>([]);\n\t\tfor (const [nodeId, node] of this.nodes.entries(undefined, [])) {\n\t\t\tif (isParentedForestNode(node)) {\n\t\t\t\tconst parent = this.get(node.parentId);\n\t\t\t\tconst trait = parent.traits.get(node.traitParent);\n\t\t\t\tassert(trait !== undefined, 0x61d /* trait exists */);\n\t\t\t\tassert(trait.includes(node.identifier), 0x61e /* node is parented incorrectly */);\n\t\t\t}\n\n\t\t\tfor (const trait of node.traits.values()) {\n\t\t\t\tassert(trait.length > 0, 0x61f /* trait is present but empty */);\n\t\t\t\tfor (const childId of trait) {\n\t\t\t\t\tconst child = this.nodes.get(childId);\n\t\t\t\t\tassert(child !== undefined, 0x620 /* child in trait is not in forest */);\n\t\t\t\t\tassert(isParentedForestNode(child), 0x621 /* child is not parented */);\n\t\t\t\t\tassert(child.parentId === node.identifier, 0x622 /* child parent pointer is incorrect */);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!checkedChildren.has(childId),\n\t\t\t\t\t\t0x623 /* the item tree tree must not contain cycles or multi-parented nodes */\n\t\t\t\t\t);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t(child.parentId ?? fail('each node must have associated metadata')) === nodeId,\n\t\t\t\t\t\t0x624 /* cached parent is incorrect */\n\t\t\t\t\t);\n\t\t\t\t\tcheckedChildren.add(childId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @returns the parent of `id`. Should not be used if there is no node with id or if id refers to the root node.\n\t */\n\tpublic getParent(id: NodeId): ParentData {\n\t\tconst child = this.nodes.get(id);\n\t\tif (child === undefined) {\n\t\t\tfail('NodeId not found');\n\t\t}\n\n\t\tassert(isParentedForestNode(child), 0x625 /* Node is not parented */);\n\t\treturn { parentId: child.parentId, traitParent: child.traitParent };\n\t}\n\n\t/**\n\t * @returns undefined iff root, otherwise the parent of `id`.\n\t */\n\tpublic tryGetParent(id: NodeId): ParentData | undefined {\n\t\tconst child = this.nodes.get(id);\n\t\tif (child === undefined || !isParentedForestNode(child)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\tparentId: child.parentId,\n\t\t\ttraitParent: child.traitParent,\n\t\t};\n\t}\n\n\t/**\n\t * Compares two forests for equality.\n\t * @param forest - the other forest to compare to this one\n\t * @param comparator - a function which returns true if two objects of type ForestNode are equivalent, false otherwise\n\t * @returns true iff the forests are equal.\n\t */\n\tpublic equals(forest: Forest): boolean {\n\t\tif (this === forest || this.nodes === forest.nodes) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (forest.size !== this.size) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn compareBtrees(this.nodes, forest.nodes, compareForestNodes);\n\t}\n\n\t/**\n\t * Calculate the difference between two forests.\n\t * @param forest - the other forest to compare to this one\n\t * @param comparator - a function which returns true if two objects of type ForestNode are equivalent, false otherwise\n\t * @returns A {@link Delta} listing which nodes must be changed, added, and removed to get from `this` to `forest`.\n\t */\n\tpublic delta(forest: Forest): Delta<NodeId> {\n\t\tconst changed: NodeId[] = [];\n\t\tconst removed: NodeId[] = [];\n\t\tconst added: NodeId[] = [];\n\t\tthis.nodes.diffAgainst(\n\t\t\tforest.nodes,\n\t\t\t(id) => {\n\t\t\t\tremoved.push(id);\n\t\t\t},\n\t\t\t(id) => {\n\t\t\t\tadded.push(id);\n\t\t\t},\n\t\t\t(id, nodeThis, nodeOther) => {\n\t\t\t\tif (!compareForestNodes(nodeThis, nodeOther)) {\n\t\t\t\t\tchanged.push(id);\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t\treturn {\n\t\t\tchanged,\n\t\t\tadded,\n\t\t\tremoved,\n\t\t};\n\t}\n}\n\n/**\n * @returns true iff two `ForestNodes` are equivalent.\n * May return false for nodes they contain equivalent payloads encoded differently.\n */\nexport function compareForestNodes(nodeA: ForestNode, nodeB: ForestNode): boolean {\n\tif (nodeA === nodeB) {\n\t\treturn true;\n\t}\n\n\tif (nodeA.identifier !== nodeB.identifier) {\n\t\treturn false;\n\t}\n\n\tif (nodeA.definition !== nodeB.definition) {\n\t\treturn false;\n\t}\n\n\tif (!comparePayloads(nodeA.payload, nodeB.payload)) {\n\t\treturn false;\n\t}\n\n\tif (nodeA.traits.size !== nodeB.traits.size) {\n\t\treturn false;\n\t}\n\n\tfor (const traitA of nodeA.traits) {\n\t\tconst [traitLabelA, nodeSequenceA] = traitA;\n\t\tconst nodeSequenceB = nodeB.traits.get(traitLabelA);\n\t\tif (!nodeSequenceB) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (nodeSequenceA.length !== nodeSequenceB.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (let i = 0; i < nodeSequenceA.length; i++) {\n\t\t\tif (nodeSequenceA[i] !== nodeSequenceB[i]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true;\n}\n"]}
1
+ {"version":3,"file":"Forest.js","sourceRoot":"","sources":["../src/Forest.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 { BTree } from '@tylerbu/sorted-btree-es6';\nimport { assert } from '@fluidframework/core-utils';\nimport { fail, copyPropertyIfDefined, compareBtrees, compareFiniteNumbers } from './Common';\nimport { NodeId, TraitLabel } from './Identifiers';\nimport { comparePayloads } from './PayloadUtilities';\nimport { NodeData, Payload } from './persisted-types';\n\n/**\n * A node that can be contained within a Forest\n * @alpha\n */\nexport interface ForestNode extends NodeData<NodeId> {\n\treadonly traits: ReadonlyMap<TraitLabel, readonly NodeId[]>;\n}\n\n/**\n * A node within a Forest that has a parent (and is therefore not the root node)\n *\n * @public\n */\nexport interface ParentedForestNode extends ForestNode, ParentData {}\n\n/**\n * Check whether or not the given node in a forest is parented\n *\n * @public\n */\nexport function isParentedForestNode(node: ForestNode): node is ParentedForestNode {\n\tconst parentedNode = node as ForestNode & Partial<ParentedForestNode>;\n\tconst hasParent = parentedNode.parentId !== undefined;\n\tconst hasTraitParent = parentedNode.traitParent !== undefined;\n\tassert(hasParent === hasTraitParent, 0x610 /* node must have either both parent and traitParent set or neither */);\n\treturn hasParent;\n}\n\n/**\n * Information about a ForestNode's parent\n * @alpha\n */\nexport interface ParentData {\n\treadonly parentId: NodeId;\n\treadonly traitParent: TraitLabel;\n}\n\n/**\n * Differences from one forest to another.\n * @alpha\n */\nexport interface Delta<NodeId> {\n\t/**\n\t * Nodes whose content changed.\n\t */\n\treadonly changed: readonly NodeId[];\n\t/**\n\t * Nodes that were added.\n\t */\n\treadonly added: readonly NodeId[];\n\t/**\n\t * Nodes that were removed.\n\t */\n\treadonly removed: readonly NodeId[];\n}\n\ninterface ForestState {\n\tnodes: BTree<NodeId, ForestNode>;\n\texpensiveValidation: boolean;\n}\n\n/**\n * An immutable forest of ForestNode.\n * Enforces single parenting, and allows querying the parent.\n * @alpha\n */\nexport class Forest {\n\t/**\n\t * Contains the nodes in the forest.\n\t * Used as an immutable data-structure: must not be modified.\n\t */\n\tprivate readonly nodes: BTree<NodeId, ForestNode>;\n\n\t/**\n\t * If true, consistency checks will be applied after forest operations.\n\t */\n\tprivate readonly expensiveValidation: boolean;\n\n\t/**\n\t * Caller must ensure provided BTrees are not modified.\n\t * Will not modify the BTrees.\n\t */\n\tprivate constructor(data: ForestState);\n\n\t/**\n\t * Construct a new forest without reusing nodes from a previous one.\n\t */\n\tprivate constructor(expensiveValidation: boolean);\n\n\tprivate constructor(data?: ForestState | boolean) {\n\t\tif (typeof data === 'object') {\n\t\t\tthis.nodes = data.nodes;\n\t\t\tthis.expensiveValidation = data.expensiveValidation;\n\t\t} else {\n\t\t\tthis.nodes = new BTree<NodeId, ForestNode>(undefined, compareFiniteNumbers);\n\t\t\tthis.expensiveValidation = data ?? false;\n\t\t}\n\t\tif (this.expensiveValidation) {\n\t\t\tthis.assertConsistent();\n\t\t}\n\t}\n\n\t/**\n\t * Creates a new Forest.\n\t */\n\tpublic static create(expensiveValidation = false): Forest {\n\t\treturn new Forest(expensiveValidation);\n\t}\n\n\t/**\n\t * Returns the number of nodes in the forest.\n\t */\n\tpublic get size(): number {\n\t\treturn this.nodes.size;\n\t}\n\n\t/**\n\t * Adds the supplied nodes to the forest. The nodes' IDs must be unique in the forest.\n\t * @param nodes - the sequence of nodes to add to the forest. If any of them have children which exist in the forest already, those\n\t * children will be parented. Any trait arrays present in a node must be non-empty. The nodes may be provided in any order.\n\t */\n\tpublic add(nodes: Iterable<ForestNode>): Forest {\n\t\tconst newNodes = [...nodes];\n\t\tconst mutableNodes = this.nodes.clone();\n\n\t\t// This method iterates through the supplied nodes in two passes, first looking only at children and second actually adding the\n\t\t// nodes. This allows nodes to be passed in any order, e.g. a parent followed by a child or a child followed by a parent.\n\n\t\tconst childToParent = new Map<NodeId, ParentData>(); // Temporarily records the parentage of children that don't exist yet\n\n\t\t// First, inspect the children of each node. If the child is already in the forest, update its parentage. If it is not in the\n\t\t// forest, it may be about to be added in the second loop below so record its parentage temporarily for when that happens.\n\t\tfor (const node of newNodes) {\n\t\t\tconst { identifier } = node;\n\t\t\tfor (const [traitLabel, trait] of node.traits) {\n\t\t\t\tassert(trait.length > 0, 0x611 /* any trait arrays present in a node must be non-empty */);\n\t\t\t\tfor (const childId of trait) {\n\t\t\t\t\tconst child = mutableNodes.get(childId);\n\t\t\t\t\tif (child !== undefined) {\n\t\t\t\t\t\t// A child already exists in the forest, and its parent is now being added\n\t\t\t\t\t\tassert(!isParentedForestNode(child), 0x612 /* can not give a child multiple parents */);\n\t\t\t\t\t\tconst parentedChild = {\n\t\t\t\t\t\t\tdefinition: child.definition,\n\t\t\t\t\t\t\tidentifier: child.identifier,\n\t\t\t\t\t\t\ttraits: child.traits,\n\t\t\t\t\t\t\tparentId: identifier,\n\t\t\t\t\t\t\ttraitParent: traitLabel,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tcopyPropertyIfDefined(child, parentedChild, 'payload');\n\t\t\t\t\t\t// Overwrite the existing child with its parented version\n\t\t\t\t\t\tmutableNodes.set(childId, parentedChild);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// The child hasn't been added yet, so record its parentage to use when it is added below\n\t\t\t\t\t\tchildToParent.set(childId, { parentId: identifier, traitParent: traitLabel });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Now add each node to the forest and apply any parentage information that was recorded above\n\t\tfor (const node of newNodes) {\n\t\t\tconst parentData = childToParent.get(node.identifier);\n\t\t\tassert(!mutableNodes.has(node.identifier), 0x613 /* can not add node with already existing id */);\n\t\t\tif (parentData !== undefined) {\n\t\t\t\t// This is a child whom we haven't added yet, but whose parent we already added above. Supply the recorded parentage info.\n\t\t\t\tconst child = {\n\t\t\t\t\tdefinition: node.definition,\n\t\t\t\t\tidentifier: node.identifier,\n\t\t\t\t\ttraits: node.traits,\n\t\t\t\t\t...parentData,\n\t\t\t\t};\n\t\t\t\tcopyPropertyIfDefined(node, child, 'payload');\n\t\t\t\tmutableNodes.set(node.identifier, child);\n\t\t\t} else {\n\t\t\t\t// This is a node that has no parent. Add it with no parentage information.\n\t\t\t\tmutableNodes.set(node.identifier, node);\n\t\t\t}\n\t\t}\n\n\t\treturn new Forest({\n\t\t\tnodes: mutableNodes,\n\t\t\texpensiveValidation: this.expensiveValidation,\n\t\t});\n\t}\n\n\t/**\n\t * Parents a set of nodes already in the forest at a specified location within a trait.\n\t * @param parentId - the id of the parent under which to insert the new nodes\n\t * @param label - the label of the trait under which to insert the new nodes\n\t * @param index - the index in the trait after which to insert the new nodes\n\t * @param childIds - the ids of the nodes to insert\n\t */\n\tpublic attachRangeOfChildren(\n\t\tparentId: NodeId,\n\t\tlabel: TraitLabel,\n\t\tindex: number,\n\t\tchildIds: readonly NodeId[]\n\t): Forest {\n\t\tassert(index >= 0, 0x614 /* invalid attach index */);\n\t\tconst parentNode = this.nodes.get(parentId);\n\t\tassert(parentNode !== undefined, 0x615 /* can not insert children under node that does not exist */);\n\t\tconst mutableNodes = this.nodes.clone();\n\t\tconst traits = new Map(parentNode.traits);\n\t\tconst trait = traits.get(label) ?? [];\n\t\tassert(index <= trait.length, 0x616 /* invalid attach index */);\n\n\t\t// If there is nothing to insert, return early.\n\t\t// This is good for performance, but also avoids an edge case where an empty trait could be created (which is an error).\n\t\tif (childIds.length === 0) {\n\t\t\treturn this;\n\t\t}\n\t\tconst newChildren = [...trait.slice(0, index), ...childIds, ...trait.slice(index)];\n\t\ttraits.set(label, newChildren);\n\t\tmutableNodes.set(parentId, { ...parentNode, traits });\n\n\t\tfor (const childId of childIds) {\n\t\t\tmutableNodes.editRange(childId, childId, true, (_, n) => {\n\t\t\t\tassert(!isParentedForestNode(n), 0x617 /* can not attach node that already has a parent */);\n\t\t\t\tconst breakVal: { value: ParentedForestNode } = {\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\t...n,\n\t\t\t\t\t\tparentId,\n\t\t\t\t\t\ttraitParent: label,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\treturn breakVal;\n\t\t\t});\n\t\t}\n\n\t\treturn new Forest({\n\t\t\tnodes: mutableNodes,\n\t\t\texpensiveValidation: this.expensiveValidation,\n\t\t});\n\t}\n\n\t/**\n\t * Detaches a range of nodes from their parent. The detached nodes remain in the `Forest`.\n\t * @param parentId - the id of the parent from which to detach the nodes\n\t * @param label - the label of the trait from which to detach the nodes\n\t * @param startIndex - the index of the first node in the range to detach\n\t * @param endIndex - the index after the last node in the range to detach\n\t * @returns a new `Forest` with the nodes detached, and a list of the ids of the nodes that were detached\n\t */\n\tpublic detachRangeOfChildren(\n\t\tparentId: NodeId,\n\t\tlabel: TraitLabel,\n\t\tstartIndex: number,\n\t\tendIndex: number\n\t): { forest: Forest; detached: readonly NodeId[] } {\n\t\tassert(startIndex >= 0 && endIndex >= startIndex, 0x618 /* invalid detach index range */);\n\t\tconst parentNode = this.nodes.get(parentId);\n\t\tassert(parentNode !== undefined, 0x619 /* can not detach children under node that does not exist */);\n\t\tif (startIndex === endIndex) {\n\t\t\treturn { forest: this, detached: [] };\n\t\t}\n\n\t\tconst mutableNodes = this.nodes.clone();\n\t\tconst traits = new Map(parentNode.traits);\n\t\tconst trait = traits.get(label) ?? [];\n\t\tassert(endIndex <= trait.length, 0x61a /* invalid detach index range */);\n\t\tconst detached: NodeId[] = trait.slice(startIndex, endIndex);\n\t\tconst newChildren = [...trait.slice(0, startIndex), ...trait.slice(endIndex)];\n\t\tconst deleteTrait = newChildren.length === 0;\n\t\tif (deleteTrait) {\n\t\t\ttraits.delete(label);\n\t\t} else {\n\t\t\ttraits.set(label, newChildren);\n\t\t}\n\n\t\tmutableNodes.set(parentId, { ...parentNode, traits });\n\t\tfor (const childId of detached) {\n\t\t\tmutableNodes.editRange(childId, childId, true, (_, n) => {\n\t\t\t\tconst breakVal: { value: ForestNode } = {\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tdefinition: n.definition,\n\t\t\t\t\t\tidentifier: n.identifier,\n\t\t\t\t\t\ttraits: n.traits,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tcopyPropertyIfDefined(n, breakVal.value, 'payload');\n\t\t\t\treturn breakVal;\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\tforest: new Forest({\n\t\t\t\tnodes: mutableNodes,\n\t\t\t\texpensiveValidation: this.expensiveValidation,\n\t\t\t}),\n\t\t\tdetached,\n\t\t};\n\t}\n\n\t/**\n\t * Replaces a node's value. The node must exist in this `Forest`.\n\t * @param nodeId - the id of the node\n\t * @param value - the new value\n\t */\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic setValue(nodeId: NodeId, value: Payload | null): Forest {\n\t\tconst node = this.nodes.get(nodeId);\n\t\tassert(node !== undefined, 0x61b /* can not replace payload for node that does not exist */);\n\t\tconst mutableNodes = this.nodes.clone();\n\t\tconst newNode = { ...node };\n\t\tif (value !== null) {\n\t\t\tnewNode.payload = value;\n\t\t} else {\n\t\t\tdelete newNode.payload;\n\t\t}\n\t\tmutableNodes.set(nodeId, newNode);\n\t\treturn new Forest({\n\t\t\tnodes: mutableNodes,\n\t\t\texpensiveValidation: this.expensiveValidation,\n\t\t});\n\t}\n\n\t/**\n\t * @returns true if the node associated with `id` exists in this forest, otherwise false\n\t */\n\tpublic has(id: NodeId): boolean {\n\t\treturn this.nodes.has(id);\n\t}\n\n\t/**\n\t * @returns the node associated with `id`. Should not be used if there is no node with the provided id.\n\t */\n\tpublic get(id: NodeId): ForestNode {\n\t\treturn this.nodes.get(id) ?? fail('NodeId not found');\n\t}\n\n\t/**\n\t * @returns the node associated with `id`, or undefined if there is none\n\t */\n\tpublic tryGet(id: NodeId): ForestNode | undefined {\n\t\treturn this.nodes.get(id);\n\t}\n\n\t/**\n\t * Deletes every node in ids (each of which must be unparented)\n\t * @param ids - The IDs of the nodes to delete.\n\t * @param deleteChildren - If true, recursively deletes descendants. Otherwise, leaves children unparented.\n\t */\n\tpublic delete(ids: Iterable<NodeId>, deleteChildren: boolean): Forest {\n\t\tconst mutableNodes = this.nodes.clone();\n\t\tfor (const id of ids) {\n\t\t\tthis.deleteRecursive(mutableNodes, id, deleteChildren);\n\t\t}\n\n\t\treturn new Forest({\n\t\t\tnodes: mutableNodes,\n\t\t\texpensiveValidation: this.expensiveValidation,\n\t\t});\n\t}\n\n\tprivate deleteRecursive(mutableNodes: BTree<NodeId, ForestNode>, id: NodeId, deleteChildren: boolean): void {\n\t\tconst node = mutableNodes.get(id) ?? fail('node to delete must exist');\n\t\tassert(!isParentedForestNode(node), 0x61c /* deleted nodes must be unparented */);\n\t\tmutableNodes.delete(id);\n\t\tfor (const trait of node.traits.values()) {\n\t\t\tfor (const childId of trait) {\n\t\t\t\tmutableNodes.editRange(childId, childId, true, (_, n) => {\n\t\t\t\t\tconst breakVal: { value: ForestNode } = {\n\t\t\t\t\t\tvalue: {\n\t\t\t\t\t\t\tdefinition: n.definition,\n\t\t\t\t\t\t\tidentifier: n.identifier,\n\t\t\t\t\t\t\ttraits: n.traits,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t\tcopyPropertyIfDefined(n, breakVal.value, 'payload');\n\t\t\t\t\treturn breakVal;\n\t\t\t\t});\n\n\t\t\t\tif (deleteChildren) {\n\t\t\t\t\tthis.deleteRecursive(mutableNodes, childId, deleteChildren);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Checks that the metadata is correct, and the items form a forest.\n\t * This is an expensive O(map size) operation.\n\t */\n\tpublic assertConsistent(): void {\n\t\tconst checkedChildren = new Set<NodeId>([]);\n\t\tfor (const [nodeId, node] of this.nodes.entries(undefined, [])) {\n\t\t\tif (isParentedForestNode(node)) {\n\t\t\t\tconst parent = this.get(node.parentId);\n\t\t\t\tconst trait = parent.traits.get(node.traitParent);\n\t\t\t\tassert(trait !== undefined, 0x61d /* trait exists */);\n\t\t\t\tassert(trait.includes(node.identifier), 0x61e /* node is parented incorrectly */);\n\t\t\t}\n\n\t\t\tfor (const trait of node.traits.values()) {\n\t\t\t\tassert(trait.length > 0, 0x61f /* trait is present but empty */);\n\t\t\t\tfor (const childId of trait) {\n\t\t\t\t\tconst child = this.nodes.get(childId);\n\t\t\t\t\tassert(child !== undefined, 0x620 /* child in trait is not in forest */);\n\t\t\t\t\tassert(isParentedForestNode(child), 0x621 /* child is not parented */);\n\t\t\t\t\tassert(child.parentId === node.identifier, 0x622 /* child parent pointer is incorrect */);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t!checkedChildren.has(childId),\n\t\t\t\t\t\t0x623 /* the item tree tree must not contain cycles or multi-parented nodes */\n\t\t\t\t\t);\n\t\t\t\t\tassert(\n\t\t\t\t\t\t(child.parentId ?? fail('each node must have associated metadata')) === nodeId,\n\t\t\t\t\t\t0x624 /* cached parent is incorrect */\n\t\t\t\t\t);\n\t\t\t\t\tcheckedChildren.add(childId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * @returns the parent of `id`. Should not be used if there is no node with id or if id refers to the root node.\n\t */\n\tpublic getParent(id: NodeId): ParentData {\n\t\tconst child = this.nodes.get(id);\n\t\tif (child === undefined) {\n\t\t\tfail('NodeId not found');\n\t\t}\n\n\t\tassert(isParentedForestNode(child), 0x625 /* Node is not parented */);\n\t\treturn { parentId: child.parentId, traitParent: child.traitParent };\n\t}\n\n\t/**\n\t * @returns undefined iff root, otherwise the parent of `id`.\n\t */\n\tpublic tryGetParent(id: NodeId): ParentData | undefined {\n\t\tconst child = this.nodes.get(id);\n\t\tif (child === undefined || !isParentedForestNode(child)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\tparentId: child.parentId,\n\t\t\ttraitParent: child.traitParent,\n\t\t};\n\t}\n\n\t/**\n\t * Compares two forests for equality.\n\t * @param forest - the other forest to compare to this one\n\t * @param comparator - a function which returns true if two objects of type ForestNode are equivalent, false otherwise\n\t * @returns true iff the forests are equal.\n\t */\n\tpublic equals(forest: Forest): boolean {\n\t\tif (this === forest || this.nodes === forest.nodes) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (forest.size !== this.size) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn compareBtrees(this.nodes, forest.nodes, compareForestNodes);\n\t}\n\n\t/**\n\t * Calculate the difference between two forests.\n\t * @param forest - the other forest to compare to this one\n\t * @param comparator - a function which returns true if two objects of type ForestNode are equivalent, false otherwise\n\t * @returns A {@link Delta} listing which nodes must be changed, added, and removed to get from `this` to `forest`.\n\t */\n\tpublic delta(forest: Forest): Delta<NodeId> {\n\t\tconst changed: NodeId[] = [];\n\t\tconst removed: NodeId[] = [];\n\t\tconst added: NodeId[] = [];\n\t\tthis.nodes.diffAgainst(\n\t\t\tforest.nodes,\n\t\t\t(id) => {\n\t\t\t\tremoved.push(id);\n\t\t\t},\n\t\t\t(id) => {\n\t\t\t\tadded.push(id);\n\t\t\t},\n\t\t\t(id, nodeThis, nodeOther) => {\n\t\t\t\tif (!compareForestNodes(nodeThis, nodeOther)) {\n\t\t\t\t\tchanged.push(id);\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t\treturn {\n\t\t\tchanged,\n\t\t\tadded,\n\t\t\tremoved,\n\t\t};\n\t}\n}\n\n/**\n * @returns true iff two `ForestNodes` are equivalent.\n * May return false for nodes they contain equivalent payloads encoded differently.\n */\nexport function compareForestNodes(nodeA: ForestNode, nodeB: ForestNode): boolean {\n\tif (nodeA === nodeB) {\n\t\treturn true;\n\t}\n\n\tif (nodeA.identifier !== nodeB.identifier) {\n\t\treturn false;\n\t}\n\n\tif (nodeA.definition !== nodeB.definition) {\n\t\treturn false;\n\t}\n\n\tif (!comparePayloads(nodeA.payload, nodeB.payload)) {\n\t\treturn false;\n\t}\n\n\tif (nodeA.traits.size !== nodeB.traits.size) {\n\t\treturn false;\n\t}\n\n\tfor (const traitA of nodeA.traits) {\n\t\tconst [traitLabelA, nodeSequenceA] = traitA;\n\t\tconst nodeSequenceB = nodeB.traits.get(traitLabelA);\n\t\tif (!nodeSequenceB) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (nodeSequenceA.length !== nodeSequenceB.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (let i = 0; i < nodeSequenceA.length; i++) {\n\t\t\tif (nodeSequenceA[i] !== nodeSequenceB[i]) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true;\n}\n"]}
@@ -9,14 +9,14 @@
9
9
  * A 128-bit Universally Unique IDentifier. Represented here
10
10
  * with a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
11
11
  * where x is a lowercase hex digit.
12
- * @internal
12
+ * @alpha
13
13
  */
14
14
  export type UuidString = string & {
15
15
  readonly UuidString: '9d40d0ae-90d9-44b1-9482-9f55d59d5465';
16
16
  };
17
17
  /**
18
18
  * An identifier associated with a session for the purpose of attributing its created content to some user/entity.
19
- * @internal
19
+ * @alpha
20
20
  */
21
21
  export type AttributionId = UuidString;
22
22
  /**
@@ -35,7 +35,7 @@ export type SessionId = StableId & {
35
35
  };
36
36
  /**
37
37
  * Edit identifier
38
- * @internal
38
+ * @alpha
39
39
  */
40
40
  export type EditId = UuidString & {
41
41
  readonly EditId: '56897beb-53e4-4e66-85da-4bf5cd5d0d49';
@@ -46,14 +46,14 @@ export type EditId = UuidString & {
46
46
  * Within a given Edit, any DetachedSequenceId must be a source at most once, and a destination at most once.
47
47
  * If used as a source, it must be after it is used as a destination.
48
48
  * If this is violated, the Edit is considered malformed.
49
- * @internal
49
+ * @alpha
50
50
  */
51
51
  export type DetachedSequenceId = number & {
52
52
  readonly DetachedSequenceId: 'f7d7903a-194e-45e7-8e82-c9ef4333577d';
53
53
  };
54
54
  /**
55
55
  * An identifier (UUID) that has been shortened by a distributed compression algorithm.
56
- * @internal
56
+ * @alpha
57
57
  */
58
58
  export type CompressedId = FinalCompressedId | LocalCompressedId;
59
59
  /**
@@ -65,7 +65,7 @@ export type InternedStringId = number & {
65
65
  };
66
66
  /**
67
67
  * A brand for identity types that are unique within a particular session (SharedTree instance).
68
- * @internal
68
+ * @alpha
69
69
  */
70
70
  export interface SessionUnique {
71
71
  readonly SessionUnique: 'cea55054-6b82-4cbf-ad19-1fa645ea3b3e';
@@ -74,7 +74,7 @@ export interface SessionUnique {
74
74
  * A compressed ID that has been normalized into "session space" (see `IdCompressor` for more).
75
75
  * Consumer-facing APIs and data structures should use session-space IDs as their lifetime and equality is stable and tied to the
76
76
  * compressor that produced them.
77
- * @internal
77
+ * @alpha
78
78
  */
79
79
  export type SessionSpaceCompressedId = CompressedId & SessionUnique;
80
80
  /**
@@ -90,7 +90,7 @@ export type OpSpaceCompressedId = CompressedId & {
90
90
  * A compressed ID that is local to a document. Stable across all revisions of a document starting from the one in which it was created.
91
91
  * It should not be persisted outside of the history as it can only be decompressed in the context of the originating document.
92
92
  * If external persistence is needed (e.g. by a client), a StableId should be used instead.
93
- * @internal
93
+ * @alpha
94
94
  */
95
95
  export type FinalCompressedId = number & {
96
96
  readonly FinalCompressedId: '5d83d1e2-98b7-4e4e-a889-54c855cfa73d';
@@ -100,13 +100,13 @@ export type FinalCompressedId = number & {
100
100
  * A compressed ID that is local to a session (can only be decompressed when paired with a SessionId).
101
101
  * It should not be persisted outside of the history as it can only be decompressed in the context of the originating session.
102
102
  * If external persistence is needed (e.g. by a client), a StableId should be used instead.
103
- * @internal
103
+ * @alpha
104
104
  */
105
105
  export type LocalCompressedId = number & {
106
106
  readonly LocalCompressedId: '6fccb42f-e2a4-4243-bd29-f13d12b9c6d1';
107
107
  } & SessionUnique;
108
108
  /**
109
- * @internal
109
+ * @alpha
110
110
  */
111
111
  export interface NodeIdBrand {
112
112
  readonly NodeId: 'e53e7d6b-c8b9-431a-8805-4843fc639342';
@@ -114,7 +114,7 @@ export interface NodeIdBrand {
114
114
  /**
115
115
  * Node identifier.
116
116
  * Identifies a node within a document.
117
- * @internal
117
+ * @alpha
118
118
  */
119
119
  export type NodeId = number & SessionSpaceCompressedId & NodeIdBrand;
120
120
  export type FinalNodeId = FinalCompressedId & NodeIdBrand;
@@ -126,7 +126,7 @@ export type OpSpaceNodeId = number & OpSpaceCompressedId & NodeIdBrand;
126
126
  /**
127
127
  * Globally unique node identifier.
128
128
  * Uniquely identifies a node within and across documents. Can be used across SharedTree instances.
129
- * @internal
129
+ * @alpha
130
130
  */
131
131
  export type StableNodeId = string & {
132
132
  readonly StableNodeId: 'a0843b38-699d-4bb2-aa7a-16c502a71151';
@@ -134,7 +134,7 @@ export type StableNodeId = string & {
134
134
  /**
135
135
  * Definition.
136
136
  * A full (Uuid) persistable definition.
137
- * @internal
137
+ * @alpha
138
138
  */
139
139
  export type Definition = UuidString & {
140
140
  readonly Definition: 'c0ef9488-2a78-482d-aeed-37fba996354c';
@@ -142,7 +142,7 @@ export type Definition = UuidString & {
142
142
  /**
143
143
  * Definition.
144
144
  * A full (Uuid) persistable label for a trait.
145
- * @internal
145
+ * @alpha
146
146
  */
147
147
  export type TraitLabel = UuidString & {
148
148
  readonly TraitLabel: '613826ed-49cc-4df3-b2b8-bfc6866af8e3';
@@ -1 +1 @@
1
- {"version":3,"file":"Identifiers.js","sourceRoot":"","sources":["../src/Identifiers.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAwJH;;;GAGG;AACH,wDAAwD;AACxD,SAAgB,oBAAoB,CAAC,IAAiC;IACrE,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC;AACjC,CAAC;AAFD,oDAEC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Type-safe identifiers for specific use cases.\n */\n\n/**\n * A 128-bit Universally Unique IDentifier. Represented here\n * with a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,\n * where x is a lowercase hex digit.\n * @internal\n */\nexport type UuidString = string & { readonly UuidString: '9d40d0ae-90d9-44b1-9482-9f55d59d5465' };\n\n/**\n * An identifier associated with a session for the purpose of attributing its created content to some user/entity.\n * @internal\n */\nexport type AttributionId = UuidString;\n\n/**\n * A version 4, variant 2 uuid (https://datatracker.ietf.org/doc/html/rfc4122).\n * @internal\n */\nexport type StableId = UuidString & { readonly StableId: '53172b0d-a3d5-41ea-bd75-b43839c97f5a' };\n\n/**\n * A StableId which is suitable for use as a session identifier\n * @internal\n */\nexport type SessionId = StableId & { readonly SessionId: '4498f850-e14e-4be9-8db0-89ec00997e58' };\n\n/**\n * Edit identifier\n * @internal\n */\nexport type EditId = UuidString & { readonly EditId: '56897beb-53e4-4e66-85da-4bf5cd5d0d49' };\n\n/**\n * Scoped to a single edit: identifies a sequences of nodes that can be moved into a trait.\n *\n * Within a given Edit, any DetachedSequenceId must be a source at most once, and a destination at most once.\n * If used as a source, it must be after it is used as a destination.\n * If this is violated, the Edit is considered malformed.\n * @internal\n */\nexport type DetachedSequenceId = number & { readonly DetachedSequenceId: 'f7d7903a-194e-45e7-8e82-c9ef4333577d' };\n\n/**\n * An identifier (UUID) that has been shortened by a distributed compression algorithm.\n * @internal\n */\nexport type CompressedId = FinalCompressedId | LocalCompressedId;\n\n/**\n * The ID of the string that has been interned, which can be used by a {@link StringInterner} to retrieve the original string.\n * @internal\n */\nexport type InternedStringId = number & { readonly InternedStringId: 'e221abc9-9d17-4493-8db0-70c871a1c27c' };\n\n/**\n * A brand for identity types that are unique within a particular session (SharedTree instance).\n * @internal\n */\nexport interface SessionUnique {\n\treadonly SessionUnique: 'cea55054-6b82-4cbf-ad19-1fa645ea3b3e';\n}\n\n/**\n * A compressed ID that has been normalized into \"session space\" (see `IdCompressor` for more).\n * Consumer-facing APIs and data structures should use session-space IDs as their lifetime and equality is stable and tied to the\n * compressor that produced them.\n * @internal\n */\nexport type SessionSpaceCompressedId = CompressedId & SessionUnique;\n\n/**\n * A compressed ID that has been normalized into \"op space\" (see `IdCompressor` for more).\n * Serialized/persisted structures (e.g. ops) should use op-space IDs as a performance optimization, as they require no normalizing when\n * received by a remote client due to the fact that op space for a given compressor is session space for all other compressors.\n * @internal\n */\nexport type OpSpaceCompressedId = CompressedId & {\n\treadonly OpNormalized: '9209432d-a959-4df7-b2ad-767ead4dbcae';\n};\n\n/**\n * A compressed ID that is local to a document. Stable across all revisions of a document starting from the one in which it was created.\n * It should not be persisted outside of the history as it can only be decompressed in the context of the originating document.\n * If external persistence is needed (e.g. by a client), a StableId should be used instead.\n * @internal\n */\nexport type FinalCompressedId = number & {\n\treadonly FinalCompressedId: '5d83d1e2-98b7-4e4e-a889-54c855cfa73d';\n\n\t// Same brand as OpNormalizedCompressedId, as final IDs are always finally normalized\n\treadonly OpNormalized: '9209432d-a959-4df7-b2ad-767ead4dbcae';\n};\n\n/**\n * A compressed ID that is local to a session (can only be decompressed when paired with a SessionId).\n * It should not be persisted outside of the history as it can only be decompressed in the context of the originating session.\n * If external persistence is needed (e.g. by a client), a StableId should be used instead.\n * @internal\n */\nexport type LocalCompressedId = number & {\n\treadonly LocalCompressedId: '6fccb42f-e2a4-4243-bd29-f13d12b9c6d1';\n} & SessionUnique; // Same brand as CompressedId, as local IDs are always locally normalized\n\n/**\n * @internal\n */\nexport interface NodeIdBrand {\n\treadonly NodeId: 'e53e7d6b-c8b9-431a-8805-4843fc639342';\n}\n\n/**\n * Node identifier.\n * Identifies a node within a document.\n * @internal\n */\nexport type NodeId = number & SessionSpaceCompressedId & NodeIdBrand;\n\nexport type FinalNodeId = FinalCompressedId & NodeIdBrand;\n\n/**\n * A Node identifier which is persisted by SharedTree internals. Not usable as a {@link NodeId}.\n * @internal\n */\nexport type OpSpaceNodeId = number & OpSpaceCompressedId & NodeIdBrand;\n\n/**\n * Globally unique node identifier.\n * Uniquely identifies a node within and across documents. Can be used across SharedTree instances.\n * @internal\n */\nexport type StableNodeId = string & { readonly StableNodeId: 'a0843b38-699d-4bb2-aa7a-16c502a71151' };\n\n/**\n * Definition.\n * A full (Uuid) persistable definition.\n * @internal\n */\nexport type Definition = UuidString & { readonly Definition: 'c0ef9488-2a78-482d-aeed-37fba996354c' };\n\n/**\n * Definition.\n * A full (Uuid) persistable label for a trait.\n * @internal\n */\nexport type TraitLabel = UuidString & { readonly TraitLabel: '613826ed-49cc-4df3-b2b8-bfc6866af8e3' };\n\n/**\n * Determine if a node is a DetachedSequenceId.\n * @internal\n */\n// Nodes can be an `object` type which is a banned type.\nexport function isDetachedSequenceId(node: DetachedSequenceId | object): node is DetachedSequenceId {\n\treturn typeof node !== 'object';\n}\n"]}
1
+ {"version":3,"file":"Identifiers.js","sourceRoot":"","sources":["../src/Identifiers.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAwJH;;;GAGG;AACH,wDAAwD;AACxD,SAAgB,oBAAoB,CAAC,IAAiC;IACrE,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC;AACjC,CAAC;AAFD,oDAEC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Type-safe identifiers for specific use cases.\n */\n\n/**\n * A 128-bit Universally Unique IDentifier. Represented here\n * with a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,\n * where x is a lowercase hex digit.\n * @alpha\n */\nexport type UuidString = string & { readonly UuidString: '9d40d0ae-90d9-44b1-9482-9f55d59d5465' };\n\n/**\n * An identifier associated with a session for the purpose of attributing its created content to some user/entity.\n * @alpha\n */\nexport type AttributionId = UuidString;\n\n/**\n * A version 4, variant 2 uuid (https://datatracker.ietf.org/doc/html/rfc4122).\n * @internal\n */\nexport type StableId = UuidString & { readonly StableId: '53172b0d-a3d5-41ea-bd75-b43839c97f5a' };\n\n/**\n * A StableId which is suitable for use as a session identifier\n * @internal\n */\nexport type SessionId = StableId & { readonly SessionId: '4498f850-e14e-4be9-8db0-89ec00997e58' };\n\n/**\n * Edit identifier\n * @alpha\n */\nexport type EditId = UuidString & { readonly EditId: '56897beb-53e4-4e66-85da-4bf5cd5d0d49' };\n\n/**\n * Scoped to a single edit: identifies a sequences of nodes that can be moved into a trait.\n *\n * Within a given Edit, any DetachedSequenceId must be a source at most once, and a destination at most once.\n * If used as a source, it must be after it is used as a destination.\n * If this is violated, the Edit is considered malformed.\n * @alpha\n */\nexport type DetachedSequenceId = number & { readonly DetachedSequenceId: 'f7d7903a-194e-45e7-8e82-c9ef4333577d' };\n\n/**\n * An identifier (UUID) that has been shortened by a distributed compression algorithm.\n * @alpha\n */\nexport type CompressedId = FinalCompressedId | LocalCompressedId;\n\n/**\n * The ID of the string that has been interned, which can be used by a {@link StringInterner} to retrieve the original string.\n * @internal\n */\nexport type InternedStringId = number & { readonly InternedStringId: 'e221abc9-9d17-4493-8db0-70c871a1c27c' };\n\n/**\n * A brand for identity types that are unique within a particular session (SharedTree instance).\n * @alpha\n */\nexport interface SessionUnique {\n\treadonly SessionUnique: 'cea55054-6b82-4cbf-ad19-1fa645ea3b3e';\n}\n\n/**\n * A compressed ID that has been normalized into \"session space\" (see `IdCompressor` for more).\n * Consumer-facing APIs and data structures should use session-space IDs as their lifetime and equality is stable and tied to the\n * compressor that produced them.\n * @alpha\n */\nexport type SessionSpaceCompressedId = CompressedId & SessionUnique;\n\n/**\n * A compressed ID that has been normalized into \"op space\" (see `IdCompressor` for more).\n * Serialized/persisted structures (e.g. ops) should use op-space IDs as a performance optimization, as they require no normalizing when\n * received by a remote client due to the fact that op space for a given compressor is session space for all other compressors.\n * @internal\n */\nexport type OpSpaceCompressedId = CompressedId & {\n\treadonly OpNormalized: '9209432d-a959-4df7-b2ad-767ead4dbcae';\n};\n\n/**\n * A compressed ID that is local to a document. Stable across all revisions of a document starting from the one in which it was created.\n * It should not be persisted outside of the history as it can only be decompressed in the context of the originating document.\n * If external persistence is needed (e.g. by a client), a StableId should be used instead.\n * @alpha\n */\nexport type FinalCompressedId = number & {\n\treadonly FinalCompressedId: '5d83d1e2-98b7-4e4e-a889-54c855cfa73d';\n\n\t// Same brand as OpNormalizedCompressedId, as final IDs are always finally normalized\n\treadonly OpNormalized: '9209432d-a959-4df7-b2ad-767ead4dbcae';\n};\n\n/**\n * A compressed ID that is local to a session (can only be decompressed when paired with a SessionId).\n * It should not be persisted outside of the history as it can only be decompressed in the context of the originating session.\n * If external persistence is needed (e.g. by a client), a StableId should be used instead.\n * @alpha\n */\nexport type LocalCompressedId = number & {\n\treadonly LocalCompressedId: '6fccb42f-e2a4-4243-bd29-f13d12b9c6d1';\n} & SessionUnique; // Same brand as CompressedId, as local IDs are always locally normalized\n\n/**\n * @alpha\n */\nexport interface NodeIdBrand {\n\treadonly NodeId: 'e53e7d6b-c8b9-431a-8805-4843fc639342';\n}\n\n/**\n * Node identifier.\n * Identifies a node within a document.\n * @alpha\n */\nexport type NodeId = number & SessionSpaceCompressedId & NodeIdBrand;\n\nexport type FinalNodeId = FinalCompressedId & NodeIdBrand;\n\n/**\n * A Node identifier which is persisted by SharedTree internals. Not usable as a {@link NodeId}.\n * @internal\n */\nexport type OpSpaceNodeId = number & OpSpaceCompressedId & NodeIdBrand;\n\n/**\n * Globally unique node identifier.\n * Uniquely identifies a node within and across documents. Can be used across SharedTree instances.\n * @alpha\n */\nexport type StableNodeId = string & { readonly StableNodeId: 'a0843b38-699d-4bb2-aa7a-16c502a71151' };\n\n/**\n * Definition.\n * A full (Uuid) persistable definition.\n * @alpha\n */\nexport type Definition = UuidString & { readonly Definition: 'c0ef9488-2a78-482d-aeed-37fba996354c' };\n\n/**\n * Definition.\n * A full (Uuid) persistable label for a trait.\n * @alpha\n */\nexport type TraitLabel = UuidString & { readonly TraitLabel: '613826ed-49cc-4df3-b2b8-bfc6866af8e3' };\n\n/**\n * Determine if a node is a DetachedSequenceId.\n * @internal\n */\n// Nodes can be an `object` type which is a banned type.\nexport function isDetachedSequenceId(node: DetachedSequenceId | object): node is DetachedSequenceId {\n\treturn typeof node !== 'object';\n}\n"]}
@@ -5,7 +5,7 @@
5
5
  import { ChangeNode_0_0_2 } from './persisted-types';
6
6
  /**
7
7
  * The initial tree.
8
- * @internal
8
+ * @alpha
9
9
  */
10
10
  export declare const initialTree: ChangeNode_0_0_2;
11
11
  //# sourceMappingURL=InitialTree.d.ts.map
@@ -8,7 +8,7 @@ exports.initialTree = void 0;
8
8
  const id_compressor_1 = require("./id-compressor");
9
9
  /**
10
10
  * The initial tree.
11
- * @internal
11
+ * @alpha
12
12
  */
13
13
  exports.initialTree = {
14
14
  traits: {},
@@ -1 +1 @@
1
- {"version":3,"file":"InitialTree.js","sourceRoot":"","sources":["../src/InitialTree.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,mDAAgE;AAGhE;;;GAGG;AACU,QAAA,WAAW,GAAqB;IAC5C,MAAM,EAAE,EAAE;IACV,UAAU,EAAE,sCAAoD;IAChE,UAAU,EAAE,6CAA6C;CACzD,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { Definition, StableNodeId } from './Identifiers';\nimport { legacySharedTreeInitialTreeId } from './id-compressor';\nimport { ChangeNode_0_0_2 } from './persisted-types';\n\n/**\n * The initial tree.\n * @internal\n */\nexport const initialTree: ChangeNode_0_0_2 = {\n\ttraits: {},\n\tdefinition: '51c58718-47b9-4fe4-ad46-56312f3b9e86' as Definition,\n\tidentifier: legacySharedTreeInitialTreeId as StableNodeId,\n};\n"]}
1
+ {"version":3,"file":"InitialTree.js","sourceRoot":"","sources":["../src/InitialTree.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,mDAAgE;AAGhE;;;GAGG;AACU,QAAA,WAAW,GAAqB;IAC5C,MAAM,EAAE,EAAE;IACV,UAAU,EAAE,sCAAoD;IAChE,UAAU,EAAE,6CAA6C;CACzD,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { Definition, StableNodeId } from './Identifiers';\nimport { legacySharedTreeInitialTreeId } from './id-compressor';\nimport { ChangeNode_0_0_2 } from './persisted-types';\n\n/**\n * The initial tree.\n * @alpha\n */\nexport const initialTree: ChangeNode_0_0_2 = {\n\ttraits: {},\n\tdefinition: '51c58718-47b9-4fe4-ad46-56312f3b9e86' as Definition,\n\tidentifier: legacySharedTreeInitialTreeId as StableNodeId,\n};\n"]}
@@ -129,7 +129,7 @@ export type CachedEditingResult = AttemptedEditResultCacheEntry & {
129
129
  };
130
130
  /**
131
131
  * Creates `RevisionView`s for the revisions in an `EditLog`
132
- * @internal
132
+ * @alpha
133
133
  */
134
134
  export interface LogViewer {
135
135
  /**
@@ -193,7 +193,7 @@ export interface ICachingLogViewerEvents extends IEvent {
193
193
  *
194
194
  * Does so by listening for edits added to the log. If the underlying EditLog or its listeners need to be reused beyond the lifetime of
195
195
  * a CachingLogViewer instance, that instance should be disposed with `detachFromEditLog` to ensure it is garbage-collectable.
196
- * @internal
196
+ * @alpha
197
197
  */
198
198
  export declare class CachingLogViewer extends TypedEventEmitter<ICachingLogViewerEvents> implements LogViewer {
199
199
  readonly log: EditLog<ChangeInternal>;
package/dist/LogViewer.js CHANGED
@@ -27,7 +27,7 @@ var CachingLogViewerDiagnosticEvents;
27
27
  *
28
28
  * Does so by listening for edits added to the log. If the underlying EditLog or its listeners need to be reused beyond the lifetime of
29
29
  * a CachingLogViewer instance, that instance should be disposed with `detachFromEditLog` to ensure it is garbage-collectable.
30
- * @internal
30
+ * @alpha
31
31
  */
32
32
  class CachingLogViewer extends client_utils_1.TypedEventEmitter {
33
33
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"LogViewer.js","sourceRoot":"","sources":["../src/LogViewer.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 Denque from 'denque';\nimport { TypedEventEmitter } from '@fluid-internal/client-utils';\nimport { IEvent } from '@fluidframework/core-interfaces';\nimport { assert } from '@fluidframework/core-utils';\nimport { fail, noop } from './Common';\nimport { EditLog, SequencedOrderedEditId } from './EditLog';\nimport { EditId } from './Identifiers';\nimport { Revision, RevisionValueCache } from './RevisionValueCache';\nimport { ReconciliationChange, ReconciliationEdit, ReconciliationPath } from './ReconciliationPath';\nimport { ChangeInternal, Edit, EditStatus } from './persisted-types';\nimport { RevisionView } from './RevisionView';\nimport { EditingResult, TransactionInternal } from './TransactionInternal';\n\n/**\n * Callback for when an edit is applied (meaning the result of applying it to a particular revision is computed).\n *\n * Edits may be applied any time a TreeView is computed that includes them.\n * Depending on the caching policy of the LogViewer, a given edit may or may not be applied in order to compute a TreeView containing it.\n *\n * If the same edit occurs in different contexts (ex: a local edit is adjusted for a new remote edit),\n * that it will be reapplied, and this may result in different results.\n *\n * Edits may additionally be reapplied at other times since their previous output might not be cached.\n *\n * If an application requests the current view, this will force all edits to be applied.\n * Such an application can use this callback can be log each edit as it comes it to see its status,\n * however this may include duplicates, as well as entries for reapplications in modified contexts.\n *\n * In the context of this callback,\n * skipping the first evaluation of an edit in a particular context due to setKnownEditingResult is still considered applying.\n * To use this call back to track when the actual computational work of applying edits is done, only count cases when `wasCached` is false.\n */\nexport type EditStatusCallback = (editResult: EditStatus, editId: EditId, wasCached: boolean) => void;\n\n/**\n * Callback for when a sequenced edit is applied.\n * This includes local edits though the callback is only invoked once the sequenced version is received.\n *\n * For edits that were local (see {@link SequencedEditResult.wasLocal}, this callback will only be called once.\n * For non-local edits, it may be called multiple times: the number of calls and when they occur depends on caching and is an implementation\n * detail.\n */\nexport type SequencedEditResultCallback = (args: SequencedEditResult) => void;\n\n/**\n * The relevant information pertaining to the application of a sequenced edit.\n */\nexport interface SequencedEditResult {\n\t/**\n\t * The edit that was applied.\n\t */\n\tedit: Edit<ChangeInternal>;\n\t/**\n\t * true iff the edit was local.\n\t */\n\twasLocal: boolean;\n\t/**\n\t * The result of applying the edit.\n\t */\n\tresult: AttemptedEditResultCacheEntry;\n\t/**\n\t * The reconciliation path for the edit.\n\t */\n\treconciliationPath: ReconciliationPath;\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit.\n */\nexport type EditCacheEntry = SuccessfulEditCacheEntry | UnsuccessfulEditCacheEntry | SummarizedEditResultCacheEntry;\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has attempted to apply locally.\n */\nexport type AttemptedEditResultCacheEntry = SuccessfulEditCacheEntry | UnsuccessfulEditCacheEntry;\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has successfully applied locally.\n */\nexport interface SuccessfulEditCacheEntry {\n\t/**\n\t * The revision view resulting from the edit.\n\t */\n\treadonly view: RevisionView;\n\t/**\n\t * The status code for the edit that produced the revision.\n\t */\n\treadonly status: EditStatus.Applied;\n\t/**\n\t * The resolved changes that were applied during the edit and their associated outcome.\n\t */\n\treadonly steps: readonly ReconciliationChange[];\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has unsuccessfully attempted to apply locally.\n */\nexport interface UnsuccessfulEditCacheEntry {\n\t/**\n\t * The revision view resulting from the edit.\n\t */\n\treadonly view: RevisionView;\n\t/**\n\t * The status code for the edit that produced the revision.\n\t */\n\treadonly status: EditStatus.Invalid | EditStatus.Malformed;\n\t/**\n\t * Information about the failure encountered by the edit\n\t */\n\treadonly failure: TransactionInternal.Failure;\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has retrieved from a summary.\n * TODO:#57176: once summarized edits carry enough information remove this interface and use `AttemptedEditResultCacheEntry` instead.\n */\nexport interface SummarizedEditResultCacheEntry {\n\t/**\n\t * The revision view resulting from the edit.\n\t */\n\treadonly view: RevisionView;\n\t/**\n\t * Not specified on `SummarizedEditResultCacheEntry`.\n\t * Declared to allow checking `entry.status` against undefined.\n\t */\n\treadonly status?: never;\n}\n\nexport type CachedEditingResult = AttemptedEditResultCacheEntry & {\n\t/**\n\t * Unique identifier for this edit. Must never be reused.\n\t * Used for referencing and de-duplicating edits.\n\t */\n\treadonly id: EditId;\n\treadonly before: RevisionView;\n\treadonly changes: readonly ChangeInternal[];\n};\n\n/**\n * Creates `RevisionView`s for the revisions in an `EditLog`\n * @internal\n */\nexport interface LogViewer {\n\t/**\n\t * Returns the `TreeView` output associated with the largest revision in `editLog` less than (but not equal to) the supplied revision.\n\t *\n\t * For example:\n\t *\n\t * - revision 0 returns the initialRevision.\n\t *\n\t * - revision 1 returns the output of editLog[0] (or initialRevision if there is no edit 0).\n\t *\n\t * - revision Number.POSITIVE_INFINITY returns the newest revision.\n\t *\n\t * @deprecated Edit virtualization is no longer supported, use {@link LogViewer.getRevisionViewInMemory}\n\t */\n\tgetRevisionView(revision: Revision): Promise<RevisionView>;\n\n\t/**\n\t * Returns the `TreeView` output associated with the largest revision in `editLog` less than (but not equal to) the supplied revision.\n\t * Can only be used to retrieve revisions added during the current sessions.\n\t *\n\t * For example:\n\t *\n\t * - revision 0 returns the initialRevision.\n\t *\n\t * - revision 1 returns the output of editLog[0] (or initialRevision if there is no edit 0).\n\t *\n\t * - revision Number.POSITIVE_INFINITY returns the newest revision.\n\t *\n\t * @deprecated Edit virtualization is no longer supported so the 'inSession' APIs will be removed, use {@link LogViewer.getRevisionViewInMemory}\n\t */\n\tgetRevisionViewInSession(revision: Revision): RevisionView;\n\n\t/**\n\t * Returns the `TreeView` output associated with the largest revision in `editLog` less than (but not equal to) the supplied revision.\n\t * Can only be used to retrieve revisions added during the current session that have not been evicted from `editLog`.\n\t *\n\t * For example:\n\t *\n\t * - revision 0 returns the oldest edit in the log (which might be initialRevision).\n\t *\n\t * - revision 1 returns the output of editLog[0] (or initialRevision if there is no edit 0).\n\t *\n\t * - revision Number.POSITIVE_INFINITY returns the newest revision.\n\t */\n\tgetRevisionViewInMemory(revision: Revision): RevisionView;\n}\n\n/**\n * Events reported by {@link CachingLogViewer} for diagnostics or testing purposes.\n */\nexport enum CachingLogViewerDiagnosticEvents {\n\tRevisionRetained = 'revisionRetained',\n}\n\n/**\n * Events which may be emitted by {@link CachingLogViewer}\n * @public\n */\nexport interface ICachingLogViewerEvents extends IEvent {\n\t(event: CachingLogViewerDiagnosticEvents.RevisionRetained, listener: (revision: Revision) => void);\n}\n\n/**\n * Creates views for revisions associated with an EditLog and caches the results.\n *\n * Does so by listening for edits added to the log. If the underlying EditLog or its listeners need to be reused beyond the lifetime of\n * a CachingLogViewer instance, that instance should be disposed with `detachFromEditLog` to ensure it is garbage-collectable.\n * @internal\n */\nexport class CachingLogViewer extends TypedEventEmitter<ICachingLogViewerEvents> implements LogViewer {\n\tpublic readonly log: EditLog<ChangeInternal>;\n\n\t/**\n\t * Maximum size of the sequenced revision cache.\n\t */\n\tpublic static readonly sequencedCacheSizeMax = 50;\n\n\t/**\n\t * A cache for local revisions.\n\t * It is invalidated whenever a new sequenced edit (that was not already a local edit) is added to the log.\n\t * When a previously local edit is sequenced, this cache is adjusted to account for it, not invalidated.\n\t */\n\tprivate readonly localRevisionCache = new Denque<AttemptedEditResultCacheEntry>();\n\n\t/**\n\t * Cache of sequenced revisions.\n\t */\n\tprivate readonly sequencedRevisionCache: RevisionValueCache<EditCacheEntry>;\n\n\t/**\n\t * Called whenever a sequenced edit is applied.\n\t * This will have been called at least once for any edit if a revision after than edit has been requested.\n\t * It may be called multiple times: the number of calls and when they occur depends on caching and is an implementation detail.\n\t */\n\tprivate readonly processSequencedEditResult: SequencedEditResultCallback;\n\n\t/**\n\t * Called whenever an edit is processed.\n\t * This will have been called at least once for any edit if a revision after than edit has been requested.\n\t * It may be called multiple times: the number of calls and when they occur depends on caching and is an implementation detail.\n\t */\n\tprivate readonly processEditStatus: EditStatusCallback;\n\n\t/**\n\t * The ordered queue of edits that originated from this client that have never been applied (by this log viewer) in a sequenced state.\n\t * This means these edits may be local or sequenced, and may have been applied (possibly multiple times) while still local.\n\t * Used to log telemetry about the result of edit application. Edits are removed when first applied after being sequenced.\n\t */\n\tprivate readonly unappliedSelfEdits = new Denque<EditId>();\n\n\t/**\n\t * Cache of applying a edit.\n\t * Due to use of Transactions in checkouts, a common pattern involves applying an edit\n\t * as part of the transaction, then submitting it.\n\t * This cache helps optimize that case by avoiding recomputing the edit if no other edits were added during the transaction.\n\t */\n\tprivate cachedEditResult?: { editId: EditId; result: EditingResult };\n\n\t/**\n\t * Cache entry for the highest revision.\n\t * `undefined` when not cached.\n\t */\n\tprivate highestRevisionCacheEntry?: EditCacheEntry;\n\n\t/**\n\t * Removes this log viewer from the set of handleEditAdded listeners on its underlying log.\n\t * This should be called if the underlying log or its listeners are re-used past the lifetime of this log viewer.\n\t */\n\tpublic readonly detachFromEditLog: () => void;\n\n\t/**\n\t * @returns true if the highest revision is cached.\n\t */\n\tpublic highestRevisionCached(): boolean {\n\t\treturn this.highestRevisionCacheEntry !== undefined;\n\t}\n\n\t/**\n\t * Create a new LogViewer\n\t * @param log - the edit log which revisions will be based on.\n\t * @param baseTree - the tree used in the view corresponding to the 0th revision.\n\t * @param initialRevision - a [sequencedRevision, view] pair that is known (been precomputed) at construction time.\n\t * This revision is guaranteed to never be evicted from the cache unless it is replaced as the oldest in memory revision.\n\t * @param expensiveValidation - Iff true, additional correctness assertions will be run during LogViewer operations.\n\t * @param processEditStatus - called after applying an edit.\n\t * @param processSequencedEditResult - called after applying a sequenced edit.\n\t */\n\tpublic constructor(\n\t\tlog: EditLog<ChangeInternal>,\n\t\tbaseView: RevisionView,\n\t\tinitialRevision?: [Revision, EditCacheEntry],\n\t\tprocessEditStatus: EditStatusCallback = noop,\n\t\tprocessSequencedEditResult: SequencedEditResultCallback = noop,\n\t\tminimumSequenceNumber = 0\n\t) {\n\t\tsuper();\n\t\tthis.log = log;\n\t\tif (initialRevision !== undefined) {\n\t\t\tassert(Number.isInteger(initialRevision[0]), 0x628 /* revision must be an integer */);\n\t\t\tassert(\n\t\t\t\tthis.log.isSequencedRevision(initialRevision[0]),\n\t\t\t\t0x629 /* revision must correspond to the result of a SequencedEdit */\n\t\t\t);\n\t\t}\n\n\t\tthis.sequencedRevisionCache = new RevisionValueCache(\n\t\t\tCachingLogViewer.sequencedCacheSizeMax,\n\t\t\tminimumSequenceNumber,\n\t\t\tinitialRevision ?? [0, { view: baseView }]\n\t\t);\n\t\tthis.processEditStatus = processEditStatus ?? noop;\n\t\tthis.processSequencedEditResult = processSequencedEditResult ?? noop;\n\t\tthis.detachFromEditLog = this.log.registerEditAddedHandler(this.handleEditAdded.bind(this));\n\n\t\t// Registers a handler that is called when edits are evicted\n\t\tthis.log.registerEditEvictionHandler(this.evictCachedRevisions.bind(this));\n\t}\n\n\t/**\n\t * As a performance optimization, this method caches views generated by local edits if they are sequenced without\n\t * being interleaved with remote edits.\n\t */\n\tprivate handleEditAdded(edit: Edit<ChangeInternal>, isLocal: boolean, wasLocal: boolean): void {\n\t\t// Clear highestRevisionCacheEntry, since what revision is highest might change.\n\t\t// Note that as an optimization we could skip clearing this when a local edit is sequenced.\n\t\tthis.highestRevisionCacheEntry = undefined;\n\n\t\tif (isLocal) {\n\t\t\tthis.unappliedSelfEdits.push(edit.id);\n\t\t} else if (wasLocal) {\n\t\t\t// If the new sequenced edit was generated by this client, the corresponding cache entry (if there is one)\n\t\t\t// will be at the front of the queue. If the queue is empty, then a concurrent sequenced edit from remote client\n\t\t\t// must have invalidated the queue cache.\n\t\t\tconst entry = this.localRevisionCache.shift();\n\t\t\tif (entry !== undefined) {\n\t\t\t\tconst revision = this.log.numberOfSequencedEdits;\n\t\t\t\tconst { view } = entry;\n\t\t\t\tthis.sequencedRevisionCache.cacheValue(\n\t\t\t\t\trevision,\n\t\t\t\t\tentry.status === EditStatus.Applied\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tview,\n\t\t\t\t\t\t\t\tstatus: entry.status,\n\t\t\t\t\t\t\t\tsteps: entry.steps,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tview,\n\t\t\t\t\t\t\t\tstatus: entry.status,\n\t\t\t\t\t\t\t\tfailure: entry.failure,\n\t\t\t\t\t\t }\n\t\t\t\t);\n\t\t\t\tthis.handleSequencedEditResult(edit, entry, []);\n\t\t\t}\n\t\t} else {\n\t\t\t// Invalidate any cached results of applying edits which are ordered after `edit` (which are all remaining local edits)\n\t\t\tthis.localRevisionCache.clear();\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc LogViewer.getRevisionViewInMemory}\n\t */\n\tpublic getRevisionViewInMemory(revision: number): RevisionView {\n\t\treturn this.getEditResultInMemory(revision).view;\n\t}\n\n\t/**\n\t * @returns the {@link EditCacheEntry} for the requested revision\n\t */\n\tpublic getEditResultInMemory(revision: Revision): EditCacheEntry {\n\t\tassert(revision >= this.log.earliestAvailableEditIndex, 0x62a /* revision not stored in memory */);\n\t\tconst startingPoint = this.getStartingPoint(revision);\n\t\tconst { startRevision } = startingPoint;\n\t\tlet current: EditCacheEntry = startingPoint;\n\t\tfor (let i = startRevision; i < revision && i < this.log.length; i++) {\n\t\t\tconst edit = this.log.tryGetEditAtIndex(i) ?? fail('edit not found');\n\t\t\tcurrent = this.applyEdit(current.view, edit, i);\n\t\t}\n\t\treturn current;\n\t}\n\n\t/**\n\t * Informs the CachingLogViewer of the latest known minimumSequenceNumber for all connected clients.\n\t * This can be used to provide more aggressive caching of revisions within the collaboration window, as those revisions\n\t * are more likely to be demanded to resolve conflicts.\n\t * @param minSequenceNumber - the minimum known sequence number of all connected clients.\n\t */\n\tpublic setMinimumSequenceNumber(minimumSequenceNumber: number): void {\n\t\t// Sequence numbers in Fluid are 1-indexed, meaning they correspond to revisions, and can be used as revisions.\n\t\t// This ensures that all revisions >= minimumSequenceNumber are kept in the cache, meaning that even if all clients are caught up\n\t\t// the most recent sequenced revision will be cached.\n\t\tthis.sequencedRevisionCache.updateRetentionWindow(minimumSequenceNumber);\n\t}\n\n\t/**\n\t * Inform the CachingLogViewer that a particular edit is known to have a specific result when applied to a particular TreeView.\n\t * CachingLogViewer may use this information as an optimization to avoid re-running the edit if re-applied to the same TreeView.\n\t */\n\tpublic setKnownEditingResult(edit: Edit<ChangeInternal>, result: EditingResult): void {\n\t\tthis.cachedEditResult = { editId: edit.id, result };\n\t}\n\n\t/**\n\t * Handler that is called before the stored edit log evicts any edits.\n\t * This caches the revision that corresponds to the edit that will be the oldest in memory after eviction\n\t * to ensure that there is always a base revision that any in memory edit can be applied to.\n\t */\n\tprivate evictCachedRevisions(editsToEvict: number): void {\n\t\tconst revisionToRetain = this.log.earliestAvailableEditIndex + editsToEvict;\n\t\tconst cacheEntry: EditCacheEntry = this.getEditResultInMemory(revisionToRetain);\n\t\tthis.sequencedRevisionCache.cacheRetainedValue(revisionToRetain, cacheEntry);\n\t\tthis.emit(CachingLogViewerDiagnosticEvents.RevisionRetained, revisionToRetain);\n\t}\n\n\t/**\n\t * @returns the cached revision view closest to the requested `revision`.\n\t */\n\tprivate getStartingPoint(revision: Revision): { startRevision: Revision } & EditCacheEntry {\n\t\t// Per the documentation for revision, the returned view should be the output of the edit at the largest index <= `revision`.\n\t\tconst revisionClamped = Math.min(revision, this.log.length);\n\n\t\t// If the highest revision is requested, and it's cached, use highestRevisionCacheEntry.\n\t\tif (revisionClamped === this.log.length && this.highestRevisionCacheEntry !== undefined) {\n\t\t\treturn { ...this.highestRevisionCacheEntry, startRevision: revisionClamped };\n\t\t}\n\n\t\tlet current: EditCacheEntry;\n\t\tlet startRevision: Revision;\n\t\tconst { numberOfSequencedEdits } = this.log;\n\t\tconst isLocalRevision = revisionClamped > numberOfSequencedEdits;\n\t\tif (isLocalRevision && !this.localRevisionCache.isEmpty()) {\n\t\t\tconst { length } = this.localRevisionCache;\n\t\t\t// Local revision view cache is indexed such that the view for revision 0 (a local edit) is stored at index 0 in the cache.\n\t\t\t// This is because the local cache does not contain an entry for the implicit initial tree edit.\n\t\t\tconst localCacheIndex = revisionClamped - 1 - numberOfSequencedEdits;\n\t\t\tif (localCacheIndex < length) {\n\t\t\t\tconst cached =\n\t\t\t\t\tthis.localRevisionCache.peekAt(localCacheIndex) ?? fail('missing tail of localRevisionViewCache');\n\t\t\t\treturn {\n\t\t\t\t\t...cached,\n\t\t\t\t\tstartRevision: revisionClamped,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tcurrent = this.localRevisionCache.peekAt(length - 1) ?? fail('missing tail of localRevisionViewCache');\n\t\t\t\tstartRevision = numberOfSequencedEdits + length;\n\t\t\t}\n\t\t} else {\n\t\t\tconst [cachedRevision, cachedView] =\n\t\t\t\tthis.sequencedRevisionCache.getClosestEntry(revisionClamped) ??\n\t\t\t\tfail('No preceding revision view cached.');\n\n\t\t\tstartRevision = cachedRevision;\n\t\t\tcurrent = cachedView;\n\t\t}\n\t\treturn { startRevision, ...current };\n\t}\n\n\t/**\n\t * Helper for applying an edit at the supplied revision view.\n\t * Must only be called in the order that edits appear in the log.\n\t * Must only be called once for a given local edit as long as the local cache has not been invalidated.\n\t * Must only be called once for a given sequenced edit.\n\t * @returns the resulting revision view and the outcome of edit that produced it.\n\t */\n\tprivate applyEdit(\n\t\tprevView: RevisionView,\n\t\tedit: Edit<ChangeInternal>,\n\t\teditIndex: number\n\t): AttemptedEditResultCacheEntry {\n\t\tlet editingResult: EditingResult;\n\t\tlet cached;\n\t\tlet reconciliationPath: ReconciliationPath = [];\n\t\tif (\n\t\t\tthis.cachedEditResult !== undefined &&\n\t\t\tthis.cachedEditResult.editId === edit.id &&\n\t\t\tthis.cachedEditResult.result.before === prevView\n\t\t) {\n\t\t\teditingResult = this.cachedEditResult.result;\n\t\t\tcached = true;\n\t\t} else {\n\t\t\treconciliationPath = this.reconciliationPathFromEdit(edit.id);\n\t\t\teditingResult = TransactionInternal.factory(prevView)\n\t\t\t\t.applyChanges(edit.changes, reconciliationPath)\n\t\t\t\t.close();\n\t\t\tcached = false;\n\t\t}\n\n\t\tconst revision = editIndex + 1;\n\t\tconst nextView: RevisionView = editingResult.status === EditStatus.Applied ? editingResult.after : prevView;\n\n\t\tconst computedCacheEntry =\n\t\t\teditingResult.status === EditStatus.Applied\n\t\t\t\t? { view: nextView, status: editingResult.status, steps: editingResult.steps }\n\t\t\t\t: { view: nextView, status: editingResult.status, failure: editingResult.failure };\n\n\t\tif (this.log.isSequencedRevision(revision)) {\n\t\t\tthis.sequencedRevisionCache.cacheValue(revision, computedCacheEntry);\n\t\t\tthis.handleSequencedEditResult(edit, computedCacheEntry, reconciliationPath);\n\t\t} else {\n\t\t\t// This relies on local edits being append only, and that generating the view for a local revision requires generating\n\t\t\t// the views for all local revisions before it in the log. Thus, generating such a view will necessarily require\n\t\t\t// calls to this method for all local revisions prior, guaranteeing the correct push order.\n\t\t\tassert(\n\t\t\t\trevision === this.log.numberOfSequencedEdits + this.localRevisionCache.length + 1,\n\t\t\t\t0x62b /* Local revision view cached out of order. */\n\t\t\t);\n\t\t\tthis.localRevisionCache.push(computedCacheEntry);\n\t\t}\n\n\t\t// Only update highestRevisionCacheEntry if this snapshot is the highest revision.\n\t\tif (revision >= this.log.length) {\n\t\t\tthis.highestRevisionCacheEntry = computedCacheEntry;\n\t\t}\n\n\t\tthis.processEditStatus(editingResult.status, this.log.getIdAtIndex(editIndex), cached);\n\t\treturn computedCacheEntry;\n\t}\n\n\t/**\n\t * Helper for performing caching when a sequenced local edit is first applied.\n\t * Invokes the `processSequencedEditResult` handler that was passed to the constructor (if any).\n\t * Must only be called for non-cached sequenced edits.\n\t */\n\tprivate handleSequencedEditResult(\n\t\tedit: Edit<ChangeInternal>,\n\t\tresult: AttemptedEditResultCacheEntry,\n\t\treconciliationPath: ReconciliationPath\n\t): void {\n\t\tlet wasLocal = false;\n\t\t// This is the first time this sequenced edit has been processed by this LogViewer. If it was a local edit, log telemetry\n\t\t// in the event that it was invalid or malformed.\n\t\tif (this.unappliedSelfEdits.length > 0) {\n\t\t\tif (edit.id === this.unappliedSelfEdits.peekFront()) {\n\t\t\t\twasLocal = true;\n\t\t\t\tthis.unappliedSelfEdits.shift();\n\t\t\t}\n\t\t}\n\t\tthis.processSequencedEditResult({ edit, wasLocal, result, reconciliationPath });\n\t}\n\n\t/**\n\t * We currently compute only the \"main branch\" part of the reconciliation path (meaning we don't include inverts of the edits\n\t * that occurred on the rebased branch). Doing so is only needed for the sequential anchor resolution approach which is not\n\t * yet supported.\n\t * @param editId - The ID for the edit to get the reconciliation path for.\n\t */\n\tpublic reconciliationPathFromEdit(editId: EditId): ReconciliationPath {\n\t\tconst reconciliationPath: ReconciliationEdit[] = [];\n\t\tlet cached = false;\n\t\treturn new Proxy(reconciliationPath, {\n\t\t\tget: (target, prop): unknown => {\n\t\t\t\tif (!cached) {\n\t\t\t\t\tcached = true;\n\t\t\t\t\tconst orderedId = this.log.getOrderedEditId(editId);\n\t\t\t\t\tif (orderedId.isLocal === false && orderedId.sequenceInfo !== undefined) {\n\t\t\t\t\t\tconst earliestSequenced = this.earliestSequencedEditInMemory();\n\t\t\t\t\t\tif (earliestSequenced !== undefined) {\n\t\t\t\t\t\t\tconst earliestEditSequenceNumber = earliestSequenced.sequenceNumber;\n\t\t\t\t\t\t\tconst targetSequenceNumber = Math.max(\n\t\t\t\t\t\t\t\tearliestEditSequenceNumber,\n\t\t\t\t\t\t\t\torderedId.sequenceInfo.referenceSequenceNumber\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (targetSequenceNumber < orderedId.sequenceInfo.sequenceNumber) {\n\t\t\t\t\t\t\t\tconst firstEdit = this.getEditResultFromSequenceNumber(targetSequenceNumber);\n\t\t\t\t\t\t\t\tif (firstEdit !== undefined) {\n\t\t\t\t\t\t\t\t\tif (firstEdit.status === EditStatus.Applied) {\n\t\t\t\t\t\t\t\t\t\tconst firstEditInfo = this.log.getOrderedEditId(\n\t\t\t\t\t\t\t\t\t\t\tfirstEdit.id\n\t\t\t\t\t\t\t\t\t\t) as SequencedOrderedEditId;\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tfirstEditInfo.sequenceInfo !== undefined &&\n\t\t\t\t\t\t\t\t\t\t\tfirstEditInfo.sequenceInfo.sequenceNumber >\n\t\t\t\t\t\t\t\t\t\t\t\torderedId.sequenceInfo.referenceSequenceNumber\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\treconciliationPath.push({\n\t\t\t\t\t\t\t\t\t\t\t\t...firstEdit.steps,\n\t\t\t\t\t\t\t\t\t\t\t\tbefore: firstEdit.before,\n\t\t\t\t\t\t\t\t\t\t\t\tafter: firstEdit.view,\n\t\t\t\t\t\t\t\t\t\t\t\tlength: firstEdit.steps.length,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst lowestIndex = this.log.getIndexOfId(firstEdit.id) + 1;\n\t\t\t\t\t\t\t\t\tconst highestIndex = this.log.getIndexOfId(editId) - 1;\n\t\t\t\t\t\t\t\t\tfor (let index = lowestIndex; index <= highestIndex; ++index) {\n\t\t\t\t\t\t\t\t\t\tconst edit = this.getEditResultFromIndex(index);\n\t\t\t\t\t\t\t\t\t\tif (edit.status === EditStatus.Applied) {\n\t\t\t\t\t\t\t\t\t\t\treconciliationPath.push({\n\t\t\t\t\t\t\t\t\t\t\t\t...edit.steps,\n\t\t\t\t\t\t\t\t\t\t\t\tbefore: edit.before,\n\t\t\t\t\t\t\t\t\t\t\t\tafter: edit.view,\n\t\t\t\t\t\t\t\t\t\t\t\tlength: edit.steps.length,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\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\treturn target[prop];\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * @returns Edit information for the earliest known sequenced edit.\n\t */\n\tpublic earliestSequencedEditInMemory(): { edit: Edit<ChangeInternal>; sequenceNumber: number } | undefined {\n\t\tconst earliestEditIndex = this.log.earliestAvailableEditIndex;\n\t\tconst lastSequencedEdit = this.log.numberOfSequencedEdits + earliestEditIndex - 1;\n\t\tfor (let index = earliestEditIndex; index <= lastSequencedEdit; ++index) {\n\t\t\tconst edit = this.log.tryGetEditAtIndex(index);\n\t\t\tif (edit !== undefined) {\n\t\t\t\tconst editOrderedId = this.log.getOrderedEditId(edit.id) as SequencedOrderedEditId;\n\t\t\t\tif (editOrderedId.sequenceInfo !== undefined) {\n\t\t\t\t\treturn { edit, sequenceNumber: editOrderedId.sequenceInfo.sequenceNumber };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * @returns Edit result information for the edit at the given `index`.\n\t */\n\tprivate getEditResultFromIndex(index: number): CachedEditingResult {\n\t\tconst edit = this.log.tryGetEditAtIndex(index) ?? fail('edit does not exist in memory');\n\t\tconst before = this.getRevisionViewInMemory(index);\n\t\tconst resultAfter = this.getEditResultInMemory(index + 1);\n\t\tif (resultAfter.status === undefined) {\n\t\t\tfail('The status of every edit in memory should be known');\n\t\t}\n\t\treturn resultAfter.status === EditStatus.Applied\n\t\t\t? {\n\t\t\t\t\tid: edit.id,\n\t\t\t\t\tstatus: EditStatus.Applied,\n\t\t\t\t\tbefore,\n\t\t\t\t\tchanges: edit.changes,\n\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\tsteps: resultAfter.steps,\n\t\t\t }\n\t\t\t: {\n\t\t\t\t\tid: edit.id,\n\t\t\t\t\tstatus: resultAfter.status,\n\t\t\t\t\tfailure: resultAfter.failure,\n\t\t\t\t\tbefore,\n\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\tchanges: edit.changes,\n\t\t\t };\n\t}\n\n\t/**\n\t * @param sequenceNumber - The server-assigned sequenced number assigned to the edit of interest.\n\t * @returns Edit result information for the edit with the given sequence number or the nearest sequenced edit before that.\n\t * Undefined if no sequenced edit occurred at or prior to the given sequenceNumber.\n\t */\n\tpublic getEditResultFromSequenceNumber(sequenceNumber: number): CachedEditingResult | undefined {\n\t\tconst earliestSequenced = this.earliestSequencedEditInMemory();\n\t\tif (earliestSequenced !== undefined && sequenceNumber >= earliestSequenced.sequenceNumber) {\n\t\t\tconst lowestIndex = this.log.getIndexOfId(earliestSequenced.edit.id);\n\t\t\tconst highestIndex = this.log.numberOfSequencedEdits - 1;\n\t\t\tfor (let index = highestIndex; index >= lowestIndex; --index) {\n\t\t\t\tconst edit = this.log.tryGetEditAtIndex(index);\n\t\t\t\tif (edit !== undefined) {\n\t\t\t\t\tconst orderedId = this.log.getOrderedEditId(edit.id) as SequencedOrderedEditId;\n\t\t\t\t\t// If `orderedId.sequenceInfo.sequenceNumber` is equal to the requested `sequenceNumber` then we have found the edit of\n\t\t\t\t\t// interest and simply return its associated information.\n\t\t\t\t\t// Note that the check bellow also is also satisfied if `orderedId.sequenceInfo.sequenceNumber`is lower than the requested\n\t\t\t\t\t// `sequenceNumber`. This can happen when the edit for the requested `sequenceNumber` has either not yet been received or\n\t\t\t\t\t// has been processed by a different DDS (several DDSes can share the same stream of operations and will only see those\n\t\t\t\t\t// relevant to them). In such cases, we return the edit info for the last known edit before that.\n\t\t\t\t\tif (orderedId.sequenceInfo && orderedId.sequenceInfo.sequenceNumber <= sequenceNumber) {\n\t\t\t\t\t\tconst before = this.getRevisionViewInMemory(index);\n\t\t\t\t\t\tconst resultAfter = this.getEditResultInMemory(index + 1);\n\t\t\t\t\t\tif (resultAfter.status === undefined) {\n\t\t\t\t\t\t\tfail('The status of every edit in session should be known');\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn resultAfter.status === EditStatus.Applied\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tid: edit.id,\n\t\t\t\t\t\t\t\t\tstatus: EditStatus.Applied,\n\t\t\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\t\t\tchanges: edit.changes,\n\t\t\t\t\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\t\t\t\t\tsteps: resultAfter.steps,\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\tid: edit.id,\n\t\t\t\t\t\t\t\t\tstatus: resultAfter.status,\n\t\t\t\t\t\t\t\t\tfailure: resultAfter.failure,\n\t\t\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\t\t\t\t\tchanges: edit.changes,\n\t\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\treturn undefined;\n\t}\n\n\t// DEPRECATED APIS\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported, do not use the asynchronous APIs.\n\t */\n\tpublic async getEditResult(revision: Revision): Promise<EditCacheEntry> {\n\t\treturn this.getEditResultInMemory(revision);\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported, use {@link LogViewer.getRevisionViewInMemory}\n\t */\n\tpublic async getRevisionView(revision: Revision): Promise<RevisionView> {\n\t\treturn this.getEditResultInMemory(revision).view;\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported, do not use the 'InSession' APIs.\n\t */\n\tpublic getEditResultInSession(revision: Revision): EditCacheEntry {\n\t\treturn this.getEditResultInMemory(revision);\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported, use {@link LogViewer.getRevisionViewInMemory}\n\t */\n\tpublic getRevisionViewInSession(revision: Revision): RevisionView {\n\t\treturn this.getEditResultInMemory(revision).view;\n\t}\n}\n"]}
1
+ {"version":3,"file":"LogViewer.js","sourceRoot":"","sources":["../src/LogViewer.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 Denque from 'denque';\nimport { TypedEventEmitter } from '@fluid-internal/client-utils';\nimport { IEvent } from '@fluidframework/core-interfaces';\nimport { assert } from '@fluidframework/core-utils';\nimport { fail, noop } from './Common';\nimport { EditLog, SequencedOrderedEditId } from './EditLog';\nimport { EditId } from './Identifiers';\nimport { Revision, RevisionValueCache } from './RevisionValueCache';\nimport { ReconciliationChange, ReconciliationEdit, ReconciliationPath } from './ReconciliationPath';\nimport { ChangeInternal, Edit, EditStatus } from './persisted-types';\nimport { RevisionView } from './RevisionView';\nimport { EditingResult, TransactionInternal } from './TransactionInternal';\n\n/**\n * Callback for when an edit is applied (meaning the result of applying it to a particular revision is computed).\n *\n * Edits may be applied any time a TreeView is computed that includes them.\n * Depending on the caching policy of the LogViewer, a given edit may or may not be applied in order to compute a TreeView containing it.\n *\n * If the same edit occurs in different contexts (ex: a local edit is adjusted for a new remote edit),\n * that it will be reapplied, and this may result in different results.\n *\n * Edits may additionally be reapplied at other times since their previous output might not be cached.\n *\n * If an application requests the current view, this will force all edits to be applied.\n * Such an application can use this callback can be log each edit as it comes it to see its status,\n * however this may include duplicates, as well as entries for reapplications in modified contexts.\n *\n * In the context of this callback,\n * skipping the first evaluation of an edit in a particular context due to setKnownEditingResult is still considered applying.\n * To use this call back to track when the actual computational work of applying edits is done, only count cases when `wasCached` is false.\n */\nexport type EditStatusCallback = (editResult: EditStatus, editId: EditId, wasCached: boolean) => void;\n\n/**\n * Callback for when a sequenced edit is applied.\n * This includes local edits though the callback is only invoked once the sequenced version is received.\n *\n * For edits that were local (see {@link SequencedEditResult.wasLocal}, this callback will only be called once.\n * For non-local edits, it may be called multiple times: the number of calls and when they occur depends on caching and is an implementation\n * detail.\n */\nexport type SequencedEditResultCallback = (args: SequencedEditResult) => void;\n\n/**\n * The relevant information pertaining to the application of a sequenced edit.\n */\nexport interface SequencedEditResult {\n\t/**\n\t * The edit that was applied.\n\t */\n\tedit: Edit<ChangeInternal>;\n\t/**\n\t * true iff the edit was local.\n\t */\n\twasLocal: boolean;\n\t/**\n\t * The result of applying the edit.\n\t */\n\tresult: AttemptedEditResultCacheEntry;\n\t/**\n\t * The reconciliation path for the edit.\n\t */\n\treconciliationPath: ReconciliationPath;\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit.\n */\nexport type EditCacheEntry = SuccessfulEditCacheEntry | UnsuccessfulEditCacheEntry | SummarizedEditResultCacheEntry;\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has attempted to apply locally.\n */\nexport type AttemptedEditResultCacheEntry = SuccessfulEditCacheEntry | UnsuccessfulEditCacheEntry;\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has successfully applied locally.\n */\nexport interface SuccessfulEditCacheEntry {\n\t/**\n\t * The revision view resulting from the edit.\n\t */\n\treadonly view: RevisionView;\n\t/**\n\t * The status code for the edit that produced the revision.\n\t */\n\treadonly status: EditStatus.Applied;\n\t/**\n\t * The resolved changes that were applied during the edit and their associated outcome.\n\t */\n\treadonly steps: readonly ReconciliationChange[];\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has unsuccessfully attempted to apply locally.\n */\nexport interface UnsuccessfulEditCacheEntry {\n\t/**\n\t * The revision view resulting from the edit.\n\t */\n\treadonly view: RevisionView;\n\t/**\n\t * The status code for the edit that produced the revision.\n\t */\n\treadonly status: EditStatus.Invalid | EditStatus.Malformed;\n\t/**\n\t * Information about the failure encountered by the edit\n\t */\n\treadonly failure: TransactionInternal.Failure;\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has retrieved from a summary.\n * TODO:#57176: once summarized edits carry enough information remove this interface and use `AttemptedEditResultCacheEntry` instead.\n */\nexport interface SummarizedEditResultCacheEntry {\n\t/**\n\t * The revision view resulting from the edit.\n\t */\n\treadonly view: RevisionView;\n\t/**\n\t * Not specified on `SummarizedEditResultCacheEntry`.\n\t * Declared to allow checking `entry.status` against undefined.\n\t */\n\treadonly status?: never;\n}\n\nexport type CachedEditingResult = AttemptedEditResultCacheEntry & {\n\t/**\n\t * Unique identifier for this edit. Must never be reused.\n\t * Used for referencing and de-duplicating edits.\n\t */\n\treadonly id: EditId;\n\treadonly before: RevisionView;\n\treadonly changes: readonly ChangeInternal[];\n};\n\n/**\n * Creates `RevisionView`s for the revisions in an `EditLog`\n * @alpha\n */\nexport interface LogViewer {\n\t/**\n\t * Returns the `TreeView` output associated with the largest revision in `editLog` less than (but not equal to) the supplied revision.\n\t *\n\t * For example:\n\t *\n\t * - revision 0 returns the initialRevision.\n\t *\n\t * - revision 1 returns the output of editLog[0] (or initialRevision if there is no edit 0).\n\t *\n\t * - revision Number.POSITIVE_INFINITY returns the newest revision.\n\t *\n\t * @deprecated Edit virtualization is no longer supported, use {@link LogViewer.getRevisionViewInMemory}\n\t */\n\tgetRevisionView(revision: Revision): Promise<RevisionView>;\n\n\t/**\n\t * Returns the `TreeView` output associated with the largest revision in `editLog` less than (but not equal to) the supplied revision.\n\t * Can only be used to retrieve revisions added during the current sessions.\n\t *\n\t * For example:\n\t *\n\t * - revision 0 returns the initialRevision.\n\t *\n\t * - revision 1 returns the output of editLog[0] (or initialRevision if there is no edit 0).\n\t *\n\t * - revision Number.POSITIVE_INFINITY returns the newest revision.\n\t *\n\t * @deprecated Edit virtualization is no longer supported so the 'inSession' APIs will be removed, use {@link LogViewer.getRevisionViewInMemory}\n\t */\n\tgetRevisionViewInSession(revision: Revision): RevisionView;\n\n\t/**\n\t * Returns the `TreeView` output associated with the largest revision in `editLog` less than (but not equal to) the supplied revision.\n\t * Can only be used to retrieve revisions added during the current session that have not been evicted from `editLog`.\n\t *\n\t * For example:\n\t *\n\t * - revision 0 returns the oldest edit in the log (which might be initialRevision).\n\t *\n\t * - revision 1 returns the output of editLog[0] (or initialRevision if there is no edit 0).\n\t *\n\t * - revision Number.POSITIVE_INFINITY returns the newest revision.\n\t */\n\tgetRevisionViewInMemory(revision: Revision): RevisionView;\n}\n\n/**\n * Events reported by {@link CachingLogViewer} for diagnostics or testing purposes.\n */\nexport enum CachingLogViewerDiagnosticEvents {\n\tRevisionRetained = 'revisionRetained',\n}\n\n/**\n * Events which may be emitted by {@link CachingLogViewer}\n * @public\n */\nexport interface ICachingLogViewerEvents extends IEvent {\n\t(event: CachingLogViewerDiagnosticEvents.RevisionRetained, listener: (revision: Revision) => void);\n}\n\n/**\n * Creates views for revisions associated with an EditLog and caches the results.\n *\n * Does so by listening for edits added to the log. If the underlying EditLog or its listeners need to be reused beyond the lifetime of\n * a CachingLogViewer instance, that instance should be disposed with `detachFromEditLog` to ensure it is garbage-collectable.\n * @alpha\n */\nexport class CachingLogViewer extends TypedEventEmitter<ICachingLogViewerEvents> implements LogViewer {\n\tpublic readonly log: EditLog<ChangeInternal>;\n\n\t/**\n\t * Maximum size of the sequenced revision cache.\n\t */\n\tpublic static readonly sequencedCacheSizeMax = 50;\n\n\t/**\n\t * A cache for local revisions.\n\t * It is invalidated whenever a new sequenced edit (that was not already a local edit) is added to the log.\n\t * When a previously local edit is sequenced, this cache is adjusted to account for it, not invalidated.\n\t */\n\tprivate readonly localRevisionCache = new Denque<AttemptedEditResultCacheEntry>();\n\n\t/**\n\t * Cache of sequenced revisions.\n\t */\n\tprivate readonly sequencedRevisionCache: RevisionValueCache<EditCacheEntry>;\n\n\t/**\n\t * Called whenever a sequenced edit is applied.\n\t * This will have been called at least once for any edit if a revision after than edit has been requested.\n\t * It may be called multiple times: the number of calls and when they occur depends on caching and is an implementation detail.\n\t */\n\tprivate readonly processSequencedEditResult: SequencedEditResultCallback;\n\n\t/**\n\t * Called whenever an edit is processed.\n\t * This will have been called at least once for any edit if a revision after than edit has been requested.\n\t * It may be called multiple times: the number of calls and when they occur depends on caching and is an implementation detail.\n\t */\n\tprivate readonly processEditStatus: EditStatusCallback;\n\n\t/**\n\t * The ordered queue of edits that originated from this client that have never been applied (by this log viewer) in a sequenced state.\n\t * This means these edits may be local or sequenced, and may have been applied (possibly multiple times) while still local.\n\t * Used to log telemetry about the result of edit application. Edits are removed when first applied after being sequenced.\n\t */\n\tprivate readonly unappliedSelfEdits = new Denque<EditId>();\n\n\t/**\n\t * Cache of applying a edit.\n\t * Due to use of Transactions in checkouts, a common pattern involves applying an edit\n\t * as part of the transaction, then submitting it.\n\t * This cache helps optimize that case by avoiding recomputing the edit if no other edits were added during the transaction.\n\t */\n\tprivate cachedEditResult?: { editId: EditId; result: EditingResult };\n\n\t/**\n\t * Cache entry for the highest revision.\n\t * `undefined` when not cached.\n\t */\n\tprivate highestRevisionCacheEntry?: EditCacheEntry;\n\n\t/**\n\t * Removes this log viewer from the set of handleEditAdded listeners on its underlying log.\n\t * This should be called if the underlying log or its listeners are re-used past the lifetime of this log viewer.\n\t */\n\tpublic readonly detachFromEditLog: () => void;\n\n\t/**\n\t * @returns true if the highest revision is cached.\n\t */\n\tpublic highestRevisionCached(): boolean {\n\t\treturn this.highestRevisionCacheEntry !== undefined;\n\t}\n\n\t/**\n\t * Create a new LogViewer\n\t * @param log - the edit log which revisions will be based on.\n\t * @param baseTree - the tree used in the view corresponding to the 0th revision.\n\t * @param initialRevision - a [sequencedRevision, view] pair that is known (been precomputed) at construction time.\n\t * This revision is guaranteed to never be evicted from the cache unless it is replaced as the oldest in memory revision.\n\t * @param expensiveValidation - Iff true, additional correctness assertions will be run during LogViewer operations.\n\t * @param processEditStatus - called after applying an edit.\n\t * @param processSequencedEditResult - called after applying a sequenced edit.\n\t */\n\tpublic constructor(\n\t\tlog: EditLog<ChangeInternal>,\n\t\tbaseView: RevisionView,\n\t\tinitialRevision?: [Revision, EditCacheEntry],\n\t\tprocessEditStatus: EditStatusCallback = noop,\n\t\tprocessSequencedEditResult: SequencedEditResultCallback = noop,\n\t\tminimumSequenceNumber = 0\n\t) {\n\t\tsuper();\n\t\tthis.log = log;\n\t\tif (initialRevision !== undefined) {\n\t\t\tassert(Number.isInteger(initialRevision[0]), 0x628 /* revision must be an integer */);\n\t\t\tassert(\n\t\t\t\tthis.log.isSequencedRevision(initialRevision[0]),\n\t\t\t\t0x629 /* revision must correspond to the result of a SequencedEdit */\n\t\t\t);\n\t\t}\n\n\t\tthis.sequencedRevisionCache = new RevisionValueCache(\n\t\t\tCachingLogViewer.sequencedCacheSizeMax,\n\t\t\tminimumSequenceNumber,\n\t\t\tinitialRevision ?? [0, { view: baseView }]\n\t\t);\n\t\tthis.processEditStatus = processEditStatus ?? noop;\n\t\tthis.processSequencedEditResult = processSequencedEditResult ?? noop;\n\t\tthis.detachFromEditLog = this.log.registerEditAddedHandler(this.handleEditAdded.bind(this));\n\n\t\t// Registers a handler that is called when edits are evicted\n\t\tthis.log.registerEditEvictionHandler(this.evictCachedRevisions.bind(this));\n\t}\n\n\t/**\n\t * As a performance optimization, this method caches views generated by local edits if they are sequenced without\n\t * being interleaved with remote edits.\n\t */\n\tprivate handleEditAdded(edit: Edit<ChangeInternal>, isLocal: boolean, wasLocal: boolean): void {\n\t\t// Clear highestRevisionCacheEntry, since what revision is highest might change.\n\t\t// Note that as an optimization we could skip clearing this when a local edit is sequenced.\n\t\tthis.highestRevisionCacheEntry = undefined;\n\n\t\tif (isLocal) {\n\t\t\tthis.unappliedSelfEdits.push(edit.id);\n\t\t} else if (wasLocal) {\n\t\t\t// If the new sequenced edit was generated by this client, the corresponding cache entry (if there is one)\n\t\t\t// will be at the front of the queue. If the queue is empty, then a concurrent sequenced edit from remote client\n\t\t\t// must have invalidated the queue cache.\n\t\t\tconst entry = this.localRevisionCache.shift();\n\t\t\tif (entry !== undefined) {\n\t\t\t\tconst revision = this.log.numberOfSequencedEdits;\n\t\t\t\tconst { view } = entry;\n\t\t\t\tthis.sequencedRevisionCache.cacheValue(\n\t\t\t\t\trevision,\n\t\t\t\t\tentry.status === EditStatus.Applied\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tview,\n\t\t\t\t\t\t\t\tstatus: entry.status,\n\t\t\t\t\t\t\t\tsteps: entry.steps,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tview,\n\t\t\t\t\t\t\t\tstatus: entry.status,\n\t\t\t\t\t\t\t\tfailure: entry.failure,\n\t\t\t\t\t\t }\n\t\t\t\t);\n\t\t\t\tthis.handleSequencedEditResult(edit, entry, []);\n\t\t\t}\n\t\t} else {\n\t\t\t// Invalidate any cached results of applying edits which are ordered after `edit` (which are all remaining local edits)\n\t\t\tthis.localRevisionCache.clear();\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc LogViewer.getRevisionViewInMemory}\n\t */\n\tpublic getRevisionViewInMemory(revision: number): RevisionView {\n\t\treturn this.getEditResultInMemory(revision).view;\n\t}\n\n\t/**\n\t * @returns the {@link EditCacheEntry} for the requested revision\n\t */\n\tpublic getEditResultInMemory(revision: Revision): EditCacheEntry {\n\t\tassert(revision >= this.log.earliestAvailableEditIndex, 0x62a /* revision not stored in memory */);\n\t\tconst startingPoint = this.getStartingPoint(revision);\n\t\tconst { startRevision } = startingPoint;\n\t\tlet current: EditCacheEntry = startingPoint;\n\t\tfor (let i = startRevision; i < revision && i < this.log.length; i++) {\n\t\t\tconst edit = this.log.tryGetEditAtIndex(i) ?? fail('edit not found');\n\t\t\tcurrent = this.applyEdit(current.view, edit, i);\n\t\t}\n\t\treturn current;\n\t}\n\n\t/**\n\t * Informs the CachingLogViewer of the latest known minimumSequenceNumber for all connected clients.\n\t * This can be used to provide more aggressive caching of revisions within the collaboration window, as those revisions\n\t * are more likely to be demanded to resolve conflicts.\n\t * @param minSequenceNumber - the minimum known sequence number of all connected clients.\n\t */\n\tpublic setMinimumSequenceNumber(minimumSequenceNumber: number): void {\n\t\t// Sequence numbers in Fluid are 1-indexed, meaning they correspond to revisions, and can be used as revisions.\n\t\t// This ensures that all revisions >= minimumSequenceNumber are kept in the cache, meaning that even if all clients are caught up\n\t\t// the most recent sequenced revision will be cached.\n\t\tthis.sequencedRevisionCache.updateRetentionWindow(minimumSequenceNumber);\n\t}\n\n\t/**\n\t * Inform the CachingLogViewer that a particular edit is known to have a specific result when applied to a particular TreeView.\n\t * CachingLogViewer may use this information as an optimization to avoid re-running the edit if re-applied to the same TreeView.\n\t */\n\tpublic setKnownEditingResult(edit: Edit<ChangeInternal>, result: EditingResult): void {\n\t\tthis.cachedEditResult = { editId: edit.id, result };\n\t}\n\n\t/**\n\t * Handler that is called before the stored edit log evicts any edits.\n\t * This caches the revision that corresponds to the edit that will be the oldest in memory after eviction\n\t * to ensure that there is always a base revision that any in memory edit can be applied to.\n\t */\n\tprivate evictCachedRevisions(editsToEvict: number): void {\n\t\tconst revisionToRetain = this.log.earliestAvailableEditIndex + editsToEvict;\n\t\tconst cacheEntry: EditCacheEntry = this.getEditResultInMemory(revisionToRetain);\n\t\tthis.sequencedRevisionCache.cacheRetainedValue(revisionToRetain, cacheEntry);\n\t\tthis.emit(CachingLogViewerDiagnosticEvents.RevisionRetained, revisionToRetain);\n\t}\n\n\t/**\n\t * @returns the cached revision view closest to the requested `revision`.\n\t */\n\tprivate getStartingPoint(revision: Revision): { startRevision: Revision } & EditCacheEntry {\n\t\t// Per the documentation for revision, the returned view should be the output of the edit at the largest index <= `revision`.\n\t\tconst revisionClamped = Math.min(revision, this.log.length);\n\n\t\t// If the highest revision is requested, and it's cached, use highestRevisionCacheEntry.\n\t\tif (revisionClamped === this.log.length && this.highestRevisionCacheEntry !== undefined) {\n\t\t\treturn { ...this.highestRevisionCacheEntry, startRevision: revisionClamped };\n\t\t}\n\n\t\tlet current: EditCacheEntry;\n\t\tlet startRevision: Revision;\n\t\tconst { numberOfSequencedEdits } = this.log;\n\t\tconst isLocalRevision = revisionClamped > numberOfSequencedEdits;\n\t\tif (isLocalRevision && !this.localRevisionCache.isEmpty()) {\n\t\t\tconst { length } = this.localRevisionCache;\n\t\t\t// Local revision view cache is indexed such that the view for revision 0 (a local edit) is stored at index 0 in the cache.\n\t\t\t// This is because the local cache does not contain an entry for the implicit initial tree edit.\n\t\t\tconst localCacheIndex = revisionClamped - 1 - numberOfSequencedEdits;\n\t\t\tif (localCacheIndex < length) {\n\t\t\t\tconst cached =\n\t\t\t\t\tthis.localRevisionCache.peekAt(localCacheIndex) ?? fail('missing tail of localRevisionViewCache');\n\t\t\t\treturn {\n\t\t\t\t\t...cached,\n\t\t\t\t\tstartRevision: revisionClamped,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tcurrent = this.localRevisionCache.peekAt(length - 1) ?? fail('missing tail of localRevisionViewCache');\n\t\t\t\tstartRevision = numberOfSequencedEdits + length;\n\t\t\t}\n\t\t} else {\n\t\t\tconst [cachedRevision, cachedView] =\n\t\t\t\tthis.sequencedRevisionCache.getClosestEntry(revisionClamped) ??\n\t\t\t\tfail('No preceding revision view cached.');\n\n\t\t\tstartRevision = cachedRevision;\n\t\t\tcurrent = cachedView;\n\t\t}\n\t\treturn { startRevision, ...current };\n\t}\n\n\t/**\n\t * Helper for applying an edit at the supplied revision view.\n\t * Must only be called in the order that edits appear in the log.\n\t * Must only be called once for a given local edit as long as the local cache has not been invalidated.\n\t * Must only be called once for a given sequenced edit.\n\t * @returns the resulting revision view and the outcome of edit that produced it.\n\t */\n\tprivate applyEdit(\n\t\tprevView: RevisionView,\n\t\tedit: Edit<ChangeInternal>,\n\t\teditIndex: number\n\t): AttemptedEditResultCacheEntry {\n\t\tlet editingResult: EditingResult;\n\t\tlet cached;\n\t\tlet reconciliationPath: ReconciliationPath = [];\n\t\tif (\n\t\t\tthis.cachedEditResult !== undefined &&\n\t\t\tthis.cachedEditResult.editId === edit.id &&\n\t\t\tthis.cachedEditResult.result.before === prevView\n\t\t) {\n\t\t\teditingResult = this.cachedEditResult.result;\n\t\t\tcached = true;\n\t\t} else {\n\t\t\treconciliationPath = this.reconciliationPathFromEdit(edit.id);\n\t\t\teditingResult = TransactionInternal.factory(prevView)\n\t\t\t\t.applyChanges(edit.changes, reconciliationPath)\n\t\t\t\t.close();\n\t\t\tcached = false;\n\t\t}\n\n\t\tconst revision = editIndex + 1;\n\t\tconst nextView: RevisionView = editingResult.status === EditStatus.Applied ? editingResult.after : prevView;\n\n\t\tconst computedCacheEntry =\n\t\t\teditingResult.status === EditStatus.Applied\n\t\t\t\t? { view: nextView, status: editingResult.status, steps: editingResult.steps }\n\t\t\t\t: { view: nextView, status: editingResult.status, failure: editingResult.failure };\n\n\t\tif (this.log.isSequencedRevision(revision)) {\n\t\t\tthis.sequencedRevisionCache.cacheValue(revision, computedCacheEntry);\n\t\t\tthis.handleSequencedEditResult(edit, computedCacheEntry, reconciliationPath);\n\t\t} else {\n\t\t\t// This relies on local edits being append only, and that generating the view for a local revision requires generating\n\t\t\t// the views for all local revisions before it in the log. Thus, generating such a view will necessarily require\n\t\t\t// calls to this method for all local revisions prior, guaranteeing the correct push order.\n\t\t\tassert(\n\t\t\t\trevision === this.log.numberOfSequencedEdits + this.localRevisionCache.length + 1,\n\t\t\t\t0x62b /* Local revision view cached out of order. */\n\t\t\t);\n\t\t\tthis.localRevisionCache.push(computedCacheEntry);\n\t\t}\n\n\t\t// Only update highestRevisionCacheEntry if this snapshot is the highest revision.\n\t\tif (revision >= this.log.length) {\n\t\t\tthis.highestRevisionCacheEntry = computedCacheEntry;\n\t\t}\n\n\t\tthis.processEditStatus(editingResult.status, this.log.getIdAtIndex(editIndex), cached);\n\t\treturn computedCacheEntry;\n\t}\n\n\t/**\n\t * Helper for performing caching when a sequenced local edit is first applied.\n\t * Invokes the `processSequencedEditResult` handler that was passed to the constructor (if any).\n\t * Must only be called for non-cached sequenced edits.\n\t */\n\tprivate handleSequencedEditResult(\n\t\tedit: Edit<ChangeInternal>,\n\t\tresult: AttemptedEditResultCacheEntry,\n\t\treconciliationPath: ReconciliationPath\n\t): void {\n\t\tlet wasLocal = false;\n\t\t// This is the first time this sequenced edit has been processed by this LogViewer. If it was a local edit, log telemetry\n\t\t// in the event that it was invalid or malformed.\n\t\tif (this.unappliedSelfEdits.length > 0) {\n\t\t\tif (edit.id === this.unappliedSelfEdits.peekFront()) {\n\t\t\t\twasLocal = true;\n\t\t\t\tthis.unappliedSelfEdits.shift();\n\t\t\t}\n\t\t}\n\t\tthis.processSequencedEditResult({ edit, wasLocal, result, reconciliationPath });\n\t}\n\n\t/**\n\t * We currently compute only the \"main branch\" part of the reconciliation path (meaning we don't include inverts of the edits\n\t * that occurred on the rebased branch). Doing so is only needed for the sequential anchor resolution approach which is not\n\t * yet supported.\n\t * @param editId - The ID for the edit to get the reconciliation path for.\n\t */\n\tpublic reconciliationPathFromEdit(editId: EditId): ReconciliationPath {\n\t\tconst reconciliationPath: ReconciliationEdit[] = [];\n\t\tlet cached = false;\n\t\treturn new Proxy(reconciliationPath, {\n\t\t\tget: (target, prop): unknown => {\n\t\t\t\tif (!cached) {\n\t\t\t\t\tcached = true;\n\t\t\t\t\tconst orderedId = this.log.getOrderedEditId(editId);\n\t\t\t\t\tif (orderedId.isLocal === false && orderedId.sequenceInfo !== undefined) {\n\t\t\t\t\t\tconst earliestSequenced = this.earliestSequencedEditInMemory();\n\t\t\t\t\t\tif (earliestSequenced !== undefined) {\n\t\t\t\t\t\t\tconst earliestEditSequenceNumber = earliestSequenced.sequenceNumber;\n\t\t\t\t\t\t\tconst targetSequenceNumber = Math.max(\n\t\t\t\t\t\t\t\tearliestEditSequenceNumber,\n\t\t\t\t\t\t\t\torderedId.sequenceInfo.referenceSequenceNumber\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (targetSequenceNumber < orderedId.sequenceInfo.sequenceNumber) {\n\t\t\t\t\t\t\t\tconst firstEdit = this.getEditResultFromSequenceNumber(targetSequenceNumber);\n\t\t\t\t\t\t\t\tif (firstEdit !== undefined) {\n\t\t\t\t\t\t\t\t\tif (firstEdit.status === EditStatus.Applied) {\n\t\t\t\t\t\t\t\t\t\tconst firstEditInfo = this.log.getOrderedEditId(\n\t\t\t\t\t\t\t\t\t\t\tfirstEdit.id\n\t\t\t\t\t\t\t\t\t\t) as SequencedOrderedEditId;\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tfirstEditInfo.sequenceInfo !== undefined &&\n\t\t\t\t\t\t\t\t\t\t\tfirstEditInfo.sequenceInfo.sequenceNumber >\n\t\t\t\t\t\t\t\t\t\t\t\torderedId.sequenceInfo.referenceSequenceNumber\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\treconciliationPath.push({\n\t\t\t\t\t\t\t\t\t\t\t\t...firstEdit.steps,\n\t\t\t\t\t\t\t\t\t\t\t\tbefore: firstEdit.before,\n\t\t\t\t\t\t\t\t\t\t\t\tafter: firstEdit.view,\n\t\t\t\t\t\t\t\t\t\t\t\tlength: firstEdit.steps.length,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst lowestIndex = this.log.getIndexOfId(firstEdit.id) + 1;\n\t\t\t\t\t\t\t\t\tconst highestIndex = this.log.getIndexOfId(editId) - 1;\n\t\t\t\t\t\t\t\t\tfor (let index = lowestIndex; index <= highestIndex; ++index) {\n\t\t\t\t\t\t\t\t\t\tconst edit = this.getEditResultFromIndex(index);\n\t\t\t\t\t\t\t\t\t\tif (edit.status === EditStatus.Applied) {\n\t\t\t\t\t\t\t\t\t\t\treconciliationPath.push({\n\t\t\t\t\t\t\t\t\t\t\t\t...edit.steps,\n\t\t\t\t\t\t\t\t\t\t\t\tbefore: edit.before,\n\t\t\t\t\t\t\t\t\t\t\t\tafter: edit.view,\n\t\t\t\t\t\t\t\t\t\t\t\tlength: edit.steps.length,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\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\treturn target[prop];\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * @returns Edit information for the earliest known sequenced edit.\n\t */\n\tpublic earliestSequencedEditInMemory(): { edit: Edit<ChangeInternal>; sequenceNumber: number } | undefined {\n\t\tconst earliestEditIndex = this.log.earliestAvailableEditIndex;\n\t\tconst lastSequencedEdit = this.log.numberOfSequencedEdits + earliestEditIndex - 1;\n\t\tfor (let index = earliestEditIndex; index <= lastSequencedEdit; ++index) {\n\t\t\tconst edit = this.log.tryGetEditAtIndex(index);\n\t\t\tif (edit !== undefined) {\n\t\t\t\tconst editOrderedId = this.log.getOrderedEditId(edit.id) as SequencedOrderedEditId;\n\t\t\t\tif (editOrderedId.sequenceInfo !== undefined) {\n\t\t\t\t\treturn { edit, sequenceNumber: editOrderedId.sequenceInfo.sequenceNumber };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * @returns Edit result information for the edit at the given `index`.\n\t */\n\tprivate getEditResultFromIndex(index: number): CachedEditingResult {\n\t\tconst edit = this.log.tryGetEditAtIndex(index) ?? fail('edit does not exist in memory');\n\t\tconst before = this.getRevisionViewInMemory(index);\n\t\tconst resultAfter = this.getEditResultInMemory(index + 1);\n\t\tif (resultAfter.status === undefined) {\n\t\t\tfail('The status of every edit in memory should be known');\n\t\t}\n\t\treturn resultAfter.status === EditStatus.Applied\n\t\t\t? {\n\t\t\t\t\tid: edit.id,\n\t\t\t\t\tstatus: EditStatus.Applied,\n\t\t\t\t\tbefore,\n\t\t\t\t\tchanges: edit.changes,\n\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\tsteps: resultAfter.steps,\n\t\t\t }\n\t\t\t: {\n\t\t\t\t\tid: edit.id,\n\t\t\t\t\tstatus: resultAfter.status,\n\t\t\t\t\tfailure: resultAfter.failure,\n\t\t\t\t\tbefore,\n\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\tchanges: edit.changes,\n\t\t\t };\n\t}\n\n\t/**\n\t * @param sequenceNumber - The server-assigned sequenced number assigned to the edit of interest.\n\t * @returns Edit result information for the edit with the given sequence number or the nearest sequenced edit before that.\n\t * Undefined if no sequenced edit occurred at or prior to the given sequenceNumber.\n\t */\n\tpublic getEditResultFromSequenceNumber(sequenceNumber: number): CachedEditingResult | undefined {\n\t\tconst earliestSequenced = this.earliestSequencedEditInMemory();\n\t\tif (earliestSequenced !== undefined && sequenceNumber >= earliestSequenced.sequenceNumber) {\n\t\t\tconst lowestIndex = this.log.getIndexOfId(earliestSequenced.edit.id);\n\t\t\tconst highestIndex = this.log.numberOfSequencedEdits - 1;\n\t\t\tfor (let index = highestIndex; index >= lowestIndex; --index) {\n\t\t\t\tconst edit = this.log.tryGetEditAtIndex(index);\n\t\t\t\tif (edit !== undefined) {\n\t\t\t\t\tconst orderedId = this.log.getOrderedEditId(edit.id) as SequencedOrderedEditId;\n\t\t\t\t\t// If `orderedId.sequenceInfo.sequenceNumber` is equal to the requested `sequenceNumber` then we have found the edit of\n\t\t\t\t\t// interest and simply return its associated information.\n\t\t\t\t\t// Note that the check bellow also is also satisfied if `orderedId.sequenceInfo.sequenceNumber`is lower than the requested\n\t\t\t\t\t// `sequenceNumber`. This can happen when the edit for the requested `sequenceNumber` has either not yet been received or\n\t\t\t\t\t// has been processed by a different DDS (several DDSes can share the same stream of operations and will only see those\n\t\t\t\t\t// relevant to them). In such cases, we return the edit info for the last known edit before that.\n\t\t\t\t\tif (orderedId.sequenceInfo && orderedId.sequenceInfo.sequenceNumber <= sequenceNumber) {\n\t\t\t\t\t\tconst before = this.getRevisionViewInMemory(index);\n\t\t\t\t\t\tconst resultAfter = this.getEditResultInMemory(index + 1);\n\t\t\t\t\t\tif (resultAfter.status === undefined) {\n\t\t\t\t\t\t\tfail('The status of every edit in session should be known');\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn resultAfter.status === EditStatus.Applied\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tid: edit.id,\n\t\t\t\t\t\t\t\t\tstatus: EditStatus.Applied,\n\t\t\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\t\t\tchanges: edit.changes,\n\t\t\t\t\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\t\t\t\t\tsteps: resultAfter.steps,\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\tid: edit.id,\n\t\t\t\t\t\t\t\t\tstatus: resultAfter.status,\n\t\t\t\t\t\t\t\t\tfailure: resultAfter.failure,\n\t\t\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\t\t\t\t\tchanges: edit.changes,\n\t\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\treturn undefined;\n\t}\n\n\t// DEPRECATED APIS\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported, do not use the asynchronous APIs.\n\t */\n\tpublic async getEditResult(revision: Revision): Promise<EditCacheEntry> {\n\t\treturn this.getEditResultInMemory(revision);\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported, use {@link LogViewer.getRevisionViewInMemory}\n\t */\n\tpublic async getRevisionView(revision: Revision): Promise<RevisionView> {\n\t\treturn this.getEditResultInMemory(revision).view;\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported, do not use the 'InSession' APIs.\n\t */\n\tpublic getEditResultInSession(revision: Revision): EditCacheEntry {\n\t\treturn this.getEditResultInMemory(revision);\n\t}\n\n\t/**\n\t * @deprecated Edit virtualization is no longer supported, use {@link LogViewer.getRevisionViewInMemory}\n\t */\n\tpublic getRevisionViewInSession(revision: Revision): RevisionView {\n\t\treturn this.getEditResultInMemory(revision).view;\n\t}\n}\n"]}
@@ -7,13 +7,13 @@ import { FinalNodeId, NodeId, OpSpaceNodeId, SessionId, StableNodeId } from './I
7
7
  import { NodeData } from './persisted-types';
8
8
  /**
9
9
  * An object which can generate node IDs and convert node IDs between compressed and stable variants
10
- * @internal
10
+ * @alpha
11
11
  */
12
12
  export interface NodeIdContext extends NodeIdGenerator, NodeIdConverter {
13
13
  }
14
14
  /**
15
15
  * An object which can generate node IDs
16
- * @internal
16
+ * @alpha
17
17
  */
18
18
  export interface NodeIdGenerator {
19
19
  /**
@@ -31,7 +31,7 @@ export interface NodeIdGenerator {
31
31
  }
32
32
  /**
33
33
  * An object which can convert node IDs between compressed and stable variants
34
- * @internal
34
+ * @alpha
35
35
  */
36
36
  export interface NodeIdConverter {
37
37
  /**