@fluid-experimental/tree 0.58.3000-61081 → 0.59.2000-61729

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 (98) hide show
  1. package/README.md +156 -43
  2. package/dist/ChangeTypes.d.ts +9 -14
  3. package/dist/ChangeTypes.d.ts.map +1 -1
  4. package/dist/ChangeTypes.js.map +1 -1
  5. package/dist/Checkout.d.ts.map +1 -1
  6. package/dist/Checkout.js +3 -2
  7. package/dist/Checkout.js.map +1 -1
  8. package/dist/LogViewer.d.ts +2 -3
  9. package/dist/LogViewer.d.ts.map +1 -1
  10. package/dist/LogViewer.js +5 -4
  11. package/dist/LogViewer.js.map +1 -1
  12. package/dist/NodeIdUtilities.d.ts +26 -11
  13. package/dist/NodeIdUtilities.d.ts.map +1 -1
  14. package/dist/NodeIdUtilities.js.map +1 -1
  15. package/dist/SharedTree.d.ts +61 -22
  16. package/dist/SharedTree.d.ts.map +1 -1
  17. package/dist/SharedTree.js +75 -30
  18. package/dist/SharedTree.js.map +1 -1
  19. package/dist/Transaction.d.ts +22 -4
  20. package/dist/Transaction.d.ts.map +1 -1
  21. package/dist/Transaction.js +27 -11
  22. package/dist/Transaction.js.map +1 -1
  23. package/dist/TransactionInternal.d.ts +3 -6
  24. package/dist/TransactionInternal.d.ts.map +1 -1
  25. package/dist/TransactionInternal.js +8 -4
  26. package/dist/TransactionInternal.js.map +1 -1
  27. package/dist/TreeCompressor.d.ts +0 -1
  28. package/dist/TreeCompressor.d.ts.map +1 -1
  29. package/dist/TreeCompressor.js +31 -26
  30. package/dist/TreeCompressor.js.map +1 -1
  31. package/dist/TreeView.d.ts.map +1 -1
  32. package/dist/TreeView.js +3 -2
  33. package/dist/TreeView.js.map +1 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js.map +1 -1
  37. package/docs/Write-Format.md +19 -0
  38. package/lib/ChangeTypes.d.ts +9 -14
  39. package/lib/ChangeTypes.d.ts.map +1 -1
  40. package/lib/ChangeTypes.js.map +1 -1
  41. package/lib/Checkout.d.ts.map +1 -1
  42. package/lib/Checkout.js +3 -2
  43. package/lib/Checkout.js.map +1 -1
  44. package/lib/LogViewer.d.ts +2 -3
  45. package/lib/LogViewer.d.ts.map +1 -1
  46. package/lib/LogViewer.js +5 -4
  47. package/lib/LogViewer.js.map +1 -1
  48. package/lib/NodeIdUtilities.d.ts +26 -11
  49. package/lib/NodeIdUtilities.d.ts.map +1 -1
  50. package/lib/NodeIdUtilities.js.map +1 -1
  51. package/lib/SharedTree.d.ts +61 -22
  52. package/lib/SharedTree.d.ts.map +1 -1
  53. package/lib/SharedTree.js +75 -30
  54. package/lib/SharedTree.js.map +1 -1
  55. package/lib/Transaction.d.ts +22 -4
  56. package/lib/Transaction.d.ts.map +1 -1
  57. package/lib/Transaction.js +26 -10
  58. package/lib/Transaction.js.map +1 -1
  59. package/lib/TransactionInternal.d.ts +3 -6
  60. package/lib/TransactionInternal.d.ts.map +1 -1
  61. package/lib/TransactionInternal.js +8 -4
  62. package/lib/TransactionInternal.js.map +1 -1
  63. package/lib/TreeCompressor.d.ts +0 -1
  64. package/lib/TreeCompressor.d.ts.map +1 -1
  65. package/lib/TreeCompressor.js +31 -26
  66. package/lib/TreeCompressor.js.map +1 -1
  67. package/lib/TreeView.d.ts.map +1 -1
  68. package/lib/TreeView.js +3 -2
  69. package/lib/TreeView.js.map +1 -1
  70. package/lib/index.d.ts +1 -1
  71. package/lib/index.d.ts.map +1 -1
  72. package/lib/index.js.map +1 -1
  73. package/lib/test/LogViewer.tests.js +13 -10
  74. package/lib/test/LogViewer.tests.js.map +1 -1
  75. package/lib/test/Transaction.tests.js +36 -2
  76. package/lib/test/Transaction.tests.js.map +1 -1
  77. package/lib/test/TreeView.tests.js +29 -0
  78. package/lib/test/TreeView.tests.js.map +1 -1
  79. package/lib/test/Virtualization.tests.js +1 -2
  80. package/lib/test/Virtualization.tests.js.map +1 -1
  81. package/lib/test/fuzz/SharedTreeFuzzTests.d.ts.map +1 -1
  82. package/lib/test/fuzz/SharedTreeFuzzTests.js +19 -2
  83. package/lib/test/fuzz/SharedTreeFuzzTests.js.map +1 -1
  84. package/lib/test/utilities/SharedTreeVersioningTests.d.ts.map +1 -1
  85. package/lib/test/utilities/SharedTreeVersioningTests.js +26 -1
  86. package/lib/test/utilities/SharedTreeVersioningTests.js.map +1 -1
  87. package/package.json +18 -18
  88. package/src/ChangeTypes.ts +9 -14
  89. package/src/Checkout.ts +3 -3
  90. package/src/LogViewer.ts +4 -4
  91. package/src/NodeIdUtilities.ts +26 -11
  92. package/src/SharedTree.ts +81 -28
  93. package/src/Transaction.ts +39 -13
  94. package/src/TransactionInternal.ts +9 -10
  95. package/src/TreeCompressor.ts +31 -40
  96. package/src/TreeView.ts +3 -2
  97. package/src/index.ts +0 -1
  98. package/docs/Future.md +0 -155
