@fluid-experimental/tree 1.2.1 → 2.0.0-internal.1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/.prettierignore +6 -0
  2. package/dist/Checkout.d.ts +9 -4
  3. package/dist/Checkout.d.ts.map +1 -1
  4. package/dist/Checkout.js +34 -25
  5. package/dist/Checkout.js.map +1 -1
  6. package/dist/Common.d.ts +31 -18
  7. package/dist/Common.d.ts.map +1 -1
  8. package/dist/Common.js +32 -22
  9. package/dist/Common.js.map +1 -1
  10. package/dist/EditUtilities.d.ts +5 -0
  11. package/dist/EditUtilities.d.ts.map +1 -1
  12. package/dist/EditUtilities.js +4 -3
  13. package/dist/EditUtilities.js.map +1 -1
  14. package/dist/HistoryEditFactory.d.ts +5 -3
  15. package/dist/HistoryEditFactory.d.ts.map +1 -1
  16. package/dist/HistoryEditFactory.js +18 -3
  17. package/dist/HistoryEditFactory.js.map +1 -1
  18. package/dist/SharedTree.d.ts +6 -3
  19. package/dist/SharedTree.d.ts.map +1 -1
  20. package/dist/SharedTree.js +4 -4
  21. package/dist/SharedTree.js.map +1 -1
  22. package/dist/Transaction.d.ts +2 -2
  23. package/dist/Transaction.d.ts.map +1 -1
  24. package/dist/Transaction.js +3 -2
  25. package/dist/Transaction.js.map +1 -1
  26. package/lib/Checkout.d.ts +9 -4
  27. package/lib/Checkout.d.ts.map +1 -1
  28. package/lib/Checkout.js +36 -27
  29. package/lib/Checkout.js.map +1 -1
  30. package/lib/Common.d.ts +31 -18
  31. package/lib/Common.d.ts.map +1 -1
  32. package/lib/Common.js +30 -21
  33. package/lib/Common.js.map +1 -1
  34. package/lib/EditUtilities.d.ts +5 -0
  35. package/lib/EditUtilities.d.ts.map +1 -1
  36. package/lib/EditUtilities.js +4 -3
  37. package/lib/EditUtilities.js.map +1 -1
  38. package/lib/HistoryEditFactory.d.ts +5 -3
  39. package/lib/HistoryEditFactory.d.ts.map +1 -1
  40. package/lib/HistoryEditFactory.js +18 -3
  41. package/lib/HistoryEditFactory.js.map +1 -1
  42. package/lib/SharedTree.d.ts +6 -3
  43. package/lib/SharedTree.d.ts.map +1 -1
  44. package/lib/SharedTree.js +5 -5
  45. package/lib/SharedTree.js.map +1 -1
  46. package/lib/Transaction.d.ts +2 -2
  47. package/lib/Transaction.d.ts.map +1 -1
  48. package/lib/Transaction.js +3 -2
  49. package/lib/Transaction.js.map +1 -1
  50. package/lib/test/Checkout.tests.d.ts.map +1 -1
  51. package/lib/test/Checkout.tests.js +39 -10
  52. package/lib/test/Checkout.tests.js.map +1 -1
  53. package/lib/test/Common.tests.js +20 -1
  54. package/lib/test/Common.tests.js.map +1 -1
  55. package/lib/test/HistoryEditFactory.tests.js +48 -9
  56. package/lib/test/HistoryEditFactory.tests.js.map +1 -1
  57. package/lib/test/utilities/SharedTreeTests.d.ts.map +1 -1
  58. package/lib/test/utilities/SharedTreeTests.js +35 -26
  59. package/lib/test/utilities/SharedTreeTests.js.map +1 -1
  60. package/lib/test/utilities/TestUtilities.d.ts +5 -0
  61. package/lib/test/utilities/TestUtilities.d.ts.map +1 -1
  62. package/lib/test/utilities/TestUtilities.js +4 -3
  63. package/lib/test/utilities/TestUtilities.js.map +1 -1
  64. package/lib/test/utilities/UndoRedoTests.js +3 -2
  65. package/lib/test/utilities/UndoRedoTests.js.map +1 -1
  66. package/package.json +22 -20
  67. package/src/Checkout.ts +56 -14
  68. package/src/Common.ts +38 -21
  69. package/src/EditUtilities.ts +3 -3
  70. package/src/HistoryEditFactory.ts +24 -3
  71. package/src/SharedTree.ts +19 -8
  72. package/src/Transaction.ts +5 -4