@@ -1 +1 @@
1
- {"version":3,"file":"TreeView.js","sourceRoot":"","sources":["../src/TreeView.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAE/D,OAAO,EAAiB,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAY,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAsEnD;;;GAGG;AACH,MAAM,OAAgB,QAAQ;IAY7B,YAAsB,IAAY,EAAE,MAAc;QACjD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,gDAAgD;IAChD,IAAW,IAAI;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,qEAAqE;IAC9D,OAAO,CAAC,EAAU;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACI,oBAAoB,CAAC,KAAoB;QAC/C,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE;YAChC,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;SACpD;QACD,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,kHAAkH;IAC3G,WAAW,CAAC,EAAU;;QAC5B,aAAO,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,mCAAI,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC5D,CAAC;IAED,wHAAwH;IACjH,cAAc,CAAC,EAAU;QAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1C,IAAI,UAAU,KAAK,SAAS,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE;YACjE,MAAM,QAAQ,GAAiB;gBAC9B,UAAU,EAAE,UAAU,CAAC,UAAU;gBACjC,UAAU,EAAE,UAAU,CAAC,UAAU;gBACjC,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,SAAS,EAAE;oBACV,KAAK,EAAE,UAAU,CAAC,WAAW;oBAC7B,MAAM,EAAE,UAAU,CAAC,QAAQ;iBAC3B;aACD,CAAC;YACF,qBAAqB,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YACvD,OAAO,QAAQ,CAAC;SAChB;QAED,OAAO,UAAU,CAAC;IACnB,CAAC;IAED;;;OAGG;IACI,aAAa,CAAC,EAAU;QAC9B,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACI,gBAAgB,CAAC,EAAU;;QACjC,aAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,0CAAE,WAAW,CAAC;IAClD,CAAC;IAED;;OAEG;IACI,iBAAiB,CAAC,EAAU;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACI,oBAAoB,CAAC,EAAU;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAChD,IAAI,UAAU,KAAK,SAAS,EAAE;YAC7B,OAAO,SAAS,CAAC;SACjB;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACI,gBAAgB,CAAC,EAAU;QACjC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC7C,OAAO;YACN,MAAM,EAAE,UAAU,CAAC,QAAQ;YAC3B,KAAK,EAAE,UAAU,CAAC,WAAW;SAC7B,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,mBAAmB,CAAC,EAAU;QACpC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAChD,IAAI,UAAU,KAAK,SAAS,EAAE;YAC7B,OAAO,SAAS,CAAC;SACjB;QACD,OAAO;YACN,MAAM,EAAE,UAAU,CAAC,QAAQ;YAC3B,KAAK,EAAE,UAAU,CAAC,WAAW;SAC7B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,eAAe,CAAC,EAAU;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QAC1C,OAAO,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAC1D,CAAC;IAED;;;;OAIG;IACI,kBAAkB,CAAC,EAAU;;QACnC,MAAM,WAAW,SAAG,IAAI,CAAC,iBAAiB,0CAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACpD,IAAI,WAAW,KAAK,SAAS,EAAE;YAC9B,OAAO,WAAW,CAAC;SACnB;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAChD,IAAI,UAAU,KAAK,SAAS,EAAE;YAC7B,OAAO,SAAS,CAAC;SACjB;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,MAAM,KAAK,SAAS,EAAE;YACzB,OAAO,SAAS,CAAC;SACjB;QAED,MAAM,KAAK,SAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,mCAAI,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC/G,IAAI,UAAsC,CAAC;QAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;YACvB,OAAO,UAAU,CAAC;SAClB;QAED,MAAA,IAAI,CAAC,iBAAiB,oCAAtB,IAAI,CAAC,iBAAiB,GAAK,IAAI,GAAG,EAAE,EAAC;QACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACtC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,KAAK,GAAG,CAAmB,CAAC;YAClC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAC/C,IAAI,WAAW,KAAK,EAAE,EAAE;gBACvB,UAAU,GAAG,KAAK,CAAC;aACnB;SACD;QAED,OAAO,UAAU,CAAC;IACnB,CAAC;IAED;;OAEG;IACI,QAAQ,CAAC,aAA4B;;QAC3C,aAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,mCAAI,EAAE,CAAC;IACrF,CAAC;IAED,2FAA2F;IACpF,gBAAgB;QACtB,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;IAChC,CAAC;IAEM,CAAC,MAAM,CAAC,QAAQ,CAAC;QACvB,OAAO,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAKD;;;OAGG;IACI,cAAc,CAAC,IAAc,EAAE,MAAM,GAAG,KAAK;QACnD,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE;YAC5B,+EAA+E;YAC/E,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAC9E;QAED,OAAO,KAAK,CAAC;IACd,CAAC;IAEO,CAAC,sBAAsB,CAAC,IAAkB;QACjD,MAAM,IAAI,CAAC;QACX,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE;YAC5D,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE;gBAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;gBACxC,KAAK,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;aAC1C;SACD;IACF,CAAC;IAEO,cAAc,CAAC,IAAU,EAAE,aAA4B;QAC9D,OAAO,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAgB,CAAC,CAAC,CAAE,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,MAAqB,CAAC;IACtG,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,IAAc;QAC1B,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,8DAA8D,CAAC,CAAC;QAChG,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;CACD;AAED,SAAS,QAAQ,CAAC,IAAU,EAAE,KAAqB;IAClD,qEAAqE;IACrE,OAAO,CAAC,IAAI,GAAG,KAAK,CAAe,CAAC;AACrC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, copyPropertyIfDefined, fail } from './Common';\nimport { NodeId, TraitLabel } from './Identifiers';\nimport { Delta, Forest, isParentedForestNode } from './Forest';\nimport { NodeData, Side } from './persisted-types';\n\n/**\n * Specifies the location of a trait (a labeled sequence of nodes) within the tree.\n * @public\n */\nexport interface TraitLocation {\n\treadonly parent: NodeId;\n\treadonly label: TraitLabel;\n}\n\n/**\n * An immutable view of a distributed tree node.\n * @public\n */\nexport interface TreeViewNode extends NodeData<NodeId> {\n\t/** The IDs of the children under this node */\n\treadonly traits: ReadonlyMap<TraitLabel, readonly NodeId[]>;\n\t/** The parent and trait under which this node resides. Undefined iff this is the root node of the tree (i.e. {@link initialTree}). */\n\treadonly parentage?: TraitLocation;\n}\n\n/**\n * Index of a place within a trait.\n * 0 = before all nodes,\n * 1 = after first node,\n * etc.\n * @public\n */\nexport type PlaceIndex = number & { readonly PlaceIndex: unique symbol };\n\n/**\n * Index of a node within a trait.\n * 0 = first node,\n * 1 = second node,\n * etc.\n * @public\n */\nexport type TraitNodeIndex = number & { readonly TraitNodeIndex: unique symbol };\n\n/**\n * A place within a particular `TreeView` that is anchored relative to a specific node in the tree, or relative to the outside of the trait.\n * Valid iff 'trait' is valid and, if provided, sibling is in the Location specified by 'trait'.\n * @public\n */\nexport interface TreeViewPlace {\n\treadonly sibling?: NodeId;\n\treadonly side: Side;\n\treadonly trait: TraitLocation;\n}\n\n/**\n * Specifies the range of nodes from `start` to `end` within a trait within a particular `TreeView`.\n * Valid iff start and end are valid and are within the same trait.\n * @public\n */\nexport interface TreeViewRange {\n\treadonly start: TreeViewPlace;\n\treadonly end: TreeViewPlace;\n}\n\n/**\n * Contains some redundant information. Use only in computations between edits. Do not store.\n * @public\n */\nexport interface NodeInTrait {\n\treadonly trait: TraitLocation;\n\treadonly index: TraitNodeIndex;\n}\n\n/**\n * A view of a distributed tree.\n * @public\n */\nexport abstract class TreeView {\n\tpublic readonly root: NodeId;\n\tprotected readonly forest: Forest;\n\tprivate readonly rootNode: TreeViewNode;\n\n\t/**\n\t * A cache of node's index within their parent trait.\n\t * Used to avoid redundant linear scans of traits.\n\t * Not shared across views; initialized to empty each time a TreeView is created.\n\t */\n\tprivate traitIndicesCache?: Map<NodeId, TraitNodeIndex>;\n\n\tprotected constructor(root: NodeId, forest: Forest) {\n\t\tthis.root = root;\n\t\tthis.forest = forest;\n\t\tthis.rootNode = this.getViewNode(root);\n\t}\n\n\t/** @returns the number of nodes in this view */\n\tpublic get size(): number {\n\t\treturn this.forest.size;\n\t}\n\n\t/** @returns true iff a node with the given id exists in this view */\n\tpublic hasNode(id: NodeId): boolean {\n\t\treturn this.forest.has(id);\n\t}\n\n\t/**\n\t * @returns the index just after place (which specifies a location between items).\n\t * Performance note: this is O(siblings in trait).\n\t */\n\tpublic findIndexWithinTrait(place: TreeViewPlace): PlaceIndex {\n\t\tif (place.sibling === undefined) {\n\t\t\treturn this.getIndexOfSide(place.side, place.trait);\n\t\t}\n\t\treturn getIndex(place.side, this.getIndexInTrait(place.sibling));\n\t}\n\n\t/** @returns the node associated with the given id in this view. Fails if the node does not exist in this view. */\n\tpublic getViewNode(id: NodeId): TreeViewNode {\n\t\treturn this.tryGetViewNode(id) ?? fail('NodeId not found');\n\t}\n\n\t/** @returns the node associated with the given id in this view, or undefined if the node does not exist in this view */\n\tpublic tryGetViewNode(id: NodeId): TreeViewNode | undefined {\n\t\tconst forestNode = this.forest.tryGet(id);\n\t\tif (forestNode !== undefined && isParentedForestNode(forestNode)) {\n\t\t\tconst viewNode: TreeViewNode = {\n\t\t\t\tdefinition: forestNode.definition,\n\t\t\t\tidentifier: forestNode.identifier,\n\t\t\t\ttraits: forestNode.traits,\n\t\t\t\tparentage: {\n\t\t\t\t\tlabel: forestNode.traitParent,\n\t\t\t\t\tparent: forestNode.parentId,\n\t\t\t\t},\n\t\t\t};\n\t\t\tcopyPropertyIfDefined(forestNode, viewNode, 'payload');\n\t\t\treturn viewNode;\n\t\t}\n\n\t\treturn forestNode;\n\t}\n\n\t/**\n\t * @returns the label of the trait under which a node with the given id resides. Fails if the node does not exist in this view or if\n\t * it is the root node.\n\t */\n\tpublic getTraitLabel(id: NodeId): TraitLabel {\n\t\treturn this.forest.getParent(id).traitParent;\n\t}\n\n\t/**\n\t * @returns the label of the trait under which a node with the given id resides, or undefined if the node is not present in this\n\t * view or if it is the root node\n\t */\n\tpublic tryGetTraitLabel(id: NodeId): TraitLabel | undefined {\n\t\treturn this.forest.tryGetParent(id)?.traitParent;\n\t}\n\n\t/**\n\t * @returns the parent of the node with the given id. Fails if the node does not exist in this view or if it is the root node.\n\t */\n\tpublic getParentViewNode(id: NodeId): TreeViewNode {\n\t\tconst parentInfo = this.forest.getParent(id);\n\t\treturn this.getViewNode(parentInfo.parentId);\n\t}\n\n\t/**\n\t * @returns the parent of the node with the given id. Returns undefined if the node does not exist in this view or if it is the root\n\t * node.\n\t */\n\tpublic tryGetParentViewNode(id: NodeId): TreeViewNode | undefined {\n\t\tconst parentInfo = this.forest.tryGetParent(id);\n\t\tif (parentInfo === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.getViewNode(parentInfo.parentId);\n\t}\n\n\t/**\n\t * @returns the trait location of the node with the given id. Fails if the node does not exist in this view or of it is the root\n\t * node\n\t */\n\tpublic getTraitLocation(id: NodeId): TraitLocation {\n\t\tconst parentData = this.forest.getParent(id);\n\t\treturn {\n\t\t\tparent: parentData.parentId,\n\t\t\tlabel: parentData.traitParent,\n\t\t};\n\t}\n\n\t/**\n\t * @returns the trait location of the node with the given id, or undefined if the node does not exist in this view or if it is the root\n\t * node\n\t */\n\tpublic tryGetTraitLocation(id: NodeId): TraitLocation | undefined {\n\t\tconst parentData = this.forest.tryGetParent(id);\n\t\tif (parentData === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tparent: parentData.parentId,\n\t\t\tlabel: parentData.traitParent,\n\t\t};\n\t}\n\n\t/**\n\t * @returns the index within the trait under which the node with the given id resides. The node must exist in this view and must have a\n\t * parent.\n\t * Performance note: this is O(siblings in trait).\n\t */\n\tpublic getIndexInTrait(id: NodeId): TraitNodeIndex {\n\t\tconst index = this.tryGetIndexInTrait(id);\n\t\treturn index ?? fail('ID does not exist in the forest.');\n\t}\n\n\t/**\n\t * @returns the index within the trait under which the node with the given id resides, or undefined if the node does not exist in this\n\t * view or does not have a parent.\n\t * Performance note: this is O(siblings in trait).\n\t */\n\tpublic tryGetIndexInTrait(id: NodeId): TraitNodeIndex | undefined {\n\t\tconst cachedIndex = this.traitIndicesCache?.get(id);\n\t\tif (cachedIndex !== undefined) {\n\t\t\treturn cachedIndex;\n\t\t}\n\n\t\tconst parentData = this.forest.tryGetParent(id);\n\t\tif (parentData === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst parent = this.forest.tryGet(parentData.parentId);\n\t\tif (parent === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst trait = parent.traits.get(parentData.traitParent) ?? fail('inconsistent forest: trait parent not found');\n\t\tlet foundIndex: TraitNodeIndex | undefined;\n\t\tif (trait.length === 0) {\n\t\t\treturn foundIndex;\n\t\t}\n\n\t\tthis.traitIndicesCache ??= new Map();\n\t\tfor (let i = 0; i < trait.length; i++) {\n\t\t\tconst nodeInTrait = trait[i];\n\t\t\tconst index = i as TraitNodeIndex;\n\t\t\tthis.traitIndicesCache.set(nodeInTrait, index);\n\t\t\tif (nodeInTrait === id) {\n\t\t\t\tfoundIndex = index;\n\t\t\t}\n\t\t}\n\n\t\treturn foundIndex;\n\t}\n\n\t/**\n\t * @returns the trait at the given location. If no such trait exists, returns an empty trait.\n\t */\n\tpublic getTrait(traitLocation: TraitLocation): readonly NodeId[] {\n\t\treturn this.getViewNode(traitLocation.parent).traits.get(traitLocation.label) ?? [];\n\t}\n\n\t/** Asserts that the view's internal state is consistent. Useful for testing/validation. */\n\tpublic assertConsistent(): void {\n\t\tthis.forest.assertConsistent();\n\t}\n\n\tpublic [Symbol.iterator](): IterableIterator<TreeViewNode> {\n\t\treturn this.iterateNodeDescendants(this.rootNode);\n\t}\n\n\t/** @returns true iff the given view is equal to this view */\n\tpublic abstract equals(view: TreeView): boolean;\n\n\t/**\n\t * @returns true iff the given view's forest of nodes is equivalent to this view's forest of nodes\n\t * @param strict - if true, the views' forests must be the same object, otherwise they must merely be equivalent\n\t */\n\tpublic hasEqualForest(view: TreeView, strict = false): boolean {\n\t\tif (this.root === view.root) {\n\t\t\t// TODO:#49100:Perf: make this faster and/or remove use by PrefetchingCheckout.\n\t\t\treturn strict ? this.forest === view.forest : this.forest.equals(view.forest);\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate *iterateNodeDescendants(node: TreeViewNode): IterableIterator<TreeViewNode> {\n\t\tyield node;\n\t\tfor (const trait of Array.from(node.traits.values()).sort()) {\n\t\t\tfor (const childId of trait) {\n\t\t\t\tconst child = this.getViewNode(childId);\n\t\t\t\tyield* this.iterateNodeDescendants(child);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getIndexOfSide(side: Side, traitLocation: TraitLocation): PlaceIndex {\n\t\treturn side === Side.After ? (0 as PlaceIndex) : (this.getTrait(traitLocation).length as PlaceIndex);\n\t}\n\n\t/**\n\t * Calculate the difference between two `TreeView`s\n\t * @param view - the other view to compare to this one\n\t * @returns A {@link Delta} which nodes must be changed, added, and removed to get from `this` to `view`.\n\t * The views must share a root.\n\t */\n\tpublic delta(view: TreeView): Delta<NodeId> {\n\t\tassert(this.root === view.root, 'Delta can only be calculated between views that share a root');\n\t\treturn this.forest.delta(view.forest);\n\t}\n}\n\nfunction getIndex(side: Side, index: TraitNodeIndex): PlaceIndex {\n\t// eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n\treturn (side + index) as PlaceIndex;\n}\n"]}
1
+ {"version":3,"file":"TreeView.js","sourceRoot":"","sources":["../src/TreeView.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, copyPropertyIfDefined, fail } from './Common';\nimport { NodeId, TraitLabel } from './Identifiers';\nimport { Delta, Forest, isParentedForestNode } from './Forest';\nimport { NodeData, Side } from './persisted-types';\n\n/**\n * Specifies the location of a trait (a labeled sequence of nodes) within the tree.\n * @public\n */\nexport interface TraitLocation {\n\treadonly parent: NodeId;\n\treadonly label: TraitLabel;\n}\n\n/**\n * An immutable view of a distributed tree node.\n * @public\n */\nexport interface TreeViewNode extends NodeData<NodeId> {\n\t/** The IDs of the children under this node */\n\treadonly traits: ReadonlyMap<TraitLabel, readonly NodeId[]>;\n\t/** The parent and trait under which this node resides. Undefined iff this is the root node of the tree (i.e. {@link initialTree}). */\n\treadonly parentage?: TraitLocation;\n}\n\n/**\n * Index of a place within a trait.\n * 0 = before all nodes,\n * 1 = after first node,\n * etc.\n * @public\n */\nexport type PlaceIndex = number & { readonly PlaceIndex: unique symbol };\n\n/**\n * Index of a node within a trait.\n * 0 = first node,\n * 1 = second node,\n * etc.\n * @public\n */\nexport type TraitNodeIndex = number & { readonly TraitNodeIndex: unique symbol };\n\n/**\n * A place within a particular `TreeView` that is anchored relative to a specific node in the tree, or relative to the outside of the trait.\n * Valid iff 'trait' is valid and, if provided, sibling is in the Location specified by 'trait'.\n * @public\n */\nexport interface TreeViewPlace {\n\treadonly sibling?: NodeId;\n\treadonly side: Side;\n\treadonly trait: TraitLocation;\n}\n\n/**\n * Specifies the range of nodes from `start` to `end` within a trait within a particular `TreeView`.\n * Valid iff start and end are valid and are within the same trait.\n * @public\n */\nexport interface TreeViewRange {\n\treadonly start: TreeViewPlace;\n\treadonly end: TreeViewPlace;\n}\n\n/**\n * Contains some redundant information. Use only in computations between edits. Do not store.\n * @public\n */\nexport interface NodeInTrait {\n\treadonly trait: TraitLocation;\n\treadonly index: TraitNodeIndex;\n}\n\n/**\n * A view of a distributed tree.\n * @public\n */\nexport abstract class TreeView {\n\tpublic readonly root: NodeId;\n\tprotected readonly forest: Forest;\n\tprivate readonly rootNode: TreeViewNode;\n\n\t/**\n\t * A cache of node's index within their parent trait.\n\t * Used to avoid redundant linear scans of traits.\n\t * Not shared across views; initialized to empty each time a TreeView is created.\n\t */\n\tprivate traitIndicesCache?: Map<NodeId, TraitNodeIndex>;\n\n\tprotected constructor(root: NodeId, forest: Forest) {\n\t\tthis.root = root;\n\t\tthis.forest = forest;\n\t\tthis.rootNode = this.getViewNode(root);\n\t}\n\n\t/** @returns the number of nodes in this view */\n\tpublic get size(): number {\n\t\treturn this.forest.size;\n\t}\n\n\t/** @returns true iff a node with the given id exists in this view */\n\tpublic hasNode(id: NodeId): boolean {\n\t\treturn this.forest.has(id);\n\t}\n\n\t/**\n\t * @returns the index just after place (which specifies a location between items).\n\t * Performance note: this is O(siblings in trait).\n\t */\n\tpublic findIndexWithinTrait(place: TreeViewPlace): PlaceIndex {\n\t\tif (place.sibling === undefined) {\n\t\t\treturn this.getIndexOfSide(place.side, place.trait);\n\t\t}\n\t\treturn getIndex(place.side, this.getIndexInTrait(place.sibling));\n\t}\n\n\t/** @returns the node associated with the given id in this view. Fails if the node does not exist in this view. */\n\tpublic getViewNode(id: NodeId): TreeViewNode {\n\t\treturn this.tryGetViewNode(id) ?? fail('NodeId not found');\n\t}\n\n\t/** @returns the node associated with the given id in this view, or undefined if the node does not exist in this view */\n\tpublic tryGetViewNode(id: NodeId): TreeViewNode | undefined {\n\t\tconst forestNode = this.forest.tryGet(id);\n\t\tif (forestNode !== undefined && isParentedForestNode(forestNode)) {\n\t\t\tconst viewNode: TreeViewNode = {\n\t\t\t\tdefinition: forestNode.definition,\n\t\t\t\tidentifier: forestNode.identifier,\n\t\t\t\ttraits: forestNode.traits,\n\t\t\t\tparentage: {\n\t\t\t\t\tlabel: forestNode.traitParent,\n\t\t\t\t\tparent: forestNode.parentId,\n\t\t\t\t},\n\t\t\t};\n\t\t\tcopyPropertyIfDefined(forestNode, viewNode, 'payload');\n\t\t\treturn viewNode;\n\t\t}\n\n\t\treturn forestNode;\n\t}\n\n\t/**\n\t * @returns the label of the trait under which a node with the given id resides. Fails if the node does not exist in this view or if\n\t * it is the root node.\n\t */\n\tpublic getTraitLabel(id: NodeId): TraitLabel {\n\t\treturn this.forest.getParent(id).traitParent;\n\t}\n\n\t/**\n\t * @returns the label of the trait under which a node with the given id resides, or undefined if the node is not present in this\n\t * view or if it is the root node\n\t */\n\tpublic tryGetTraitLabel(id: NodeId): TraitLabel | undefined {\n\t\treturn this.forest.tryGetParent(id)?.traitParent;\n\t}\n\n\t/**\n\t * @returns the parent of the node with the given id. Fails if the node does not exist in this view or if it is the root node.\n\t */\n\tpublic getParentViewNode(id: NodeId): TreeViewNode {\n\t\tconst parentInfo = this.forest.getParent(id);\n\t\treturn this.getViewNode(parentInfo.parentId);\n\t}\n\n\t/**\n\t * @returns the parent of the node with the given id. Returns undefined if the node does not exist in this view or if it is the root\n\t * node.\n\t */\n\tpublic tryGetParentViewNode(id: NodeId): TreeViewNode | undefined {\n\t\tconst parentInfo = this.forest.tryGetParent(id);\n\t\tif (parentInfo === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.getViewNode(parentInfo.parentId);\n\t}\n\n\t/**\n\t * @returns the trait location of the node with the given id. Fails if the node does not exist in this view or of it is the root\n\t * node\n\t */\n\tpublic getTraitLocation(id: NodeId): TraitLocation {\n\t\tconst parentData = this.forest.getParent(id);\n\t\treturn {\n\t\t\tparent: parentData.parentId,\n\t\t\tlabel: parentData.traitParent,\n\t\t};\n\t}\n\n\t/**\n\t * @returns the trait location of the node with the given id, or undefined if the node does not exist in this view or if it is the root\n\t * node\n\t */\n\tpublic tryGetTraitLocation(id: NodeId): TraitLocation | undefined {\n\t\tconst parentData = this.forest.tryGetParent(id);\n\t\tif (parentData === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn {\n\t\t\tparent: parentData.parentId,\n\t\t\tlabel: parentData.traitParent,\n\t\t};\n\t}\n\n\t/**\n\t * @returns the index within the trait under which the node with the given id resides. The node must exist in this view and must have a\n\t * parent.\n\t * Performance note: this is O(siblings in trait).\n\t */\n\tpublic getIndexInTrait(id: NodeId): TraitNodeIndex {\n\t\tconst index = this.tryGetIndexInTrait(id);\n\t\treturn index ?? fail('ID does not exist in the forest.');\n\t}\n\n\t/**\n\t * @returns the index within the trait under which the node with the given id resides, or undefined if the node does not exist in this\n\t * view or does not have a parent.\n\t * Performance note: this is O(siblings in trait).\n\t */\n\tpublic tryGetIndexInTrait(id: NodeId): TraitNodeIndex | undefined {\n\t\tconst cachedIndex = this.traitIndicesCache?.get(id);\n\t\tif (cachedIndex !== undefined) {\n\t\t\treturn cachedIndex;\n\t\t}\n\n\t\tconst parentData = this.forest.tryGetParent(id);\n\t\tif (parentData === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst parent = this.forest.tryGet(parentData.parentId);\n\t\tif (parent === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst trait = parent.traits.get(parentData.traitParent) ?? fail('inconsistent forest: trait parent not found');\n\t\tlet foundIndex: TraitNodeIndex | undefined;\n\t\tif (trait.length === 0) {\n\t\t\treturn foundIndex;\n\t\t}\n\n\t\tthis.traitIndicesCache ??= new Map();\n\t\tfor (let i = 0; i < trait.length; i++) {\n\t\t\tconst nodeInTrait = trait[i];\n\t\t\tconst index = i as TraitNodeIndex;\n\t\t\tthis.traitIndicesCache.set(nodeInTrait, index);\n\t\t\tif (nodeInTrait === id) {\n\t\t\t\tfoundIndex = index;\n\t\t\t}\n\t\t}\n\n\t\treturn foundIndex;\n\t}\n\n\t/**\n\t * @returns the trait at the given location. If no such trait exists, returns an empty trait.\n\t */\n\tpublic getTrait(traitLocation: TraitLocation): readonly NodeId[] {\n\t\treturn this.getViewNode(traitLocation.parent).traits.get(traitLocation.label) ?? [];\n\t}\n\n\t/** Asserts that the view's internal state is consistent. Useful for testing/validation. */\n\tpublic assertConsistent(): void {\n\t\tthis.forest.assertConsistent();\n\t}\n\n\tpublic [Symbol.iterator](): IterableIterator<TreeViewNode> {\n\t\treturn this.iterateNodeDescendants(this.rootNode);\n\t}\n\n\t/** @returns true iff the given view is equal to this view */\n\tpublic abstract equals(view: TreeView): boolean;\n\n\t/**\n\t * @returns true iff the given view's forest of nodes is equivalent to this view's forest of nodes\n\t * @param strict - if true, the views' forests must be the same object, otherwise they must merely be equivalent\n\t */\n\tpublic hasEqualForest(view: TreeView, strict = false): boolean {\n\t\tif (this.root === view.root) {\n\t\t\t// TODO:#49100:Perf: make this faster and/or remove use by PrefetchingCheckout.\n\t\t\treturn strict ? this.forest === view.forest : this.forest.equals(view.forest);\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tprivate *iterateNodeDescendants(node: TreeViewNode): IterableIterator<TreeViewNode> {\n\t\tyield node;\n\t\tfor (const label of [...node.traits.keys()].sort()) {\n\t\t\tconst trait = node.traits.get(label);\n\t\t\tfor (const childId of trait ?? fail('Expected trait with label')) {\n\t\t\t\tconst child = this.getViewNode(childId);\n\t\t\t\tyield* this.iterateNodeDescendants(child);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getIndexOfSide(side: Side, traitLocation: TraitLocation): PlaceIndex {\n\t\treturn side === Side.After ? (0 as PlaceIndex) : (this.getTrait(traitLocation).length as PlaceIndex);\n\t}\n\n\t/**\n\t * Calculate the difference between two `TreeView`s\n\t * @param view - the other view to compare to this one\n\t * @returns A {@link Delta} which nodes must be changed, added, and removed to get from `this` to `view`.\n\t * The views must share a root.\n\t */\n\tpublic delta(view: TreeView): Delta<NodeId> {\n\t\tassert(this.root === view.root, 'Delta can only be calculated between views that share a root');\n\t\treturn this.forest.delta(view.forest);\n\t}\n}\n\nfunction getIndex(side: Side, index: TraitNodeIndex): PlaceIndex {\n\t// eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n\treturn (side + index) as PlaceIndex;\n}\n"]}
package/lib/index.d.ts CHANGED
@@ -32,7 +32,7 @@ export { SharedTreeFactory, SharedTree, EditCommittedHandler, SequencedEditAppli
32
32
  export * from './EventTypes';
33
33
  export { setTrait, areRevisionViewsSemanticallyEqual, BadPlaceValidationResult, BadRangeValidationResult, PlaceValidationResult, RangeValidationResult, RangeValidationResultKind, } from './EditUtilities';
34
34
  export { comparePayloads } from './PayloadUtilities';
35
- export { TransactionInternal, TransactionFactory, GenericTransaction, GenericTransactionPolicy, EditingResult, EditingResultBase, FailedEditingResult, ValidEditingResult, TransactionState, TransactionFailure, SucceedingTransactionState, FailingTransactionState, ChangeResult, } from './TransactionInternal';
35
+ export { TransactionInternal, GenericTransaction, GenericTransactionPolicy, EditingResult, EditingResultBase, FailedEditingResult, ValidEditingResult, TransactionState, TransactionFailure, SucceedingTransactionState, FailingTransactionState, ChangeResult, } from './TransactionInternal';
36
36
  export { NodeInTrait, PlaceIndex, TreeViewNode, TreeView, TraitNodeIndex, TreeViewPlace, TreeViewRange, TraitLocation, } from './TreeView';
37
37
  export { RevisionView, TransactionView } from './RevisionView';
38
38
  export { NodeIdContext, NodeIdGenerator, NodeIdConverter } from './NodeIdUtilities';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AAEH;;;GAGG;AAEH,cAAc;AAEd,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAS,MAAM,EAA0B,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAiBnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAIrD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAmB,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EACN,IAAI,EACJ,UAAU,EAIV,gBAAgB,EAEhB,cAAc,EAoBd,kBAAkB,EAElB,WAAW,EAEX,mBAAmB,EACnB,mBAAmB,GAOnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,iBAAiB,EACjB,UAAU,GAOV,MAAM,cAAc,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,OAAO,EACN,QAAQ,EACR,iCAAiC,EAGjC,qBAAqB,EAErB,yBAAyB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACN,mBAAmB,EAEnB,kBAAkB,GAWlB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAIN,QAAQ,GAKR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,OAAO;AACN,wEAAwE;AACxE,sCAAsC,IAAI,4BAA4B,EACtE,sCAAsC,GACtC,MAAM,wBAAwB,CAAC;AAEhC,cAAc,eAAe,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Fluid DDS storing a tree.\n *\n * @packageDocumentation\n */\n\n/**\n * This file represents the public API. Consumers of this package will not see exported modules unless they are enumerated here.\n * Removing / editing existing exports here will often indicate a breaking change, so please be cognizant of changes made here.\n */\n\n// API Exports\n\nexport { initialTree } from './InitialTree';\nexport { TreeNodeHandle } from './TreeNodeHandle';\nexport { Delta, Forest, ForestNode, ParentData } from './Forest';\nexport { sharedTreeAssertionErrorType, isSharedTreeEvent, Result } from './Common';\nexport type {\n\tCompressedId,\n\tDefinition,\n\tDetachedSequenceId,\n\tEditId,\n\tInternedStringId,\n\tFinalCompressedId,\n\tLocalCompressedId,\n\tNodeId,\n\tNodeIdBrand,\n\tStableNodeId,\n\tSessionSpaceCompressedId,\n\tSessionUnique,\n\tTraitLabel,\n\tUuidString,\n} from './Identifiers';\nexport { isDetachedSequenceId } from './Identifiers';\nexport type { OrderedEditSet, EditHandle } from './EditLog';\nexport { LogViewer } from './LogViewer';\nexport { Revision } from './RevisionValueCache';\nexport { Checkout, CheckoutEvent, ICheckoutEvents, EditValidationResult } from './Checkout';\nexport { LazyCheckout } from './LazyCheckout';\nexport { EagerCheckout } from './EagerCheckout';\nexport * from './ReconciliationPath';\nexport * from './MergeHealth';\nexport * from './TreeViewUtilities';\nexport { StringInterner } from './StringInterner';\nexport {\n\tSide,\n\tEditStatus,\n\tTreeNode,\n\tTreeNodeSequence,\n\tPayload,\n\tConstraintEffect,\n\tEdit,\n\tChangeInternal,\n\tChangeNode,\n\tChangeNode_0_0_2,\n\tEditLogSummary,\n\tFluidEditHandle,\n\tSharedTreeSummaryBase,\n\tEditWithoutId,\n\tPlaceholderTree,\n\tEditBase,\n\tHasTraits,\n\tInsertInternal,\n\tDetachInternal,\n\tBuildInternal,\n\tSetValueInternal,\n\tConstraintInternal,\n\tBuildNodeInternal,\n\tStablePlaceInternal_0_0_2,\n\tStableRangeInternal_0_0_2,\n\tNodeData,\n\tTraitMap,\n\tChangeTypeInternal,\n\tTraitLocationInternal_0_0_2,\n\tWriteFormat,\n\tConstraintInternal_0_0_2,\n\tStablePlaceInternal,\n\tStableRangeInternal,\n\tBuildNodeInternal_0_0_2,\n\tBuildInternal_0_0_2,\n\tInsertInternal_0_0_2,\n\tDetachInternal_0_0_2,\n\tSetValueInternal_0_0_2,\n\tTraitLocationInternal,\n} from './persisted-types';\nexport {\n\tSharedTreeFactory,\n\tSharedTree,\n\tEditCommittedHandler,\n\tSequencedEditAppliedHandler,\n\tEditCommittedEventArguments,\n\tSequencedEditAppliedEventArguments,\n\tEditApplicationOutcome,\n\tISharedTreeEvents,\n} from './SharedTree';\nexport * from './EventTypes';\nexport {\n\tsetTrait,\n\tareRevisionViewsSemanticallyEqual,\n\tBadPlaceValidationResult,\n\tBadRangeValidationResult,\n\tPlaceValidationResult,\n\tRangeValidationResult,\n\tRangeValidationResultKind,\n} from './EditUtilities';\nexport { comparePayloads } from './PayloadUtilities';\nexport {\n\tTransactionInternal,\n\tTransactionFactory,\n\tGenericTransaction,\n\tGenericTransactionPolicy,\n\tEditingResult,\n\tEditingResultBase,\n\tFailedEditingResult,\n\tValidEditingResult,\n\tTransactionState,\n\tTransactionFailure,\n\tSucceedingTransactionState,\n\tFailingTransactionState,\n\tChangeResult,\n} from './TransactionInternal';\nexport {\n\tNodeInTrait,\n\tPlaceIndex,\n\tTreeViewNode,\n\tTreeView,\n\tTraitNodeIndex,\n\tTreeViewPlace,\n\tTreeViewRange,\n\tTraitLocation,\n} from './TreeView';\nexport { RevisionView, TransactionView } from './RevisionView';\nexport { NodeIdContext, NodeIdGenerator, NodeIdConverter } from './NodeIdUtilities';\nexport { Transaction } from './Transaction';\n\n/**\n * TODO:#61413: Publish test utilities from a separate test package\n */\nexport {\n\t/** @deprecated Use `getSerializedUploadedEditChunkContents` instead. */\n\tgetSerializedUploadedEditChunkContents as getUploadedEditChunkContents,\n\tgetSerializedUploadedEditChunkContents,\n} from './SummaryTestUtilities';\n\nexport * from './ChangeTypes';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AAEH;;;GAGG;AAEH,cAAc;AAEd,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAS,MAAM,EAA0B,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAiBnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAIrD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAmB,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EACN,IAAI,EACJ,UAAU,EAIV,gBAAgB,EAEhB,cAAc,EAoBd,kBAAkB,EAElB,WAAW,EAEX,mBAAmB,EACnB,mBAAmB,GAOnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,iBAAiB,EACjB,UAAU,GAOV,MAAM,cAAc,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,OAAO,EACN,QAAQ,EACR,iCAAiC,EAGjC,qBAAqB,EAErB,yBAAyB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACN,mBAAmB,EACnB,kBAAkB,GAWlB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAIN,QAAQ,GAKR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;GAEG;AACH,OAAO;AACN,wEAAwE;AACxE,sCAAsC,IAAI,4BAA4B,EACtE,sCAAsC,GACtC,MAAM,wBAAwB,CAAC;AAEhC,cAAc,eAAe,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Fluid DDS storing a tree.\n *\n * @packageDocumentation\n */\n\n/**\n * This file represents the public API. Consumers of this package will not see exported modules unless they are enumerated here.\n * Removing / editing existing exports here will often indicate a breaking change, so please be cognizant of changes made here.\n */\n\n// API Exports\n\nexport { initialTree } from './InitialTree';\nexport { TreeNodeHandle } from './TreeNodeHandle';\nexport { Delta, Forest, ForestNode, ParentData } from './Forest';\nexport { sharedTreeAssertionErrorType, isSharedTreeEvent, Result } from './Common';\nexport type {\n\tCompressedId,\n\tDefinition,\n\tDetachedSequenceId,\n\tEditId,\n\tInternedStringId,\n\tFinalCompressedId,\n\tLocalCompressedId,\n\tNodeId,\n\tNodeIdBrand,\n\tStableNodeId,\n\tSessionSpaceCompressedId,\n\tSessionUnique,\n\tTraitLabel,\n\tUuidString,\n} from './Identifiers';\nexport { isDetachedSequenceId } from './Identifiers';\nexport type { OrderedEditSet, EditHandle } from './EditLog';\nexport { LogViewer } from './LogViewer';\nexport { Revision } from './RevisionValueCache';\nexport { Checkout, CheckoutEvent, ICheckoutEvents, EditValidationResult } from './Checkout';\nexport { LazyCheckout } from './LazyCheckout';\nexport { EagerCheckout } from './EagerCheckout';\nexport * from './ReconciliationPath';\nexport * from './MergeHealth';\nexport * from './TreeViewUtilities';\nexport { StringInterner } from './StringInterner';\nexport {\n\tSide,\n\tEditStatus,\n\tTreeNode,\n\tTreeNodeSequence,\n\tPayload,\n\tConstraintEffect,\n\tEdit,\n\tChangeInternal,\n\tChangeNode,\n\tChangeNode_0_0_2,\n\tEditLogSummary,\n\tFluidEditHandle,\n\tSharedTreeSummaryBase,\n\tEditWithoutId,\n\tPlaceholderTree,\n\tEditBase,\n\tHasTraits,\n\tInsertInternal,\n\tDetachInternal,\n\tBuildInternal,\n\tSetValueInternal,\n\tConstraintInternal,\n\tBuildNodeInternal,\n\tStablePlaceInternal_0_0_2,\n\tStableRangeInternal_0_0_2,\n\tNodeData,\n\tTraitMap,\n\tChangeTypeInternal,\n\tTraitLocationInternal_0_0_2,\n\tWriteFormat,\n\tConstraintInternal_0_0_2,\n\tStablePlaceInternal,\n\tStableRangeInternal,\n\tBuildNodeInternal_0_0_2,\n\tBuildInternal_0_0_2,\n\tInsertInternal_0_0_2,\n\tDetachInternal_0_0_2,\n\tSetValueInternal_0_0_2,\n\tTraitLocationInternal,\n} from './persisted-types';\nexport {\n\tSharedTreeFactory,\n\tSharedTree,\n\tEditCommittedHandler,\n\tSequencedEditAppliedHandler,\n\tEditCommittedEventArguments,\n\tSequencedEditAppliedEventArguments,\n\tEditApplicationOutcome,\n\tISharedTreeEvents,\n} from './SharedTree';\nexport * from './EventTypes';\nexport {\n\tsetTrait,\n\tareRevisionViewsSemanticallyEqual,\n\tBadPlaceValidationResult,\n\tBadRangeValidationResult,\n\tPlaceValidationResult,\n\tRangeValidationResult,\n\tRangeValidationResultKind,\n} from './EditUtilities';\nexport { comparePayloads } from './PayloadUtilities';\nexport {\n\tTransactionInternal,\n\tGenericTransaction,\n\tGenericTransactionPolicy,\n\tEditingResult,\n\tEditingResultBase,\n\tFailedEditingResult,\n\tValidEditingResult,\n\tTransactionState,\n\tTransactionFailure,\n\tSucceedingTransactionState,\n\tFailingTransactionState,\n\tChangeResult,\n} from './TransactionInternal';\nexport {\n\tNodeInTrait,\n\tPlaceIndex,\n\tTreeViewNode,\n\tTreeView,\n\tTraitNodeIndex,\n\tTreeViewPlace,\n\tTreeViewRange,\n\tTraitLocation,\n} from './TreeView';\nexport { RevisionView, TransactionView } from './RevisionView';\nexport { NodeIdContext, NodeIdGenerator, NodeIdConverter } from './NodeIdUtilities';\nexport { Transaction } from './Transaction';\n\n/**\n * TODO:#61413: Publish test utilities from a separate test package\n */\nexport {\n\t/** @deprecated Use `getSerializedUploadedEditChunkContents` instead. */\n\tgetSerializedUploadedEditChunkContents as getUploadedEditChunkContents,\n\tgetSerializedUploadedEditChunkContents,\n} from './SummaryTestUtilities';\n\nexport * from './ChangeTypes';\n"]}
@@ -8,14 +8,13 @@ import { EditLog } from '../EditLog';
8
8
  import { CachingLogViewer, } from '../LogViewer';
9
9
  import { assert, copyPropertyIfDefined } from '../Common';
10
10
  import { initialTree } from '../InitialTree';
11
- import { ChangeInternal, ConstraintEffect, EditStatus, StablePlaceInternal, } from '../persisted-types';
11
+ import { ChangeInternal, ChangeTypeInternal, ConstraintEffect, EditStatus, StablePlaceInternal, } from '../persisted-types';
12
12
  import { areRevisionViewsSemanticallyEqual, newEdit } from '../EditUtilities';
13
13
  import { RevisionView } from '../RevisionView';
14
14
  import { TransactionInternal } from '../TransactionInternal';
15
15
  import { StableRange } from '../ChangeTypes';
16
16
  import { expectDefined } from './utilities/TestCommon';
17
17
  import { buildLeaf } from './utilities/TestNode';
18
- import { MockTransaction } from './utilities/MockTransaction';
19
18
  import { refreshTestTree, testTraitLabel } from './utilities/TestUtilities';
20
19
  /**
21
20
  * Creates an {@link EditLog} and accompanying {@link RevisionView} with pre-existing edits.
@@ -182,7 +181,7 @@ describe('CachingLogViewer', () => {
182
181
  });
183
182
  function getCachingLogViewerAssumeAppliedEdits(log, baseView, editStatusCallback, sequencedEditResultCallback, knownRevisions) {
184
183
  return new CachingLogViewer(log, baseView, knownRevisions === null || knownRevisions === void 0 ? void 0 : knownRevisions.map((pair) => [pair[0], { view: pair[1], result: EditStatus.Applied }]),
185
- /* expensiveValidation */ true, editStatusCallback, sequencedEditResultCallback, TransactionInternal.factory, log.numberOfSequencedEdits);
184
+ /* expensiveValidation */ true, editStatusCallback, sequencedEditResultCallback, log.numberOfSequencedEdits);
186
185
  }
187
186
  runLogViewerCorrectnessTests(getCachingLogViewerAssumeAppliedEdits);
188
187
  it('detects non-integer revisions when setting revision views', async () => {
@@ -226,7 +225,12 @@ describe('CachingLogViewer', () => {
226
225
  it('caches edit results for sequenced edits', async () => {
227
226
  // Add an invalid edit
228
227
  simpleLog.addSequencedEdit(newEdit([
229
- ChangeInternal.constraint(StableRange.only(testTree.left), ConstraintEffect.InvalidAndDiscard, undefined, 0),
228
+ {
229
+ type: ChangeTypeInternal.Constraint,
230
+ toConstrain: StableRange.only(testTree.left),
231
+ effect: ConstraintEffect.InvalidAndDiscard,
232
+ length: 0,
233
+ },
230
234
  ]), { sequenceNumber: 3, referenceSequenceNumber: 2, minimumSequenceNumber: 2 });
231
235
  let editsProcessed = 0;
232
236
  const viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, () => editsProcessed++);
@@ -413,7 +417,7 @@ describe('CachingLogViewer', () => {
413
417
  const log = getTestTreeLog(testTree);
414
418
  const events = [];
415
419
  const viewer = new CachingLogViewer(log, simpleLogBaseView, [],
416
- /* expensiveValidation */ true, undefined, (args) => events.push(args), TransactionInternal.factory);
420
+ /* expensiveValidation */ true, undefined, (args) => events.push(args));
417
421
  return { log, viewer, events };
418
422
  }
419
423
  function addInvalidEdit(log) {
@@ -461,8 +465,7 @@ describe('CachingLogViewer', () => {
461
465
  describe('Sequencing', () => {
462
466
  function addFakeEdit(logViewer, sequenceNumber, referenceSequenceNumber) {
463
467
  const id = String(sequenceNumber !== null && sequenceNumber !== void 0 ? sequenceNumber : uuidv4());
464
- const fakeChange = id;
465
- const edit = { changes: [fakeChange], id };
468
+ const edit = { changes: [ChangeInternal.setPayload(simpleLogBaseView.root, id)], id };
466
469
  logViewer.log.addSequencedEdit(edit, {
467
470
  sequenceNumber,
468
471
  referenceSequenceNumber: referenceSequenceNumber !== null && referenceSequenceNumber !== void 0 ? referenceSequenceNumber : sequenceNumber - 1,
@@ -470,8 +473,7 @@ describe('CachingLogViewer', () => {
470
473
  return edit;
471
474
  }
472
475
  function minimalLogViewer() {
473
- return new CachingLogViewer(new EditLog(), simpleLogBaseView, [],
474
- /* expensiveValidation */ true, undefined, undefined, MockTransaction.factory);
476
+ return new CachingLogViewer(new EditLog(), simpleLogBaseView, [], /* expensiveValidation */ true);
475
477
  }
476
478
  it('tracks the earliest sequenced edit in the session', () => {
477
479
  const logViewer = minimalLogViewer();
@@ -527,7 +529,8 @@ describe('CachingLogViewer', () => {
527
529
  expect(actual.length).equals(path.length);
528
530
  for (let i = 0; i < path.length; ++i) {
529
531
  expect(actual[i].length).equals(1);
530
- expect(actual[i][0].resolvedChange).equals(path[i].id);
532
+ const change = actual[i][0].resolvedChange;
533
+ expect(change.payload).equals(path[i].id);
531
534
  }
532
535
  }
533
536
  // Non-sequenced edit
@@ -1 +1 @@
1
- {"version":3,"file":"LogViewer.tests.js","sourceRoot":"","sources":["../../src/test/LogViewer.tests.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 { expect } from 'chai';\nimport { v4 as uuidv4 } from 'uuid';\nimport { EditLog } from '../EditLog';\nimport {\n\tCachingLogViewer,\n\tEditStatusCallback,\n\tLogViewer,\n\tSequencedEditResult,\n\tSequencedEditResultCallback,\n} from '../LogViewer';\nimport { EditId } from '../Identifiers';\nimport { assert, copyPropertyIfDefined } from '../Common';\nimport { initialTree } from '../InitialTree';\nimport {\n\tChangeInternal,\n\tChangeNode,\n\tConstraintEffect,\n\tEdit,\n\tEditStatus,\n\tStablePlaceInternal,\n} from '../persisted-types';\nimport { areRevisionViewsSemanticallyEqual, newEdit } from '../EditUtilities';\nimport { NodeIdContext } from '../NodeIdUtilities';\nimport { RevisionView } from '../RevisionView';\nimport { TransactionInternal } from '../TransactionInternal';\nimport { StableRange } from '../ChangeTypes';\nimport { expectDefined } from './utilities/TestCommon';\nimport { buildLeaf, TestTree } from './utilities/TestNode';\nimport { MockTransaction } from './utilities/MockTransaction';\nimport { refreshTestTree, testTraitLabel } from './utilities/TestUtilities';\n\n/**\n * Creates an {@link EditLog} and accompanying {@link RevisionView} with pre-existing edits.\n *\n * @remarks Intended to be used with {@link getSimpleLogBaseView}\n * @param testTree - Test tree to work on\n * @param numEdits - The number of edits to make to the base tree\n */\nfunction getTestTreeLog(testTree: TestTree): EditLog<ChangeInternal> {\n\tconst log = new EditLog<ChangeInternal>();\n\tlog.addSequencedEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeaf(testTree.left.identifier)],\n\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t),\n\t\t{ sequenceNumber: 1, referenceSequenceNumber: 0 }\n\t);\n\tlog.addSequencedEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeaf(testTree.right.identifier)],\n\t\t\t\tStablePlaceInternal.atStartOf(testTree.right.traitLocation)\n\t\t\t)\n\t\t),\n\t\t{ sequenceNumber: 2, referenceSequenceNumber: 1 }\n\t);\n\n\treturn log;\n}\n\nfunction getLogWithNumEdits(nodeIdContext: NodeIdContext, numEdits: number): EditLog<ChangeInternal> {\n\tconst log = new EditLog<ChangeInternal>();\n\tfor (let i = 0; i < numEdits; i++) {\n\t\tlog.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[buildLeaf(nodeIdContext.generateNodeId())],\n\t\t\t\t\tStablePlaceInternal.atStartOf({\n\t\t\t\t\t\tlabel: testTraitLabel,\n\t\t\t\t\t\tparent: nodeIdContext.convertToNodeId(initialTree.identifier),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t),\n\t\t\t{\n\t\t\t\tsequenceNumber: i + 1,\n\t\t\t\treferenceSequenceNumber: i,\n\t\t\t}\n\t\t);\n\t}\n\n\treturn log;\n}\n\n/**\n * Get a base view for a log created with {@link getTestTreeLog}.\n * This can then be used to construct a {@link LogViewer} for that log.\n *\n * @param testTree - Test tree to work from\n */\nfunction getSimpleLogBaseView(testTree: TestTree): RevisionView {\n\tconst node: ChangeNode = { definition: testTree.definition, identifier: testTree.identifier, traits: {} };\n\tcopyPropertyIfDefined(testTree, node, 'payload');\n\treturn RevisionView.fromTree(node);\n}\n\nfunction getSimpleLogWithLocalEdits(testTree: TestTree): EditLog<ChangeInternal> {\n\tconst logWithLocalEdits = getTestTreeLog(testTree);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\treturn logWithLocalEdits;\n}\n\nfunction getViewsForLog(log: EditLog<ChangeInternal>, baseView: RevisionView): RevisionView[] {\n\tconst views: RevisionView[] = [baseView];\n\tfor (let i = 0; i < log.length; i++) {\n\t\tconst edit = log.getEditInSessionAtIndex(i);\n\t\tconst result = TransactionInternal.factory(views[i]).applyChanges(edit.changes).close();\n\t\tif (result.status === EditStatus.Applied) {\n\t\t\tviews.push(result.after);\n\t\t} else {\n\t\t\texpect.fail('edit failed to apply');\n\t\t}\n\t}\n\treturn views;\n}\n\nfunction runLogViewerCorrectnessTests(\n\tviewerCreator: (log: EditLog<ChangeInternal>, baseView: RevisionView) => LogViewer\n): Mocha.Suite {\n\treturn describe('LogViewer', () => {\n\t\tlet simpleLog: EditLog<ChangeInternal>;\n\t\tlet simpleLogBaseView: RevisionView;\n\t\tlet simpleLogInitialView: RevisionView;\n\t\tconst testTree = refreshTestTree(undefined, (t) => {\n\t\t\tsimpleLogBaseView = getSimpleLogBaseView(t);\n\t\t\tsimpleLog = getTestTreeLog(t);\n\t\t\tsimpleLogInitialView = t.view;\n\t\t});\n\n\t\tit('generates initialTree by default for the 0th revision', () => {\n\t\t\tconst viewer = viewerCreator(new EditLog(), simpleLogBaseView);\n\t\t\tconst headView = viewer.getRevisionViewInSession(0);\n\t\t\texpect(headView.equals(expectDefined(RevisionView.fromTree(initialTree, testTree))));\n\t\t});\n\n\t\tit('can be constructed from a non-empty EditLog', () => {\n\t\t\tconst viewer = viewerCreator(simpleLog, simpleLogBaseView);\n\t\t\tconst headView = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\t\texpect(areRevisionViewsSemanticallyEqual(headView, testTree, simpleLogInitialView, testTree));\n\t\t\texpect(headView.equals(simpleLogInitialView)).to.be.true;\n\t\t});\n\n\t\tit('can generate all revision views for an EditLog', () => {\n\t\t\tconst baseView = expectDefined(RevisionView.fromTree(initialTree, testTree));\n\t\t\tconst numNodes = 10;\n\t\t\tconst viewer = viewerCreator(getLogWithNumEdits(testTree, numNodes), baseView);\n\t\t\tconst initialRevision = viewer.getRevisionViewInSession(0);\n\t\t\texpect(initialRevision.equals(baseView)).to.be.true;\n\t\t\texpect(initialRevision.size).to.equal(1);\n\t\t\tconst oneNodeView = viewer.getRevisionViewInSession(1);\n\t\t\tconst testTrait = {\n\t\t\t\tlabel: testTraitLabel,\n\t\t\t\tparent: testTree.convertToNodeId(initialTree.identifier),\n\t\t\t};\n\t\t\texpect(oneNodeView.getTrait(testTrait).length).to.equal(1);\n\t\t\tconst twoNodeView = viewer.getRevisionViewInSession(2);\n\t\t\texpect(twoNodeView.getTrait(testTrait).length).to.equal(2);\n\t\t\tconst finalView = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\t\texpect(finalView.getTrait(testTrait).length).to.equal(numNodes);\n\t\t});\n\n\t\tit('produces correct revision views when the log is mutated', () => {\n\t\t\tconst mutableLog = new EditLog<ChangeInternal>();\n\t\t\tconst viewer = viewerCreator(mutableLog, simpleLogBaseView);\n\t\t\tconst viewsForLog = getViewsForLog(simpleLog, simpleLogBaseView);\n\t\t\t// This test takes an empty log (A) and a log with edits in it (B), and adds the edits from B to A.\n\t\t\t// After each addition, the test code will iterate from [0, length_of_A] and get a view for each revision via LogViewer\n\t\t\t// and assert that none of the views differ from those created via pure Transaction APIs.\n\t\t\tfor (let i = 0; i <= simpleLog.length; i++) {\n\t\t\t\tfor (let j = 0; j <= mutableLog.length; j++) {\n\t\t\t\t\tconst viewerView = viewer.getRevisionViewInSession(j);\n\t\t\t\t\texpect(viewerView.equals(viewsForLog[j])).to.be.true;\n\t\t\t\t}\n\t\t\t\t// Revisions are from [0, simpleLog.length], edits are at indices [0, simpleLog.length)\n\t\t\t\tif (i < simpleLog.length) {\n\t\t\t\t\tconst edit = simpleLog.getEditInSessionAtIndex(i);\n\t\t\t\t\tmutableLog.addSequencedEdit(edit, { sequenceNumber: i + 1, referenceSequenceNumber: i });\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tit('produces correct revision views when local edits are shifted in the log due to sequenced edits being added', () => {\n\t\t\tfunction getViewsFromViewer(viewer: LogViewer, lastRevision: number): RevisionView[] {\n\t\t\t\tconst views: RevisionView[] = [];\n\t\t\t\tfor (let i = 0; i <= lastRevision; i++) {\n\t\t\t\t\tviews.push(viewer.getRevisionViewInSession(i));\n\t\t\t\t}\n\t\t\t\treturn views;\n\t\t\t}\n\n\t\t\tfunction expectViewsAreEqual(log: EditLog<ChangeInternal>, viewer: LogViewer): void {\n\t\t\t\tconst viewsForLog = getViewsForLog(log, simpleLogBaseView);\n\t\t\t\tconst viewsForViewer = getViewsFromViewer(viewer, log.length);\n\t\t\t\texpect(viewsForLog.length).to.equal(viewsForViewer.length);\n\t\t\t\tfor (let i = 0; i < viewsForLog.length; i++) {\n\t\t\t\t\texpect(viewsForLog[i].equals(viewsForViewer[i])).to.be.true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\t\tconst viewer = viewerCreator(logWithLocalEdits, simpleLogBaseView);\n\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\n\t\t\tlet seqNumber = 1;\n\t\t\t// Sequence the existing local edits and ensure viewer generates the correct views\n\t\t\twhile (logWithLocalEdits.numberOfLocalEdits > 0) {\n\t\t\t\t// Add a remote sequenced edit\n\t\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\t\tnewEdit(\n\t\t\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.right.traitLocation)\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t\t);\n\t\t\t\t++seqNumber;\n\t\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\t\t\t\t// Sequence a local edit\n\t\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\t\tlogWithLocalEdits.getEditInSessionAtIndex(logWithLocalEdits.numberOfSequencedEdits),\n\t\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t\t);\n\t\t\t\t++seqNumber;\n\t\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\t\t\t}\n\t\t});\n\t});\n}\n\ndescribe('CachingLogViewer', () => {\n\t// TODO: Dedupe? shared hook for getting all of this stuff?\n\tlet simpleLog: EditLog<ChangeInternal>;\n\tlet simpleLogBaseView: RevisionView;\n\tlet simpleLogInitialView: RevisionView;\n\t// An arbitrary revision view which can be used to check to see if it gets used when provided as a cached value.\n\tlet arbitraryRevisionView: RevisionView;\n\tconst testTree = refreshTestTree(undefined, (t) => {\n\t\tsimpleLogBaseView = getSimpleLogBaseView(t);\n\t\tsimpleLog = getTestTreeLog(t);\n\t\tsimpleLogInitialView = t.view;\n\t\tarbitraryRevisionView = RevisionView.fromTree(t.buildLeaf(t.generateNodeId()));\n\t});\n\n\tfunction getCachingLogViewerAssumeAppliedEdits(\n\t\tlog: EditLog<ChangeInternal>,\n\t\tbaseView: RevisionView,\n\t\teditStatusCallback?: EditStatusCallback,\n\t\tsequencedEditResultCallback?: SequencedEditResultCallback,\n\t\tknownRevisions?: [number, RevisionView][]\n\t): CachingLogViewer {\n\t\treturn new CachingLogViewer(\n\t\t\tlog,\n\t\t\tbaseView,\n\t\t\tknownRevisions?.map((pair) => [pair[0], { view: pair[1], result: EditStatus.Applied }]),\n\t\t\t/* expensiveValidation */ true,\n\t\t\teditStatusCallback,\n\t\t\tsequencedEditResultCallback,\n\t\t\tTransactionInternal.factory,\n\t\t\tlog.numberOfSequencedEdits\n\t\t);\n\t}\n\n\trunLogViewerCorrectnessTests(getCachingLogViewerAssumeAppliedEdits);\n\n\tit('detects non-integer revisions when setting revision views', async () => {\n\t\texpect(() => {\n\t\t\treturn getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, undefined, undefined, [\n\t\t\t\t[2.4, simpleLogInitialView],\n\t\t\t]);\n\t\t}).to.throw('revision must be an integer');\n\t});\n\n\tit('detects out-of-bounds revisions when setting revision views', async () => {\n\t\texpect(() => {\n\t\t\treturn getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, undefined, undefined, [\n\t\t\t\t[1000, simpleLogInitialView],\n\t\t\t]);\n\t\t}).to.throw('revision must correspond to the result of a SequencedEdit');\n\t});\n\n\tit('can be created with known revisions', async () => {\n\t\tconst views = getViewsForLog(simpleLog, simpleLogBaseView);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tsimpleLog,\n\t\t\tsimpleLogBaseView,\n\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\tArray.from(views.keys()).map((revision) => [revision, views[revision]])\n\t\t);\n\t\tfor (let i = simpleLog.length; i >= 0; i--) {\n\t\t\texpect(viewer.getRevisionViewInSession(i).equals(views[i])).to.be.true;\n\t\t}\n\t});\n\n\tasync function requestAllRevisionViews(viewer: CachingLogViewer, log: EditLog<ChangeInternal>): Promise<void> {\n\t\tfor (let i = 0; i <= log.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t}\n\n\tit('caches revision views for sequenced edits', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, () => editsProcessed++);\n\t\tassert(simpleLog.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\n\t\t// Ask for every view; no edit application should occur, since the views will be cached.\n\t\tfor (let i = 0; i <= simpleLog.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\t});\n\n\tit('caches edit results for sequenced edits', async () => {\n\t\t// Add an invalid edit\n\t\tsimpleLog.addSequencedEdit(\n\t\t\tnewEdit([\n\t\t\t\tChangeInternal.constraint(\n\t\t\t\t\tStableRange.only(testTree.left),\n\t\t\t\t\tConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\tundefined,\n\t\t\t\t\t0\n\t\t\t\t),\n\t\t\t]),\n\t\t\t{ sequenceNumber: 3, referenceSequenceNumber: 2, minimumSequenceNumber: 2 }\n\t\t);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, () => editsProcessed++);\n\t\tassert(simpleLog.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\n\t\texpect((await viewer.getEditResult(0)).status).equals(undefined);\n\t\texpect((await viewer.getEditResult(1)).status).equals(EditStatus.Applied);\n\t\texpect((await viewer.getEditResult(2)).status).equals(EditStatus.Applied);\n\t\texpect((await viewer.getEditResult(3)).status).equals(EditStatus.Invalid);\n\n\t\texpect(viewer.getEditResultInSession(0).status).equals(undefined);\n\t\texpect(viewer.getEditResultInSession(1).status).equals(EditStatus.Applied);\n\t\texpect(viewer.getEditResultInSession(2).status).equals(EditStatus.Applied);\n\t\texpect(viewer.getEditResultInSession(3).status).equals(EditStatus.Invalid);\n\t});\n\n\tit('caches the highest revision', async () => {\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView);\n\t\texpect(viewer.highestRevisionCached()).to.be.false;\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(viewer.highestRevisionCached()).to.be.true;\n\t\tsimpleLog.addLocalEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t\tsimpleLog.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t),\n\t\t\t{\n\t\t\t\tsequenceNumber: 3,\n\t\t\t\treferenceSequenceNumber: 2,\n\t\t\t\tminimumSequenceNumber: 2,\n\t\t\t}\n\t\t);\n\t\texpect(viewer.highestRevisionCached()).to.be.false;\n\t});\n\n\tit('evicts least recently set cached revision views for sequenced edits', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst log = getLogWithNumEdits(testTree, CachingLogViewer.sequencedCacheSizeMax * 2);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlog,\n\t\t\texpectDefined(RevisionView.fromTree(initialTree, testTree)),\n\t\t\t() => editsProcessed++\n\t\t);\n\t\tviewer.setMinimumSequenceNumber(log.length + 1); // simulate all edits being subject to eviction\n\n\t\tawait requestAllRevisionViews(viewer, log);\n\t\texpect(editsProcessed).to.equal(log.length);\n\n\t\teditsProcessed = 0;\n\t\tfor (let i = CachingLogViewer.sequencedCacheSizeMax + 1; i <= log.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(0);\n\n\t\tawait viewer.getRevisionView(CachingLogViewer.sequencedCacheSizeMax);\n\t\texpect(editsProcessed).to.equal(CachingLogViewer.sequencedCacheSizeMax);\n\t});\n\n\tit('never evicts the revision view for the most recent sequenced edit', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst log = getLogWithNumEdits(testTree, CachingLogViewer.sequencedCacheSizeMax * 2);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlog,\n\t\t\texpectDefined(RevisionView.fromTree(initialTree, testTree)),\n\t\t\t() => editsProcessed++\n\t\t);\n\n\t\t// Simulate all clients being caught up.\n\t\tviewer.setMinimumSequenceNumber(log.numberOfSequencedEdits);\n\n\t\tawait requestAllRevisionViews(viewer, log);\n\t\texpect(editsProcessed).to.equal(log.length);\n\n\t\teditsProcessed = 0;\n\t\tfor (let i = 0; i <= CachingLogViewer.sequencedCacheSizeMax; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(CachingLogViewer.sequencedCacheSizeMax);\n\n\t\teditsProcessed = 0;\n\t\tawait viewer.getRevisionView(log.numberOfSequencedEdits);\n\t\texpect(editsProcessed).to.equal(0);\n\t});\n\n\tit('caches revision views for local revisions', async () => {\n\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlogWithLocalEdits,\n\t\t\tsimpleLogBaseView,\n\t\t\t() => editsProcessed++\n\t\t);\n\t\tassert(logWithLocalEdits.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, logWithLocalEdits);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.length);\n\n\t\t// Local edits should now be cached until next remote sequenced edit arrives\n\t\teditsProcessed = 0;\n\t\tfor (let i = logWithLocalEdits.numberOfSequencedEdits + 1; i <= logWithLocalEdits.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t\texpect(editsProcessed).to.equal(0);\n\t\t}\n\n\t\t// Add a new local edit, and request the latest view.\n\t\t// This should apply only a single edit, as the most recent HEAD should be cached.\n\t\teditsProcessed = 0;\n\t\tlogWithLocalEdits.addLocalEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t\tawait requestAllRevisionViews(viewer, logWithLocalEdits);\n\t\texpect(editsProcessed).to.equal(1);\n\n\t\teditsProcessed = 0;\n\t\tlet seqNumber = 1;\n\t\twhile (logWithLocalEdits.numberOfLocalEdits > 0) {\n\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\tlogWithLocalEdits.getEditInSessionAtIndex(logWithLocalEdits.numberOfSequencedEdits),\n\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t);\n\t\t\t++seqNumber;\n\t\t\tawait viewer.getRevisionView(logWithLocalEdits.numberOfSequencedEdits); // get the latest (just added) sequenced edit\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY); // get the last view, which is a local revision\n\t\t\texpect(editsProcessed).to.equal(0);\n\t\t}\n\t});\n\n\tit('invalidates cached revision views for local revisions when remote edits are received', () => {\n\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlogWithLocalEdits,\n\t\t\tsimpleLogBaseView,\n\t\t\t() => editsProcessed++\n\t\t);\n\n\t\t// Request twice, should only process edits once\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.length);\n\n\t\t// Remote edit arrives\n\t\teditsProcessed = 0;\n\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t),\n\t\t\t{ sequenceNumber: 3, referenceSequenceNumber: 2, minimumSequenceNumber: 2 }\n\t\t);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.numberOfLocalEdits + 1);\n\t});\n\n\tit('uses known editing result', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(edit, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([true]);\n\t\texpect(after).equal(arbitraryRevisionView);\n\t});\n\n\tit('ignores known editing if for wrong before revision view', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(edit, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore: arbitraryRevisionView,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\texpect(after).not.equal(arbitraryRevisionView);\n\t});\n\n\tit('ignores known editing if for wrong edit', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(newEdit([]), {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\texpect(after).not.equal(arbitraryRevisionView);\n\t});\n\n\tit('uses known editing result with multiple edits', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst edit1 = newEdit([]);\n\t\tconst edit2 = newEdit([]);\n\t\tconst edit3 = newEdit([]);\n\t\tlog.addLocalEdit(edit1);\n\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\tlog.addLocalEdit(edit2);\n\t\tviewer.setKnownEditingResult(edit2, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit2.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false, true]);\n\t\texpect(after).equal(arbitraryRevisionView);\n\t\tlog.addLocalEdit(edit3);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false, true, false]);\n\t});\n\n\tdescribe('Callbacks', () => {\n\t\tfunction getViewer(): {\n\t\t\tlog: EditLog<ChangeInternal>;\n\t\t\tviewer: CachingLogViewer;\n\t\t\tevents: SequencedEditResult[];\n\t\t} {\n\t\t\tconst log = getTestTreeLog(testTree);\n\t\t\tconst events: SequencedEditResult[] = [];\n\t\t\tconst viewer = new CachingLogViewer(\n\t\t\t\tlog,\n\t\t\t\tsimpleLogBaseView,\n\t\t\t\t[],\n\t\t\t\t/* expensiveValidation */ true,\n\t\t\t\tundefined,\n\t\t\t\t(args: SequencedEditResult) => events.push(args),\n\t\t\t\tTransactionInternal.factory\n\t\t\t);\n\t\t\treturn { log, viewer, events };\n\t\t}\n\n\t\tfunction addInvalidEdit(log: EditLog<ChangeInternal>): Edit<ChangeInternal> {\n\t\t\t// Add a local edit that will be invalid (inserts a node at a location that doesn't exist)\n\t\t\tconst edit = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\texpectDefined(\n\t\t\t\t\t\tStablePlaceInternal.atEndOf({\n\t\t\t\t\t\t\tlabel: testTraitLabel,\n\t\t\t\t\t\t\tparent: testTree.generateNodeId(),\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addLocalEdit(edit);\n\t\t\treturn edit;\n\t\t}\n\n\t\tit('processSequencedEditResult is called when a sequenced edit is applied', async () => {\n\t\t\tconst { log, events, viewer } = getViewer();\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\tevents.splice(0);\n\n\t\t\t// Non-sequenced edit should not trigger a call\n\t\t\tconst invalidEdit = addInvalidEdit(log);\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(0);\n\n\t\t\tlog.addSequencedEdit(invalidEdit, { sequenceNumber: 3, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(1);\n\t\t\texpect(events[0].edit.id).equals(invalidEdit.id);\n\t\t\texpect(events[0].wasLocal).equals(true);\n\t\t\texpect(events[0].result.status).equals(EditStatus.Invalid);\n\t\t\texpect(events[0].reconciliationPath.length).equals(0);\n\n\t\t\tconst validEdit1 = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addSequencedEdit(validEdit1, { sequenceNumber: 3, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(2);\n\t\t\texpect(events[1].edit.id).equals(validEdit1.id);\n\t\t\texpect(events[1].wasLocal).equals(false);\n\t\t\texpect(events[1].result.status).equals(EditStatus.Applied);\n\t\t\texpect(events[1].reconciliationPath.length).equals(0);\n\n\t\t\tconst validEdit2 = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addSequencedEdit(validEdit2, { sequenceNumber: 4, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(3);\n\t\t\texpect(events[2].edit.id).equals(validEdit2.id);\n\t\t\texpect(events[2].wasLocal).equals(false);\n\t\t\texpect(events[2].result.status).equals(EditStatus.Applied);\n\t\t\texpect(events[2].reconciliationPath.length).equals(1);\n\t\t});\n\t});\n\n\tdescribe('Sequencing', () => {\n\t\tfunction addFakeEdit(\n\t\t\tlogViewer: CachingLogViewer,\n\t\t\tsequenceNumber: number,\n\t\t\treferenceSequenceNumber?: number\n\t\t): Edit<unknown> {\n\t\t\tconst id = String(sequenceNumber ?? uuidv4()) as EditId;\n\t\t\tconst fakeChange = id;\n\t\t\tconst edit = { changes: [fakeChange], id } as unknown as Edit<ChangeInternal>;\n\t\t\tlogViewer.log.addSequencedEdit(edit, {\n\t\t\t\tsequenceNumber,\n\t\t\t\treferenceSequenceNumber: referenceSequenceNumber ?? sequenceNumber - 1,\n\t\t\t});\n\t\t\treturn edit;\n\t\t}\n\n\t\tfunction minimalLogViewer(): CachingLogViewer {\n\t\t\treturn new CachingLogViewer(\n\t\t\t\tnew EditLog(),\n\t\t\t\tsimpleLogBaseView,\n\t\t\t\t[],\n\t\t\t\t/* expensiveValidation */ true,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\tMockTransaction.factory\n\t\t\t);\n\t\t}\n\n\t\tit('tracks the earliest sequenced edit in the session', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).undefined;\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).undefined;\n\n\t\t\t// First sequenced edit\n\t\t\tconst edit = addFakeEdit(logViewer, 123);\n\t\t\tconst expected = { edit, sequenceNumber: 123 };\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\n\t\t\t// Second sequenced edit\n\t\t\taddFakeEdit(logViewer, 456);\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\t\t});\n\n\t\tit('can provide edit results for sequenced edits', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\n\t\t\t// First sequenced edit\n\t\t\tconst edit1 = addFakeEdit(logViewer, 123);\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\t\t\tconst expected1 = {\n\t\t\t\tid: edit1.id,\n\t\t\t};\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(123)).contains(expected1);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(124)).contains(expected1);\n\n\t\t\t// Second sequenced edit\n\t\t\t// Note that this edit is given a greater sequence number than simply incrementing after edit 1.\n\t\t\t// This is deliberately done to simulate scenarios where a given DDS may not be sent all sequenced ops (because an other DDS\n\t\t\t// might be receiving them).\n\t\t\tconst edit2 = addFakeEdit(logViewer, 456);\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(123)).contains(expected1);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(124)).contains(expected1);\n\t\t\tconst expected2 = {\n\t\t\t\tid: edit2.id,\n\t\t\t};\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(456)).contains(expected2);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(457)).contains(expected2);\n\t\t});\n\n\t\tit('can provide the reconciliation path for an edit', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\n\t\t\tfunction expectReconciliationPath(edit: Edit<unknown>, path: Edit<unknown>[]) {\n\t\t\t\tconst actual = logViewer.reconciliationPathFromEdit(edit.id);\n\t\t\t\texpect(actual.length).equals(path.length);\n\t\t\t\tfor (let i = 0; i < path.length; ++i) {\n\t\t\t\t\texpect(actual[i].length).equals(1);\n\t\t\t\t\texpect(actual[i][0].resolvedChange).equals(path[i].id);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Non-sequenced edit\n\t\t\tconst nonSeqEdit = { id: uuidv4() as EditId, changes: [] };\n\t\t\tlogViewer.log.addLocalEdit(nonSeqEdit);\n\t\t\texpectReconciliationPath(nonSeqEdit, []);\n\n\t\t\tconst edit1 = addFakeEdit(logViewer, 1001);\n\t\t\texpectReconciliationPath(edit1, []);\n\n\t\t\t// Note that this edit is given a greater sequence number than simply incrementing after edit 1.\n\t\t\t// This is deliberately done to simulate scenarios where a given DDS may not be sent all sequenced ops (because an other DDS\n\t\t\t// might be receiving them).\n\t\t\tconst edit2 = addFakeEdit(logViewer, 2001, 1001);\n\t\t\texpectReconciliationPath(edit2, []);\n\n\t\t\tconst edit3 = addFakeEdit(logViewer, 3001, 2000);\n\t\t\texpectReconciliationPath(edit3, [edit2]);\n\n\t\t\tconst edit4 = addFakeEdit(logViewer, 4001, 2500);\n\t\t\texpectReconciliationPath(edit4, [edit3]);\n\n\t\t\tconst edit5 = addFakeEdit(logViewer, 5001, 500);\n\t\t\texpectReconciliationPath(edit5, [edit1, edit2, edit3, edit4]);\n\t\t});\n\t});\n});\n"]}
1
+ {"version":3,"file":"LogViewer.tests.js","sourceRoot":"","sources":["../../src/test/LogViewer.tests.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 { expect } from 'chai';\nimport { v4 as uuidv4 } from 'uuid';\nimport { EditLog } from '../EditLog';\nimport {\n\tCachingLogViewer,\n\tEditStatusCallback,\n\tLogViewer,\n\tSequencedEditResult,\n\tSequencedEditResultCallback,\n} from '../LogViewer';\nimport { EditId } from '../Identifiers';\nimport { assert, copyPropertyIfDefined } from '../Common';\nimport { initialTree } from '../InitialTree';\nimport {\n\tChangeInternal,\n\tChangeNode,\n\tChangeTypeInternal,\n\tConstraintEffect,\n\tEdit,\n\tEditStatus,\n\tSetValueInternal,\n\tStablePlaceInternal,\n} from '../persisted-types';\nimport { areRevisionViewsSemanticallyEqual, newEdit } from '../EditUtilities';\nimport { NodeIdContext } from '../NodeIdUtilities';\nimport { RevisionView } from '../RevisionView';\nimport { TransactionInternal } from '../TransactionInternal';\nimport { Change, ChangeType, StableRange } from '../ChangeTypes';\nimport { expectDefined } from './utilities/TestCommon';\nimport { buildLeaf, TestTree } from './utilities/TestNode';\nimport { refreshTestTree, testTraitLabel } from './utilities/TestUtilities';\n\n/**\n * Creates an {@link EditLog} and accompanying {@link RevisionView} with pre-existing edits.\n *\n * @remarks Intended to be used with {@link getSimpleLogBaseView}\n * @param testTree - Test tree to work on\n * @param numEdits - The number of edits to make to the base tree\n */\nfunction getTestTreeLog(testTree: TestTree): EditLog<ChangeInternal> {\n\tconst log = new EditLog<ChangeInternal>();\n\tlog.addSequencedEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeaf(testTree.left.identifier)],\n\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t),\n\t\t{ sequenceNumber: 1, referenceSequenceNumber: 0 }\n\t);\n\tlog.addSequencedEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeaf(testTree.right.identifier)],\n\t\t\t\tStablePlaceInternal.atStartOf(testTree.right.traitLocation)\n\t\t\t)\n\t\t),\n\t\t{ sequenceNumber: 2, referenceSequenceNumber: 1 }\n\t);\n\n\treturn log;\n}\n\nfunction getLogWithNumEdits(nodeIdContext: NodeIdContext, numEdits: number): EditLog<ChangeInternal> {\n\tconst log = new EditLog<ChangeInternal>();\n\tfor (let i = 0; i < numEdits; i++) {\n\t\tlog.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[buildLeaf(nodeIdContext.generateNodeId())],\n\t\t\t\t\tStablePlaceInternal.atStartOf({\n\t\t\t\t\t\tlabel: testTraitLabel,\n\t\t\t\t\t\tparent: nodeIdContext.convertToNodeId(initialTree.identifier),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t),\n\t\t\t{\n\t\t\t\tsequenceNumber: i + 1,\n\t\t\t\treferenceSequenceNumber: i,\n\t\t\t}\n\t\t);\n\t}\n\n\treturn log;\n}\n\n/**\n * Get a base view for a log created with {@link getTestTreeLog}.\n * This can then be used to construct a {@link LogViewer} for that log.\n *\n * @param testTree - Test tree to work from\n */\nfunction getSimpleLogBaseView(testTree: TestTree): RevisionView {\n\tconst node: ChangeNode = { definition: testTree.definition, identifier: testTree.identifier, traits: {} };\n\tcopyPropertyIfDefined(testTree, node, 'payload');\n\treturn RevisionView.fromTree(node);\n}\n\nfunction getSimpleLogWithLocalEdits(testTree: TestTree): EditLog<ChangeInternal> {\n\tconst logWithLocalEdits = getTestTreeLog(testTree);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\treturn logWithLocalEdits;\n}\n\nfunction getViewsForLog(log: EditLog<ChangeInternal>, baseView: RevisionView): RevisionView[] {\n\tconst views: RevisionView[] = [baseView];\n\tfor (let i = 0; i < log.length; i++) {\n\t\tconst edit = log.getEditInSessionAtIndex(i);\n\t\tconst result = TransactionInternal.factory(views[i]).applyChanges(edit.changes).close();\n\t\tif (result.status === EditStatus.Applied) {\n\t\t\tviews.push(result.after);\n\t\t} else {\n\t\t\texpect.fail('edit failed to apply');\n\t\t}\n\t}\n\treturn views;\n}\n\nfunction runLogViewerCorrectnessTests(\n\tviewerCreator: (log: EditLog<ChangeInternal>, baseView: RevisionView) => LogViewer\n): Mocha.Suite {\n\treturn describe('LogViewer', () => {\n\t\tlet simpleLog: EditLog<ChangeInternal>;\n\t\tlet simpleLogBaseView: RevisionView;\n\t\tlet simpleLogInitialView: RevisionView;\n\t\tconst testTree = refreshTestTree(undefined, (t) => {\n\t\t\tsimpleLogBaseView = getSimpleLogBaseView(t);\n\t\t\tsimpleLog = getTestTreeLog(t);\n\t\t\tsimpleLogInitialView = t.view;\n\t\t});\n\n\t\tit('generates initialTree by default for the 0th revision', () => {\n\t\t\tconst viewer = viewerCreator(new EditLog(), simpleLogBaseView);\n\t\t\tconst headView = viewer.getRevisionViewInSession(0);\n\t\t\texpect(headView.equals(expectDefined(RevisionView.fromTree(initialTree, testTree))));\n\t\t});\n\n\t\tit('can be constructed from a non-empty EditLog', () => {\n\t\t\tconst viewer = viewerCreator(simpleLog, simpleLogBaseView);\n\t\t\tconst headView = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\t\texpect(areRevisionViewsSemanticallyEqual(headView, testTree, simpleLogInitialView, testTree));\n\t\t\texpect(headView.equals(simpleLogInitialView)).to.be.true;\n\t\t});\n\n\t\tit('can generate all revision views for an EditLog', () => {\n\t\t\tconst baseView = expectDefined(RevisionView.fromTree(initialTree, testTree));\n\t\t\tconst numNodes = 10;\n\t\t\tconst viewer = viewerCreator(getLogWithNumEdits(testTree, numNodes), baseView);\n\t\t\tconst initialRevision = viewer.getRevisionViewInSession(0);\n\t\t\texpect(initialRevision.equals(baseView)).to.be.true;\n\t\t\texpect(initialRevision.size).to.equal(1);\n\t\t\tconst oneNodeView = viewer.getRevisionViewInSession(1);\n\t\t\tconst testTrait = {\n\t\t\t\tlabel: testTraitLabel,\n\t\t\t\tparent: testTree.convertToNodeId(initialTree.identifier),\n\t\t\t};\n\t\t\texpect(oneNodeView.getTrait(testTrait).length).to.equal(1);\n\t\t\tconst twoNodeView = viewer.getRevisionViewInSession(2);\n\t\t\texpect(twoNodeView.getTrait(testTrait).length).to.equal(2);\n\t\t\tconst finalView = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\t\texpect(finalView.getTrait(testTrait).length).to.equal(numNodes);\n\t\t});\n\n\t\tit('produces correct revision views when the log is mutated', () => {\n\t\t\tconst mutableLog = new EditLog<ChangeInternal>();\n\t\t\tconst viewer = viewerCreator(mutableLog, simpleLogBaseView);\n\t\t\tconst viewsForLog = getViewsForLog(simpleLog, simpleLogBaseView);\n\t\t\t// This test takes an empty log (A) and a log with edits in it (B), and adds the edits from B to A.\n\t\t\t// After each addition, the test code will iterate from [0, length_of_A] and get a view for each revision via LogViewer\n\t\t\t// and assert that none of the views differ from those created via pure Transaction APIs.\n\t\t\tfor (let i = 0; i <= simpleLog.length; i++) {\n\t\t\t\tfor (let j = 0; j <= mutableLog.length; j++) {\n\t\t\t\t\tconst viewerView = viewer.getRevisionViewInSession(j);\n\t\t\t\t\texpect(viewerView.equals(viewsForLog[j])).to.be.true;\n\t\t\t\t}\n\t\t\t\t// Revisions are from [0, simpleLog.length], edits are at indices [0, simpleLog.length)\n\t\t\t\tif (i < simpleLog.length) {\n\t\t\t\t\tconst edit = simpleLog.getEditInSessionAtIndex(i);\n\t\t\t\t\tmutableLog.addSequencedEdit(edit, { sequenceNumber: i + 1, referenceSequenceNumber: i });\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tit('produces correct revision views when local edits are shifted in the log due to sequenced edits being added', () => {\n\t\t\tfunction getViewsFromViewer(viewer: LogViewer, lastRevision: number): RevisionView[] {\n\t\t\t\tconst views: RevisionView[] = [];\n\t\t\t\tfor (let i = 0; i <= lastRevision; i++) {\n\t\t\t\t\tviews.push(viewer.getRevisionViewInSession(i));\n\t\t\t\t}\n\t\t\t\treturn views;\n\t\t\t}\n\n\t\t\tfunction expectViewsAreEqual(log: EditLog<ChangeInternal>, viewer: LogViewer): void {\n\t\t\t\tconst viewsForLog = getViewsForLog(log, simpleLogBaseView);\n\t\t\t\tconst viewsForViewer = getViewsFromViewer(viewer, log.length);\n\t\t\t\texpect(viewsForLog.length).to.equal(viewsForViewer.length);\n\t\t\t\tfor (let i = 0; i < viewsForLog.length; i++) {\n\t\t\t\t\texpect(viewsForLog[i].equals(viewsForViewer[i])).to.be.true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\t\tconst viewer = viewerCreator(logWithLocalEdits, simpleLogBaseView);\n\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\n\t\t\tlet seqNumber = 1;\n\t\t\t// Sequence the existing local edits and ensure viewer generates the correct views\n\t\t\twhile (logWithLocalEdits.numberOfLocalEdits > 0) {\n\t\t\t\t// Add a remote sequenced edit\n\t\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\t\tnewEdit(\n\t\t\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.right.traitLocation)\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t\t);\n\t\t\t\t++seqNumber;\n\t\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\t\t\t\t// Sequence a local edit\n\t\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\t\tlogWithLocalEdits.getEditInSessionAtIndex(logWithLocalEdits.numberOfSequencedEdits),\n\t\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t\t);\n\t\t\t\t++seqNumber;\n\t\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\t\t\t}\n\t\t});\n\t});\n}\n\ndescribe('CachingLogViewer', () => {\n\t// TODO: Dedupe? shared hook for getting all of this stuff?\n\tlet simpleLog: EditLog<ChangeInternal>;\n\tlet simpleLogBaseView: RevisionView;\n\tlet simpleLogInitialView: RevisionView;\n\t// An arbitrary revision view which can be used to check to see if it gets used when provided as a cached value.\n\tlet arbitraryRevisionView: RevisionView;\n\tconst testTree = refreshTestTree(undefined, (t) => {\n\t\tsimpleLogBaseView = getSimpleLogBaseView(t);\n\t\tsimpleLog = getTestTreeLog(t);\n\t\tsimpleLogInitialView = t.view;\n\t\tarbitraryRevisionView = RevisionView.fromTree(t.buildLeaf(t.generateNodeId()));\n\t});\n\n\tfunction getCachingLogViewerAssumeAppliedEdits(\n\t\tlog: EditLog<ChangeInternal>,\n\t\tbaseView: RevisionView,\n\t\teditStatusCallback?: EditStatusCallback,\n\t\tsequencedEditResultCallback?: SequencedEditResultCallback,\n\t\tknownRevisions?: [number, RevisionView][]\n\t): CachingLogViewer {\n\t\treturn new CachingLogViewer(\n\t\t\tlog,\n\t\t\tbaseView,\n\t\t\tknownRevisions?.map((pair) => [pair[0], { view: pair[1], result: EditStatus.Applied }]),\n\t\t\t/* expensiveValidation */ true,\n\t\t\teditStatusCallback,\n\t\t\tsequencedEditResultCallback,\n\t\t\tlog.numberOfSequencedEdits\n\t\t);\n\t}\n\n\trunLogViewerCorrectnessTests(getCachingLogViewerAssumeAppliedEdits);\n\n\tit('detects non-integer revisions when setting revision views', async () => {\n\t\texpect(() => {\n\t\t\treturn getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, undefined, undefined, [\n\t\t\t\t[2.4, simpleLogInitialView],\n\t\t\t]);\n\t\t}).to.throw('revision must be an integer');\n\t});\n\n\tit('detects out-of-bounds revisions when setting revision views', async () => {\n\t\texpect(() => {\n\t\t\treturn getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, undefined, undefined, [\n\t\t\t\t[1000, simpleLogInitialView],\n\t\t\t]);\n\t\t}).to.throw('revision must correspond to the result of a SequencedEdit');\n\t});\n\n\tit('can be created with known revisions', async () => {\n\t\tconst views = getViewsForLog(simpleLog, simpleLogBaseView);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tsimpleLog,\n\t\t\tsimpleLogBaseView,\n\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\tArray.from(views.keys()).map((revision) => [revision, views[revision]])\n\t\t);\n\t\tfor (let i = simpleLog.length; i >= 0; i--) {\n\t\t\texpect(viewer.getRevisionViewInSession(i).equals(views[i])).to.be.true;\n\t\t}\n\t});\n\n\tasync function requestAllRevisionViews(viewer: CachingLogViewer, log: EditLog<ChangeInternal>): Promise<void> {\n\t\tfor (let i = 0; i <= log.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t}\n\n\tit('caches revision views for sequenced edits', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, () => editsProcessed++);\n\t\tassert(simpleLog.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\n\t\t// Ask for every view; no edit application should occur, since the views will be cached.\n\t\tfor (let i = 0; i <= simpleLog.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\t});\n\n\tit('caches edit results for sequenced edits', async () => {\n\t\t// Add an invalid edit\n\t\tsimpleLog.addSequencedEdit(\n\t\t\tnewEdit([\n\t\t\t\t{\n\t\t\t\t\ttype: ChangeTypeInternal.Constraint,\n\t\t\t\t\ttoConstrain: StableRange.only(testTree.left),\n\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\tlength: 0,\n\t\t\t\t},\n\t\t\t]),\n\t\t\t{ sequenceNumber: 3, referenceSequenceNumber: 2, minimumSequenceNumber: 2 }\n\t\t);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, () => editsProcessed++);\n\t\tassert(simpleLog.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\n\t\texpect((await viewer.getEditResult(0)).status).equals(undefined);\n\t\texpect((await viewer.getEditResult(1)).status).equals(EditStatus.Applied);\n\t\texpect((await viewer.getEditResult(2)).status).equals(EditStatus.Applied);\n\t\texpect((await viewer.getEditResult(3)).status).equals(EditStatus.Invalid);\n\n\t\texpect(viewer.getEditResultInSession(0).status).equals(undefined);\n\t\texpect(viewer.getEditResultInSession(1).status).equals(EditStatus.Applied);\n\t\texpect(viewer.getEditResultInSession(2).status).equals(EditStatus.Applied);\n\t\texpect(viewer.getEditResultInSession(3).status).equals(EditStatus.Invalid);\n\t});\n\n\tit('caches the highest revision', async () => {\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView);\n\t\texpect(viewer.highestRevisionCached()).to.be.false;\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(viewer.highestRevisionCached()).to.be.true;\n\t\tsimpleLog.addLocalEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t\tsimpleLog.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t),\n\t\t\t{\n\t\t\t\tsequenceNumber: 3,\n\t\t\t\treferenceSequenceNumber: 2,\n\t\t\t\tminimumSequenceNumber: 2,\n\t\t\t}\n\t\t);\n\t\texpect(viewer.highestRevisionCached()).to.be.false;\n\t});\n\n\tit('evicts least recently set cached revision views for sequenced edits', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst log = getLogWithNumEdits(testTree, CachingLogViewer.sequencedCacheSizeMax * 2);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlog,\n\t\t\texpectDefined(RevisionView.fromTree(initialTree, testTree)),\n\t\t\t() => editsProcessed++\n\t\t);\n\t\tviewer.setMinimumSequenceNumber(log.length + 1); // simulate all edits being subject to eviction\n\n\t\tawait requestAllRevisionViews(viewer, log);\n\t\texpect(editsProcessed).to.equal(log.length);\n\n\t\teditsProcessed = 0;\n\t\tfor (let i = CachingLogViewer.sequencedCacheSizeMax + 1; i <= log.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(0);\n\n\t\tawait viewer.getRevisionView(CachingLogViewer.sequencedCacheSizeMax);\n\t\texpect(editsProcessed).to.equal(CachingLogViewer.sequencedCacheSizeMax);\n\t});\n\n\tit('never evicts the revision view for the most recent sequenced edit', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst log = getLogWithNumEdits(testTree, CachingLogViewer.sequencedCacheSizeMax * 2);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlog,\n\t\t\texpectDefined(RevisionView.fromTree(initialTree, testTree)),\n\t\t\t() => editsProcessed++\n\t\t);\n\n\t\t// Simulate all clients being caught up.\n\t\tviewer.setMinimumSequenceNumber(log.numberOfSequencedEdits);\n\n\t\tawait requestAllRevisionViews(viewer, log);\n\t\texpect(editsProcessed).to.equal(log.length);\n\n\t\teditsProcessed = 0;\n\t\tfor (let i = 0; i <= CachingLogViewer.sequencedCacheSizeMax; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(CachingLogViewer.sequencedCacheSizeMax);\n\n\t\teditsProcessed = 0;\n\t\tawait viewer.getRevisionView(log.numberOfSequencedEdits);\n\t\texpect(editsProcessed).to.equal(0);\n\t});\n\n\tit('caches revision views for local revisions', async () => {\n\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlogWithLocalEdits,\n\t\t\tsimpleLogBaseView,\n\t\t\t() => editsProcessed++\n\t\t);\n\t\tassert(logWithLocalEdits.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, logWithLocalEdits);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.length);\n\n\t\t// Local edits should now be cached until next remote sequenced edit arrives\n\t\teditsProcessed = 0;\n\t\tfor (let i = logWithLocalEdits.numberOfSequencedEdits + 1; i <= logWithLocalEdits.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t\texpect(editsProcessed).to.equal(0);\n\t\t}\n\n\t\t// Add a new local edit, and request the latest view.\n\t\t// This should apply only a single edit, as the most recent HEAD should be cached.\n\t\teditsProcessed = 0;\n\t\tlogWithLocalEdits.addLocalEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t\tawait requestAllRevisionViews(viewer, logWithLocalEdits);\n\t\texpect(editsProcessed).to.equal(1);\n\n\t\teditsProcessed = 0;\n\t\tlet seqNumber = 1;\n\t\twhile (logWithLocalEdits.numberOfLocalEdits > 0) {\n\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\tlogWithLocalEdits.getEditInSessionAtIndex(logWithLocalEdits.numberOfSequencedEdits),\n\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t);\n\t\t\t++seqNumber;\n\t\t\tawait viewer.getRevisionView(logWithLocalEdits.numberOfSequencedEdits); // get the latest (just added) sequenced edit\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY); // get the last view, which is a local revision\n\t\t\texpect(editsProcessed).to.equal(0);\n\t\t}\n\t});\n\n\tit('invalidates cached revision views for local revisions when remote edits are received', () => {\n\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlogWithLocalEdits,\n\t\t\tsimpleLogBaseView,\n\t\t\t() => editsProcessed++\n\t\t);\n\n\t\t// Request twice, should only process edits once\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.length);\n\n\t\t// Remote edit arrives\n\t\teditsProcessed = 0;\n\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t),\n\t\t\t{ sequenceNumber: 3, referenceSequenceNumber: 2, minimumSequenceNumber: 2 }\n\t\t);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.numberOfLocalEdits + 1);\n\t});\n\n\tit('uses known editing result', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(edit, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([true]);\n\t\texpect(after).equal(arbitraryRevisionView);\n\t});\n\n\tit('ignores known editing if for wrong before revision view', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(edit, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore: arbitraryRevisionView,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\texpect(after).not.equal(arbitraryRevisionView);\n\t});\n\n\tit('ignores known editing if for wrong edit', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(newEdit([]), {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\texpect(after).not.equal(arbitraryRevisionView);\n\t});\n\n\tit('uses known editing result with multiple edits', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst edit1 = newEdit([]);\n\t\tconst edit2 = newEdit([]);\n\t\tconst edit3 = newEdit([]);\n\t\tlog.addLocalEdit(edit1);\n\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\tlog.addLocalEdit(edit2);\n\t\tviewer.setKnownEditingResult(edit2, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit2.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false, true]);\n\t\texpect(after).equal(arbitraryRevisionView);\n\t\tlog.addLocalEdit(edit3);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false, true, false]);\n\t});\n\n\tdescribe('Callbacks', () => {\n\t\tfunction getViewer(): {\n\t\t\tlog: EditLog<ChangeInternal>;\n\t\t\tviewer: CachingLogViewer;\n\t\t\tevents: SequencedEditResult[];\n\t\t} {\n\t\t\tconst log = getTestTreeLog(testTree);\n\t\t\tconst events: SequencedEditResult[] = [];\n\t\t\tconst viewer = new CachingLogViewer(\n\t\t\t\tlog,\n\t\t\t\tsimpleLogBaseView,\n\t\t\t\t[],\n\t\t\t\t/* expensiveValidation */ true,\n\t\t\t\tundefined,\n\t\t\t\t(args: SequencedEditResult) => events.push(args)\n\t\t\t);\n\t\t\treturn { log, viewer, events };\n\t\t}\n\n\t\tfunction addInvalidEdit(log: EditLog<ChangeInternal>): Edit<ChangeInternal> {\n\t\t\t// Add a local edit that will be invalid (inserts a node at a location that doesn't exist)\n\t\t\tconst edit = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\texpectDefined(\n\t\t\t\t\t\tStablePlaceInternal.atEndOf({\n\t\t\t\t\t\t\tlabel: testTraitLabel,\n\t\t\t\t\t\t\tparent: testTree.generateNodeId(),\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addLocalEdit(edit);\n\t\t\treturn edit;\n\t\t}\n\n\t\tit('processSequencedEditResult is called when a sequenced edit is applied', async () => {\n\t\t\tconst { log, events, viewer } = getViewer();\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\tevents.splice(0);\n\n\t\t\t// Non-sequenced edit should not trigger a call\n\t\t\tconst invalidEdit = addInvalidEdit(log);\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(0);\n\n\t\t\tlog.addSequencedEdit(invalidEdit, { sequenceNumber: 3, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(1);\n\t\t\texpect(events[0].edit.id).equals(invalidEdit.id);\n\t\t\texpect(events[0].wasLocal).equals(true);\n\t\t\texpect(events[0].result.status).equals(EditStatus.Invalid);\n\t\t\texpect(events[0].reconciliationPath.length).equals(0);\n\n\t\t\tconst validEdit1 = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addSequencedEdit(validEdit1, { sequenceNumber: 3, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(2);\n\t\t\texpect(events[1].edit.id).equals(validEdit1.id);\n\t\t\texpect(events[1].wasLocal).equals(false);\n\t\t\texpect(events[1].result.status).equals(EditStatus.Applied);\n\t\t\texpect(events[1].reconciliationPath.length).equals(0);\n\n\t\t\tconst validEdit2 = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addSequencedEdit(validEdit2, { sequenceNumber: 4, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(3);\n\t\t\texpect(events[2].edit.id).equals(validEdit2.id);\n\t\t\texpect(events[2].wasLocal).equals(false);\n\t\t\texpect(events[2].result.status).equals(EditStatus.Applied);\n\t\t\texpect(events[2].reconciliationPath.length).equals(1);\n\t\t});\n\t});\n\n\tdescribe('Sequencing', () => {\n\t\tfunction addFakeEdit(\n\t\t\tlogViewer: CachingLogViewer,\n\t\t\tsequenceNumber: number,\n\t\t\treferenceSequenceNumber?: number\n\t\t): Edit<unknown> {\n\t\t\tconst id = String(sequenceNumber ?? uuidv4()) as EditId;\n\t\t\tconst edit = { changes: [ChangeInternal.setPayload(simpleLogBaseView.root, id)], id };\n\t\t\tlogViewer.log.addSequencedEdit(edit, {\n\t\t\t\tsequenceNumber,\n\t\t\t\treferenceSequenceNumber: referenceSequenceNumber ?? sequenceNumber - 1,\n\t\t\t});\n\t\t\treturn edit;\n\t\t}\n\n\t\tfunction minimalLogViewer(): CachingLogViewer {\n\t\t\treturn new CachingLogViewer(new EditLog(), simpleLogBaseView, [], /* expensiveValidation */ true);\n\t\t}\n\n\t\tit('tracks the earliest sequenced edit in the session', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).undefined;\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).undefined;\n\n\t\t\t// First sequenced edit\n\t\t\tconst edit = addFakeEdit(logViewer, 123);\n\t\t\tconst expected = { edit, sequenceNumber: 123 };\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\n\t\t\t// Second sequenced edit\n\t\t\taddFakeEdit(logViewer, 456);\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\t\t});\n\n\t\tit('can provide edit results for sequenced edits', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\n\t\t\t// First sequenced edit\n\t\t\tconst edit1 = addFakeEdit(logViewer, 123);\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\t\t\tconst expected1 = {\n\t\t\t\tid: edit1.id,\n\t\t\t};\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(123)).contains(expected1);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(124)).contains(expected1);\n\n\t\t\t// Second sequenced edit\n\t\t\t// Note that this edit is given a greater sequence number than simply incrementing after edit 1.\n\t\t\t// This is deliberately done to simulate scenarios where a given DDS may not be sent all sequenced ops (because an other DDS\n\t\t\t// might be receiving them).\n\t\t\tconst edit2 = addFakeEdit(logViewer, 456);\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(123)).contains(expected1);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(124)).contains(expected1);\n\t\t\tconst expected2 = {\n\t\t\t\tid: edit2.id,\n\t\t\t};\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(456)).contains(expected2);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(457)).contains(expected2);\n\t\t});\n\n\t\tit('can provide the reconciliation path for an edit', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\n\t\t\tfunction expectReconciliationPath(edit: Edit<unknown>, path: Edit<unknown>[]) {\n\t\t\t\tconst actual = logViewer.reconciliationPathFromEdit(edit.id);\n\t\t\t\texpect(actual.length).equals(path.length);\n\t\t\t\tfor (let i = 0; i < path.length; ++i) {\n\t\t\t\t\texpect(actual[i].length).equals(1);\n\t\t\t\t\tconst change = actual[i][0].resolvedChange as SetValueInternal;\n\t\t\t\t\texpect(change.payload).equals(path[i].id);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Non-sequenced edit\n\t\t\tconst nonSeqEdit = { id: uuidv4() as EditId, changes: [] };\n\t\t\tlogViewer.log.addLocalEdit(nonSeqEdit);\n\t\t\texpectReconciliationPath(nonSeqEdit, []);\n\n\t\t\tconst edit1 = addFakeEdit(logViewer, 1001);\n\t\t\texpectReconciliationPath(edit1, []);\n\n\t\t\t// Note that this edit is given a greater sequence number than simply incrementing after edit 1.\n\t\t\t// This is deliberately done to simulate scenarios where a given DDS may not be sent all sequenced ops (because an other DDS\n\t\t\t// might be receiving them).\n\t\t\tconst edit2 = addFakeEdit(logViewer, 2001, 1001);\n\t\t\texpectReconciliationPath(edit2, []);\n\n\t\t\tconst edit3 = addFakeEdit(logViewer, 3001, 2000);\n\t\t\texpectReconciliationPath(edit3, [edit2]);\n\n\t\t\tconst edit4 = addFakeEdit(logViewer, 4001, 2500);\n\t\t\texpectReconciliationPath(edit4, [edit3]);\n\n\t\t\tconst edit5 = addFakeEdit(logViewer, 5001, 500);\n\t\t\texpectReconciliationPath(edit5, [edit1, edit2, edit3, edit4]);\n\t\t});\n\t});\n});\n"]}
@@ -5,8 +5,9 @@
5
5
  import { expect } from 'chai';
6
6
  import { EditStatus, WriteFormat } from '../persisted-types';
7
7
  import { Change, StablePlace, StableRange } from '../ChangeTypes';
8
- import { Transaction } from '../Transaction';
8
+ import { Transaction, TransactionEvent } from '../Transaction';
9
9
  import { setUpTestSharedTree, setUpTestTree } from './utilities/TestUtilities';
10
+ import { expectDefined } from './utilities/TestCommon';
10
11
  describe('Transaction', () => {
11
12
  function createTestTransaction() {
12
13
  const { tree } = setUpTestSharedTree({ writeFormat: WriteFormat.v0_1_1 });
@@ -16,6 +17,9 @@ describe('Transaction', () => {
16
17
  function createValidChange(testTree) {
17
18
  return Change.delete(StableRange.only(testTree.left));
18
19
  }
20
+ function createValidChanges(testTree) {
21
+ return Change.move(StableRange.only(testTree.left), StablePlace.after(testTree.right));
22
+ }
19
23
  function createInvalidChange(testTree) {
20
24
  return Change.delete(StableRange.only(testTree.generateNodeId()));
21
25
  }
@@ -50,7 +54,7 @@ describe('Transaction', () => {
50
54
  });
51
55
  it('can apply multiple changes at once', () => {
52
56
  const { tree, testTree, transaction } = createTestTransaction();
53
- transaction.apply(Change.move(StableRange.only(testTree.left), StablePlace.after(testTree.right)));
57
+ transaction.apply(createValidChanges(testTree));
54
58
  transaction.closeAndCommit();
55
59
  expect(tree.currentView.getTrait(testTree.left.traitLocation).length).to.equal(0);
56
60
  expect(tree.currentView.getTrait(testTree.right.traitLocation).length).to.equal(2);
@@ -86,5 +90,35 @@ describe('Transaction', () => {
86
90
  transaction.closeAndCommit();
87
91
  expect(transaction.isOpen).to.be.false;
88
92
  });
93
+ it('emits view change events', () => {
94
+ const { testTree, transaction } = createTestTransaction();
95
+ let beforeView;
96
+ let afterView;
97
+ transaction.addListener(TransactionEvent.ViewChange, (before, after) => {
98
+ beforeView = before;
99
+ afterView = after;
100
+ });
101
+ const beforeViewExpected = transaction.currentView;
102
+ transaction.apply(createValidChange(testTree));
103
+ const afterViewExpected = transaction.currentView;
104
+ expect(expectDefined(beforeView).equals(beforeViewExpected)).to.be.true;
105
+ expect(expectDefined(afterView).equals(afterViewExpected)).to.be.true;
106
+ });
107
+ it('emits only one view change event per apply', () => {
108
+ const { testTree, transaction } = createTestTransaction();
109
+ let eventCount = 0;
110
+ transaction.addListener(TransactionEvent.ViewChange, () => {
111
+ eventCount += 1;
112
+ });
113
+ transaction.apply(createValidChanges(testTree));
114
+ expect(eventCount).to.equal(1);
115
+ });
116
+ it('does not emit view change events when there are no changes', () => {
117
+ const { transaction } = createTestTransaction();
118
+ transaction.on(TransactionEvent.ViewChange, () => {
119
+ expect.fail();
120
+ });
121
+ transaction.apply([]);
122
+ });
89
123
  });
90
124
  //# sourceMappingURL=Transaction.tests.js.map