@@ -1 +1 @@
1
- {"version":3,"file":"HistoryEditFactory.tests.js","sourceRoot":"","sources":["../../src/test/HistoryEditFactory.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 { revert } from '../HistoryEditFactory';\nimport { DetachedSequenceId } from '../Identifiers';\nimport { ChangeInternal, DetachInternal, Side, StablePlaceInternal, StableRangeInternal } from '../persisted-types';\nimport { expectDefined } from './utilities/TestCommon';\nimport { refreshTestTree } from './utilities/TestUtilities';\n\ndescribe('revert', () => {\n\tconst testTree = refreshTestTree();\n\n\tit('can revert a single detached node', () => {\n\t\tconst firstDetachedId = 0 as DetachedSequenceId;\n\t\tconst node = testTree.buildLeafInternal();\n\t\tconst firstBuild = ChangeInternal.build([node], firstDetachedId);\n\t\tconst insertedNodeId = 1 as DetachedSequenceId;\n\t\tconst insertedBuild = ChangeInternal.build([firstDetachedId], insertedNodeId);\n\t\tconst insertChange = ChangeInternal.insert(insertedNodeId, {\n\t\t\treferenceTrait: testTree.left.traitLocation,\n\t\t\tside: Side.After,\n\t\t});\n\t\tconst result = expectDefined(revert([firstBuild, insertedBuild, insertChange], testTree.view));\n\t\texpect(result.length).to.equal(1);\n\t\tconst revertedChange = result[0] as DetachInternal;\n\t\texpect(revertedChange.source.start.referenceSibling).to.deep.equal(node.identifier);\n\t\texpect(revertedChange.source.end.referenceSibling).to.deep.equal(node.identifier);\n\t});\n\n\tit('can revert multiple detached nodes', () => {\n\t\tconst firstDetachedId = 0 as DetachedSequenceId;\n\t\tconst firstNode = testTree.buildLeafInternal();\n\t\tconst firstBuild = ChangeInternal.build([firstNode], firstDetachedId);\n\t\tconst secondDetachedId = 1 as DetachedSequenceId;\n\t\tconst secondNode = testTree.buildLeafInternal();\n\t\tconst secondBuild = ChangeInternal.build([secondNode], secondDetachedId);\n\t\tconst insertedNodeId = 2 as DetachedSequenceId;\n\t\tconst insertedBuild = ChangeInternal.build([firstDetachedId, secondDetachedId], insertedNodeId);\n\t\tconst insertChange = ChangeInternal.insert(insertedNodeId, {\n\t\t\treferenceTrait: testTree.left.traitLocation,\n\t\t\tside: Side.After,\n\t\t});\n\t\tconst result = expectDefined(revert([firstBuild, secondBuild, insertedBuild, insertChange], testTree.view));\n\t\texpect(result.length).to.equal(1);\n\t\tconst revertedChange = result[0] as DetachInternal;\n\t\texpect(revertedChange.source.start.referenceSibling).to.deep.equal(firstNode.identifier);\n\t\texpect(revertedChange.source.end.referenceSibling).to.deep.equal(secondNode.identifier);\n\t});\n\n\tdescribe('returns undefined for reverts that require more context than the view directly before the edit', () => {\n\t\tdescribe('because the edit conflicted', () => {\n\t\t\tit('when reverting a detach of a node that is not in the tree', () => {\n\t\t\t\tconst nodeNotInTree = testTree.buildLeafInternal();\n\t\t\t\tconst change = ChangeInternal.detach(StableRangeInternal.only(nodeNotInTree));\n\t\t\t\tconst result = revert([change], testTree.view);\n\t\t\t\texpect(result).to.be.undefined;\n\t\t\t});\n\n\t\t\tit('when reverting a set value of a node that is not in the tree', () => {\n\t\t\t\tconst nodeNotInTree = testTree.buildLeafInternal();\n\t\t\t\tconst change = ChangeInternal.setPayload(nodeNotInTree, '42');\n\t\t\t\tconst result = revert([change], testTree.view);\n\t\t\t\texpect(result).to.be.undefined;\n\t\t\t});\n\t\t});\n\n\t\tdescribe('because the edit was malformed', () => {\n\t\t\tit('when reverting an insert whose source is not insertable', () => {\n\t\t\t\tconst detachedId = 0 as DetachedSequenceId;\n\t\t\t\t// Revert an insert where the source is not a valid detached sequence ID (nothing has been built/detached with that ID)\n\t\t\t\texpect(\n\t\t\t\t\trevert(\n\t\t\t\t\t\t[ChangeInternal.insert(detachedId, StablePlaceInternal.atStartOf(testTree.left.traitLocation))],\n\t\t\t\t\t\ttestTree.view\n\t\t\t\t\t)\n\t\t\t\t).to.be.undefined;\n\t\t\t\t// Revert a duplicate insert (the source has already been inserted by a previous insert in the same edit)\n\t\t\t\texpect(\n\t\t\t\t\trevert(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tChangeInternal.build([testTree.buildLeafInternal()], detachedId),\n\t\t\t\t\t\t\tChangeInternal.insert(\n\t\t\t\t\t\t\t\tdetachedId,\n\t\t\t\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tChangeInternal.insert(\n\t\t\t\t\t\t\t\tdetachedId,\n\t\t\t\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttestTree.view\n\t\t\t\t\t)\n\t\t\t\t).to.be.undefined;\n\t\t\t});\n\n\t\t\tit('when reverting a detach whose destination is already occupied', () => {\n\t\t\t\tconst detachedId = 0 as DetachedSequenceId;\n\t\t\t\t// Revert a detach where the destination is already occupied due to a prior detach\n\t\t\t\texpect(\n\t\t\t\t\trevert(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tChangeInternal.detach(StableRangeInternal.only(testTree.left), detachedId),\n\t\t\t\t\t\t\tChangeInternal.detach(StableRangeInternal.only(testTree.left), detachedId),\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttestTree.view\n\t\t\t\t\t)\n\t\t\t\t).to.be.undefined;\n\t\t\t\t// Revert a detach where the destination is already occupied due to a prior build\n\t\t\t\texpect(\n\t\t\t\t\trevert(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tChangeInternal.build([testTree.buildLeafInternal()], detachedId),\n\t\t\t\t\t\t\tChangeInternal.detach(StableRangeInternal.only(testTree.left), detachedId),\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttestTree.view\n\t\t\t\t\t)\n\t\t\t\t).to.be.undefined;\n\t\t\t});\n\t\t});\n\t});\n});\n"]}
1
+ {"version":3,"file":"HistoryEditFactory.tests.js","sourceRoot":"","sources":["../../src/test/HistoryEditFactory.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 { revert } from '../HistoryEditFactory';\nimport { DetachedSequenceId, TraitLabel } from '../Identifiers';\nimport { ChangeInternal, DetachInternal, Side, StablePlaceInternal, StableRangeInternal } from '../persisted-types';\nimport { expectDefined } from './utilities/TestCommon';\nimport { refreshTestTree } from './utilities/TestUtilities';\n\ndescribe('revert', () => {\n\tconst testTree = refreshTestTree();\n\n\tit('can revert a single detached node', () => {\n\t\tconst firstDetachedId = 0 as DetachedSequenceId;\n\t\tconst node = testTree.buildLeafInternal();\n\t\tconst firstBuild = ChangeInternal.build([node], firstDetachedId);\n\t\tconst insertedNodeId = 1 as DetachedSequenceId;\n\t\tconst insertedBuild = ChangeInternal.build([firstDetachedId], insertedNodeId);\n\t\tconst insertChange = ChangeInternal.insert(\n\t\t\tinsertedNodeId,\n\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t);\n\t\tconst result = expectDefined(revert([firstBuild, insertedBuild, insertChange], testTree.view));\n\t\texpect(result.length).to.equal(1);\n\t\tconst revertedChange = result[0] as DetachInternal;\n\t\texpect(revertedChange.source.start.referenceSibling).to.deep.equal(node.identifier);\n\t\texpect(revertedChange.source.end.referenceSibling).to.deep.equal(node.identifier);\n\t});\n\n\tit('can revert multiple detached nodes', () => {\n\t\tconst firstDetachedId = 0 as DetachedSequenceId;\n\t\tconst firstNode = testTree.buildLeafInternal();\n\t\tconst firstBuild = ChangeInternal.build([firstNode], firstDetachedId);\n\t\tconst secondDetachedId = 1 as DetachedSequenceId;\n\t\tconst secondNode = testTree.buildLeafInternal();\n\t\tconst secondBuild = ChangeInternal.build([secondNode], secondDetachedId);\n\t\tconst insertedNodeId = 2 as DetachedSequenceId;\n\t\tconst insertedBuild = ChangeInternal.build([firstDetachedId, secondDetachedId], insertedNodeId);\n\t\tconst insertChange = ChangeInternal.insert(\n\t\t\tinsertedNodeId,\n\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t);\n\t\tconst result = expectDefined(revert([firstBuild, secondBuild, insertedBuild, insertChange], testTree.view));\n\t\texpect(result.length).to.equal(1);\n\t\tconst revertedChange = result[0] as DetachInternal;\n\t\texpect(revertedChange.source.start.referenceSibling).to.deep.equal(firstNode.identifier);\n\t\texpect(revertedChange.source.end.referenceSibling).to.deep.equal(secondNode.identifier);\n\t});\n\n\tit('handles reverting the insert of empty nodes, with subsequent non-empty nodes', () => {\n\t\t// build and insert of empty traits\n\t\tconst emptyTraitNodeId = 0 as DetachedSequenceId;\n\t\tconst emptyTraitBuild = ChangeInternal.build([], emptyTraitNodeId);\n\t\tconst emptyTraitInsert = ChangeInternal.insert(\n\t\t\temptyTraitNodeId,\n\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t);\n\n\t\t// build and insert of non-empty traits\n\t\tconst firstDetachedId = 1 as DetachedSequenceId;\n\t\tconst firstNode = testTree.buildLeafInternal();\n\t\tconst firstBuild = ChangeInternal.build([firstNode], firstDetachedId);\n\t\tconst insertedNodeId = 3 as DetachedSequenceId;\n\t\tconst insertedBuild = ChangeInternal.build([firstDetachedId], insertedNodeId);\n\t\tconst insertChange = ChangeInternal.insert(\n\t\t\tinsertedNodeId,\n\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t);\n\t\tconst result = expectDefined(\n\t\t\trevert([emptyTraitBuild, emptyTraitInsert, firstBuild, insertedBuild, insertChange], testTree.view)\n\t\t);\n\t\texpect(result.length).to.equal(1);\n\t\tconst revertedChange = result[0] as DetachInternal;\n\t\texpect(revertedChange.source.start.referenceSibling).to.deep.equal(firstNode.identifier);\n\t});\n\n\t/** This is a regression test for a bug where we make sure that any built/detached nodes are cleared when any\n\t * empty insert/detach change is skipped once encountered. The expected outcome is undefined, as during the second\n\t * empty insert (with the same DetachSequenceId), there should be no such node in the builtNodes.\n\t */\n\tit('handles reverting the insert of empty nodes, with subsequent empty nodes of same DetachedSequenceId', () => {\n\t\tconst emptyTraitNodeId = 0 as DetachedSequenceId;\n\t\tconst emptyTraitBuild = ChangeInternal.build([], emptyTraitNodeId);\n\t\tconst emptyTraitInsert = ChangeInternal.insert(\n\t\t\temptyTraitNodeId,\n\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t);\n\t\tconst result = revert([emptyTraitBuild, emptyTraitInsert, emptyTraitInsert], testTree.view);\n\t\texpect(result).to.be.undefined;\n\t});\n\n\tit('handles reverting the detach of an empty trait', () => {\n\t\tconst insertedNodeId = 0 as DetachedSequenceId;\n\t\tconst result = expectDefined(\n\t\t\trevert(\n\t\t\t\t[\n\t\t\t\t\tChangeInternal.detach(\n\t\t\t\t\t\tStableRangeInternal.all({\n\t\t\t\t\t\t\tlabel: 'someNonExistentTraitLabel' as TraitLabel,\n\t\t\t\t\t\t\tparent: testTree.identifier,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tinsertedNodeId\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t\ttestTree.view\n\t\t\t)\n\t\t);\n\t\texpect(result).to.have.lengthOf(0);\n\t});\n\n\tit('handles reverting the insert of an empty trait', () => {\n\t\tconst emptyTraitNodeId = 0 as DetachedSequenceId;\n\t\tconst emptyTraitBuild = ChangeInternal.build([], emptyTraitNodeId);\n\t\tconst emptyTraitInsert = ChangeInternal.insert(\n\t\t\temptyTraitNodeId,\n\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t);\n\t\tconst result = expectDefined(revert([emptyTraitBuild, emptyTraitInsert], testTree.view));\n\t\texpect(result).to.have.lengthOf(0);\n\t});\n\n\tdescribe('returns undefined for reverts that require more context than the view directly before the edit', () => {\n\t\tdescribe('because the edit conflicted', () => {\n\t\t\tit('when reverting a detach of a node that is not in the tree', () => {\n\t\t\t\tconst nodeNotInTree = testTree.buildLeafInternal();\n\t\t\t\tconst change = ChangeInternal.detach(StableRangeInternal.only(nodeNotInTree));\n\t\t\t\tconst result = revert([change], testTree.view);\n\t\t\t\texpect(result).to.be.undefined;\n\t\t\t});\n\n\t\t\tit('when reverting a set value of a node that is not in the tree', () => {\n\t\t\t\tconst nodeNotInTree = testTree.buildLeafInternal();\n\t\t\t\tconst change = ChangeInternal.setPayload(nodeNotInTree, '42');\n\t\t\t\tconst result = revert([change], testTree.view);\n\t\t\t\texpect(result).to.be.undefined;\n\t\t\t});\n\t\t});\n\n\t\tdescribe('because the edit was malformed', () => {\n\t\t\tit('when reverting an insert whose source is not insertable', () => {\n\t\t\t\tconst detachedId = 0 as DetachedSequenceId;\n\t\t\t\t// Revert an insert where the source is not a valid detached sequence ID (nothing has been built/detached with that ID)\n\t\t\t\texpect(\n\t\t\t\t\trevert(\n\t\t\t\t\t\t[ChangeInternal.insert(detachedId, StablePlaceInternal.atStartOf(testTree.left.traitLocation))],\n\t\t\t\t\t\ttestTree.view\n\t\t\t\t\t)\n\t\t\t\t).to.be.undefined;\n\t\t\t\t// Revert a duplicate insert (the source has already been inserted by a previous insert in the same edit)\n\t\t\t\texpect(\n\t\t\t\t\trevert(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tChangeInternal.build([testTree.buildLeafInternal()], detachedId),\n\t\t\t\t\t\t\tChangeInternal.insert(\n\t\t\t\t\t\t\t\tdetachedId,\n\t\t\t\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tChangeInternal.insert(\n\t\t\t\t\t\t\t\tdetachedId,\n\t\t\t\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttestTree.view\n\t\t\t\t\t)\n\t\t\t\t).to.be.undefined;\n\t\t\t});\n\n\t\t\tit('when reverting a detach whose destination is already occupied', () => {\n\t\t\t\tconst detachedId = 0 as DetachedSequenceId;\n\t\t\t\t// Revert a detach where the destination is already occupied due to a prior detach\n\t\t\t\texpect(\n\t\t\t\t\trevert(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tChangeInternal.detach(StableRangeInternal.only(testTree.left), detachedId),\n\t\t\t\t\t\t\tChangeInternal.detach(StableRangeInternal.only(testTree.left), detachedId),\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttestTree.view\n\t\t\t\t\t)\n\t\t\t\t).to.be.undefined;\n\t\t\t\t// Revert a detach where the destination is already occupied due to a prior build\n\t\t\t\texpect(\n\t\t\t\t\trevert(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tChangeInternal.build([testTree.buildLeafInternal()], detachedId),\n\t\t\t\t\t\t\tChangeInternal.detach(StableRangeInternal.only(testTree.left), detachedId),\n\t\t\t\t\t\t],\n\t\t\t\t\t\ttestTree.view\n\t\t\t\t\t)\n\t\t\t\t).to.be.undefined;\n\t\t\t});\n\t\t});\n\t});\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SharedTreeTests.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/SharedTreeTests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuBH,OAAO,EAeN,WAAW,EACX,MAAM,uBAAuB,CAAC;AAa/B,OAAO,EAGN,2BAA2B,EAC3B,wBAAwB,EAcxB,MAAM,iBAAiB,CAAC;AAazB;;;GAGG;AACH,wBAAgB,4BAA4B,CAC3C,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,WAAW,EACxB,qCAAqC,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,2BAA2B,QA0/C1G"}
1
+ {"version":3,"file":"SharedTreeTests.d.ts","sourceRoot":"","sources":["../../../src/test/utilities/SharedTreeTests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuBH,OAAO,EAeN,WAAW,EACX,MAAM,uBAAuB,CAAC;AAa/B,OAAO,EAGN,2BAA2B,EAC3B,wBAAwB,EAcxB,MAAM,iBAAiB,CAAC;AAazB;;;GAGG;AACH,wBAAgB,4BAA4B,CAC3C,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,WAAW,EACxB,qCAAqC,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,2BAA2B,QA8gD1G"}
@@ -685,12 +685,23 @@ export function runSharedTreeOperationsTests(title, writeFormat, setUpTestShared
685
685
  });
686
686
  });
687
687
  describe('telemetry', () => {
688
+ class LoggerThatOnlySeesSharedTreeEvents {
689
+ constructor(additionalFilter = (e) => true) {
690
+ this.additionalFilter = additionalFilter;
691
+ this.events = [];
692
+ }
693
+ send(event) {
694
+ if (isSharedTreeEvent(event) && this.additionalFilter(event)) {
695
+ this.events.push(event);
696
+ }
697
+ }
698
+ }
688
699
  describe('useFailedSequencedEditTelemetry', () => {
689
700
  it('decorates events with the correct properties', async () => {
690
701
  // Test that a handle can wrap a node and retrieve that node's properties
691
- const events = [];
702
+ const logger = new LoggerThatOnlySeesSharedTreeEvents();
692
703
  const { sharedTree, testTree, containerRuntimeFactory } = createSimpleTestTree({
693
- logger: { send: (event) => events.push(event) },
704
+ logger,
694
705
  allowInvalid: true,
695
706
  });
696
707
  useFailedSequencedEditTelemetry(sharedTree);
@@ -699,68 +710,66 @@ export function runSharedTreeOperationsTests(title, writeFormat, setUpTestShared
699
710
  containerRuntimeFactory.processAllMessages();
700
711
  // Force demand, which will cause a telemetry event for the invalid edit to be emitted
701
712
  await sharedTree.logViewer.getRevisionView(Number.POSITIVE_INFINITY);
702
- expect(events.length).is.greaterThan(0);
703
- events.forEach((event) => {
713
+ expect(logger.events.length).is.greaterThan(0);
714
+ logger.events.forEach((event) => {
704
715
  expect(isSharedTreeEvent(event)).is.true;
705
716
  });
706
717
  });
707
718
  it('is logged for invalid locally generated edits when those edits are sequenced', async () => {
708
- const events = [];
719
+ const logger = new LoggerThatOnlySeesSharedTreeEvents((event) => !event.eventName.includes('IdCompressor'));
709
720
  const { sharedTree, testTree, containerRuntimeFactory } = createSimpleTestTree({
710
- logger: { send: (event) => !event.eventName.includes('IdCompressor') && events.push(event) },
721
+ logger,
711
722
  allowInvalid: true,
712
723
  });
713
724
  useFailedSequencedEditTelemetry(sharedTree);
714
725
  // Invalid edit
715
726
  sharedTree.applyEdit(...Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.buildLeaf(testTree.generateNodeId()))));
716
- expect(events.length).equals(0);
727
+ expect(logger.events.length).equals(0);
717
728
  containerRuntimeFactory.processAllMessages();
718
729
  // Force demand, which will cause a telemetry event for the invalid edit to be emitted
719
730
  await sharedTree.logViewer.getRevisionView(Number.POSITIVE_INFINITY);
720
- expect(events.length).equals(1);
721
- expect(events[0].category).equals('generic');
722
- expect(events[0].eventName).equals('SharedTree:SequencedEditApplied:InvalidSharedTreeEdit');
731
+ expect(logger.events.length).equals(1);
732
+ expect(logger.events[0].category).equals('generic');
733
+ expect(logger.events[0].eventName).equals('SharedTree:SequencedEditApplied:InvalidSharedTreeEdit');
723
734
  });
724
735
  it('can be disabled and re-enabled', async () => {
725
- const events = [];
736
+ const logger = new LoggerThatOnlySeesSharedTreeEvents((event) => !event.eventName.includes('IdCompressor'));
726
737
  const { sharedTree, testTree, containerRuntimeFactory } = createSimpleTestTree({
727
- logger: { send: (event) => !event.eventName.includes('IdCompressor') && events.push(event) },
738
+ logger,
728
739
  allowInvalid: true,
729
740
  });
730
741
  const { disable } = useFailedSequencedEditTelemetry(sharedTree);
731
742
  sharedTree.applyEdit(...Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.buildLeaf(testTree.generateNodeId()))));
732
- expect(events.length).equals(0);
743
+ expect(logger.events.length).equals(0);
733
744
  containerRuntimeFactory.processAllMessages();
734
745
  await sharedTree.logViewer.getRevisionView(Number.POSITIVE_INFINITY);
735
- expect(events.length).equals(1);
736
- expect(events[0].eventName).equals('SharedTree:SequencedEditApplied:InvalidSharedTreeEdit');
746
+ expect(logger.events.length).equals(1);
747
+ expect(logger.events[0].eventName).equals('SharedTree:SequencedEditApplied:InvalidSharedTreeEdit');
737
748
  disable();
738
749
  sharedTree.applyEdit(...Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.buildLeaf(testTree.generateNodeId()))));
739
750
  containerRuntimeFactory.processAllMessages();
740
751
  await sharedTree.logViewer.getRevisionView(Number.POSITIVE_INFINITY);
741
- expect(events.length).equals(1);
752
+ expect(logger.events.length).equals(1);
742
753
  useFailedSequencedEditTelemetry(sharedTree);
743
754
  sharedTree.applyEdit(...Change.insertTree([testTree.buildLeaf()], StablePlace.after(testTree.buildLeaf(testTree.generateNodeId()))));
744
755
  containerRuntimeFactory.processAllMessages();
745
756
  await sharedTree.logViewer.getRevisionView(Number.POSITIVE_INFINITY);
746
- expect(events.length).equals(2);
747
- expect(events[1].eventName).equals('SharedTree:SequencedEditApplied:InvalidSharedTreeEdit');
757
+ expect(logger.events.length).equals(2);
758
+ expect(logger.events[1].eventName).equals('SharedTree:SequencedEditApplied:InvalidSharedTreeEdit');
748
759
  });
749
760
  it('is not logged for valid edits', async () => {
750
- const events = [];
751
- const { sharedTree, testTree, containerRuntimeFactory } = createSimpleTestTree({
752
- logger: { send: (event) => !event.eventName.includes('IdCompressor') && events.push(event) },
753
- });
761
+ const logger = new LoggerThatOnlySeesSharedTreeEvents((event) => !event.eventName.includes('IdCompressor'));
762
+ const { sharedTree, testTree, containerRuntimeFactory } = createSimpleTestTree({ logger });
754
763
  useFailedSequencedEditTelemetry(sharedTree);
755
764
  sharedTree.applyEdit(...Change.insertTree(testTree.buildLeaf(), StablePlace.after(testTree.left)));
756
765
  containerRuntimeFactory.processAllMessages();
757
766
  await sharedTree.logViewer.getRevisionView(Number.POSITIVE_INFINITY);
758
- expect(events.length).equals(0);
767
+ expect(logger.events.length).equals(0);
759
768
  });
760
769
  it('is not logged for remote edits', async () => {
761
- const events = [];
770
+ const logger = new LoggerThatOnlySeesSharedTreeEvents((event) => !event.eventName.includes('IdCompressor'));
762
771
  const { sharedTree: sharedTree1, containerRuntimeFactory } = createSimpleTestTree({
763
- logger: { send: (event) => !event.eventName.includes('IdCompressor') && events.push(event) },
772
+ logger,
764
773
  allowInvalid: true,
765
774
  localMode: false,
766
775
  });
@@ -773,7 +782,7 @@ export function runSharedTreeOperationsTests(title, writeFormat, setUpTestShared
773
782
  sharedTree2.applyEdit(...Change.insertTree([testTree2.buildLeaf()], StablePlace.after(testTree2.buildLeaf(testTree2.generateNodeId()))));
774
783
  containerRuntimeFactory.processAllMessages();
775
784
  await sharedTree1.logViewer.getRevisionView(Number.POSITIVE_INFINITY);
776
- expect(events.length).equals(0);
785
+ expect(logger.events.length).equals(0);
777
786
  });
778
787
  });
779
788
  });