@fluid-experimental/tree 0.59.2001 → 0.59.3000

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 (258) hide show
  1. package/.eslintrc.js +2 -0
  2. package/.vscode/SharedTree.code-workspace +15 -0
  3. package/.vscode/settings.json +6 -0
  4. package/dist/ChangeCompression.js +9 -9
  5. package/dist/ChangeCompression.js.map +1 -1
  6. package/dist/ChangeTypes.d.ts +1 -6
  7. package/dist/ChangeTypes.d.ts.map +1 -1
  8. package/dist/ChangeTypes.js +5 -5
  9. package/dist/ChangeTypes.js.map +1 -1
  10. package/dist/Checkout.js +14 -14
  11. package/dist/Checkout.js.map +1 -1
  12. package/dist/Common.d.ts +21 -3
  13. package/dist/Common.d.ts.map +1 -1
  14. package/dist/Common.js +29 -4
  15. package/dist/Common.js.map +1 -1
  16. package/dist/EditLog.js +26 -25
  17. package/dist/EditLog.js.map +1 -1
  18. package/dist/EditUtilities.js +17 -17
  19. package/dist/EditUtilities.js.map +1 -1
  20. package/dist/Forest.js +31 -31
  21. package/dist/Forest.js.map +1 -1
  22. package/dist/HistoryEditFactory.js +9 -9
  23. package/dist/HistoryEditFactory.js.map +1 -1
  24. package/dist/IdConversion.js +9 -9
  25. package/dist/IdConversion.js.map +1 -1
  26. package/dist/Identifiers.d.ts +4 -0
  27. package/dist/Identifiers.d.ts.map +1 -1
  28. package/dist/Identifiers.js.map +1 -1
  29. package/dist/LogViewer.d.ts +1 -5
  30. package/dist/LogViewer.d.ts.map +1 -1
  31. package/dist/LogViewer.js +11 -19
  32. package/dist/LogViewer.js.map +1 -1
  33. package/dist/MergeHealth.js +2 -2
  34. package/dist/MergeHealth.js.map +1 -1
  35. package/dist/NodeIdUtilities.js +2 -2
  36. package/dist/NodeIdUtilities.js.map +1 -1
  37. package/dist/PayloadUtilities.js +1 -1
  38. package/dist/PayloadUtilities.js.map +1 -1
  39. package/dist/RevisionValueCache.d.ts +13 -10
  40. package/dist/RevisionValueCache.d.ts.map +1 -1
  41. package/dist/RevisionValueCache.js +14 -11
  42. package/dist/RevisionValueCache.js.map +1 -1
  43. package/dist/RevisionView.js +4 -4
  44. package/dist/RevisionView.js.map +1 -1
  45. package/dist/SerializationUtilities.js +4 -4
  46. package/dist/SerializationUtilities.js.map +1 -1
  47. package/dist/SharedTree.d.ts +93 -31
  48. package/dist/SharedTree.d.ts.map +1 -1
  49. package/dist/SharedTree.js +160 -131
  50. package/dist/SharedTree.js.map +1 -1
  51. package/dist/SharedTreeEncoder.d.ts +3 -3
  52. package/dist/SharedTreeEncoder.d.ts.map +1 -1
  53. package/dist/SharedTreeEncoder.js +36 -36
  54. package/dist/SharedTreeEncoder.js.map +1 -1
  55. package/dist/StringInterner.js +1 -1
  56. package/dist/StringInterner.js.map +1 -1
  57. package/dist/Summary.js +1 -1
  58. package/dist/Summary.js.map +1 -1
  59. package/dist/SummaryBackCompatibility.js +8 -8
  60. package/dist/SummaryBackCompatibility.js.map +1 -1
  61. package/dist/Transaction.js +1 -1
  62. package/dist/Transaction.js.map +1 -1
  63. package/dist/TransactionInternal.js +17 -17
  64. package/dist/TransactionInternal.js.map +1 -1
  65. package/dist/TreeCompressor.d.ts.map +1 -1
  66. package/dist/TreeCompressor.js +6 -8
  67. package/dist/TreeCompressor.js.map +1 -1
  68. package/dist/TreeNodeHandle.js +4 -4
  69. package/dist/TreeNodeHandle.js.map +1 -1
  70. package/dist/TreeView.js +7 -7
  71. package/dist/TreeView.js.map +1 -1
  72. package/dist/TreeViewUtilities.js +2 -2
  73. package/dist/TreeViewUtilities.js.map +1 -1
  74. package/dist/UndoRedoHandler.js +1 -1
  75. package/dist/UndoRedoHandler.js.map +1 -1
  76. package/dist/UuidUtilities.d.ts +30 -0
  77. package/dist/UuidUtilities.d.ts.map +1 -0
  78. package/dist/UuidUtilities.js +106 -0
  79. package/dist/UuidUtilities.js.map +1 -0
  80. package/dist/id-compressor/AppendOnlySortedMap.d.ts +52 -28
  81. package/dist/id-compressor/AppendOnlySortedMap.d.ts.map +1 -1
  82. package/dist/id-compressor/AppendOnlySortedMap.js +167 -90
  83. package/dist/id-compressor/AppendOnlySortedMap.js.map +1 -1
  84. package/dist/id-compressor/IdCompressor.d.ts +43 -42
  85. package/dist/id-compressor/IdCompressor.d.ts.map +1 -1
  86. package/dist/id-compressor/IdCompressor.js +179 -177
  87. package/dist/id-compressor/IdCompressor.js.map +1 -1
  88. package/dist/id-compressor/IdRange.js +1 -1
  89. package/dist/id-compressor/IdRange.js.map +1 -1
  90. package/dist/id-compressor/NumericUuid.d.ts +6 -14
  91. package/dist/id-compressor/NumericUuid.d.ts.map +1 -1
  92. package/dist/id-compressor/NumericUuid.js +15 -76
  93. package/dist/id-compressor/NumericUuid.js.map +1 -1
  94. package/dist/id-compressor/SessionIdNormalizer.d.ts +122 -0
  95. package/dist/id-compressor/SessionIdNormalizer.d.ts.map +1 -0
  96. package/dist/id-compressor/SessionIdNormalizer.js +418 -0
  97. package/dist/id-compressor/SessionIdNormalizer.js.map +1 -0
  98. package/dist/id-compressor/persisted-types/0.0.1.d.ts +6 -13
  99. package/dist/id-compressor/persisted-types/0.0.1.d.ts.map +1 -1
  100. package/dist/id-compressor/persisted-types/0.0.1.js.map +1 -1
  101. package/dist/index.d.ts +2 -2
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js.map +1 -1
  104. package/dist/persisted-types/0.1.1.d.ts +1 -6
  105. package/dist/persisted-types/0.1.1.d.ts.map +1 -1
  106. package/dist/persisted-types/0.1.1.js +3 -3
  107. package/dist/persisted-types/0.1.1.js.map +1 -1
  108. package/lib/ChangeTypes.d.ts +1 -6
  109. package/lib/ChangeTypes.d.ts.map +1 -1
  110. package/lib/Checkout.js.map +1 -1
  111. package/lib/Common.d.ts +21 -3
  112. package/lib/Common.d.ts.map +1 -1
  113. package/lib/Common.js +25 -3
  114. package/lib/Common.js.map +1 -1
  115. package/lib/EditLog.js +2 -1
  116. package/lib/EditLog.js.map +1 -1
  117. package/lib/EditUtilities.js.map +1 -1
  118. package/lib/Forest.js.map +1 -1
  119. package/lib/HistoryEditFactory.js.map +1 -1
  120. package/lib/Identifiers.d.ts +4 -0
  121. package/lib/Identifiers.d.ts.map +1 -1
  122. package/lib/Identifiers.js.map +1 -1
  123. package/lib/LogViewer.d.ts +1 -5
  124. package/lib/LogViewer.d.ts.map +1 -1
  125. package/lib/LogViewer.js +5 -13
  126. package/lib/LogViewer.js.map +1 -1
  127. package/lib/MergeHealth.js.map +1 -1
  128. package/lib/NodeIdUtilities.js.map +1 -1
  129. package/lib/RevisionValueCache.d.ts +13 -10
  130. package/lib/RevisionValueCache.d.ts.map +1 -1
  131. package/lib/RevisionValueCache.js +10 -7
  132. package/lib/RevisionValueCache.js.map +1 -1
  133. package/lib/RevisionView.js.map +1 -1
  134. package/lib/SharedTree.d.ts +93 -31
  135. package/lib/SharedTree.d.ts.map +1 -1
  136. package/lib/SharedTree.js +107 -78
  137. package/lib/SharedTree.js.map +1 -1
  138. package/lib/SharedTreeEncoder.d.ts +3 -3
  139. package/lib/SharedTreeEncoder.d.ts.map +1 -1
  140. package/lib/SharedTreeEncoder.js +4 -4
  141. package/lib/SharedTreeEncoder.js.map +1 -1
  142. package/lib/StringInterner.js.map +1 -1
  143. package/lib/Summary.js.map +1 -1
  144. package/lib/TreeCompressor.d.ts.map +1 -1
  145. package/lib/TreeCompressor.js +1 -3
  146. package/lib/TreeCompressor.js.map +1 -1
  147. package/lib/TreeNodeHandle.js.map +1 -1
  148. package/lib/TreeView.js.map +1 -1
  149. package/lib/TreeViewUtilities.js.map +1 -1
  150. package/lib/UuidUtilities.d.ts +30 -0
  151. package/lib/UuidUtilities.d.ts.map +1 -0
  152. package/lib/UuidUtilities.js +98 -0
  153. package/lib/UuidUtilities.js.map +1 -0
  154. package/lib/id-compressor/AppendOnlySortedMap.d.ts +52 -28
  155. package/lib/id-compressor/AppendOnlySortedMap.d.ts.map +1 -1
  156. package/lib/id-compressor/AppendOnlySortedMap.js +165 -88
  157. package/lib/id-compressor/AppendOnlySortedMap.js.map +1 -1
  158. package/lib/id-compressor/IdCompressor.d.ts +43 -42
  159. package/lib/id-compressor/IdCompressor.d.ts.map +1 -1
  160. package/lib/id-compressor/IdCompressor.js +97 -95
  161. package/lib/id-compressor/IdCompressor.js.map +1 -1
  162. package/lib/id-compressor/NumericUuid.d.ts +6 -14
  163. package/lib/id-compressor/NumericUuid.d.ts.map +1 -1
  164. package/lib/id-compressor/NumericUuid.js +11 -70
  165. package/lib/id-compressor/NumericUuid.js.map +1 -1
  166. package/lib/id-compressor/SessionIdNormalizer.d.ts +122 -0
  167. package/lib/id-compressor/SessionIdNormalizer.d.ts.map +1 -0
  168. package/lib/id-compressor/SessionIdNormalizer.js +414 -0
  169. package/lib/id-compressor/SessionIdNormalizer.js.map +1 -0
  170. package/lib/id-compressor/persisted-types/0.0.1.d.ts +6 -13
  171. package/lib/id-compressor/persisted-types/0.0.1.d.ts.map +1 -1
  172. package/lib/id-compressor/persisted-types/0.0.1.js.map +1 -1
  173. package/lib/index.d.ts +2 -2
  174. package/lib/index.d.ts.map +1 -1
  175. package/lib/index.js.map +1 -1
  176. package/lib/persisted-types/0.1.1.d.ts +1 -6
  177. package/lib/persisted-types/0.1.1.d.ts.map +1 -1
  178. package/lib/persisted-types/0.1.1.js.map +1 -1
  179. package/lib/test/AppendOnlySortedMap.perf.tests.d.ts +6 -0
  180. package/lib/test/AppendOnlySortedMap.perf.tests.d.ts.map +1 -0
  181. package/lib/test/AppendOnlySortedMap.perf.tests.js +49 -0
  182. package/lib/test/AppendOnlySortedMap.perf.tests.js.map +1 -0
  183. package/lib/test/AppendOnlySortedMap.tests.js +56 -14
  184. package/lib/test/AppendOnlySortedMap.tests.js.map +1 -1
  185. package/lib/test/Checkout.tests.js +2 -2
  186. package/lib/test/Checkout.tests.js.map +1 -1
  187. package/lib/test/Forest.tests.js.map +1 -1
  188. package/lib/test/IdCompressor.perf.tests.js +8 -2
  189. package/lib/test/IdCompressor.perf.tests.js.map +1 -1
  190. package/lib/test/IdCompressor.tests.js +75 -24
  191. package/lib/test/IdCompressor.tests.js.map +1 -1
  192. package/lib/test/LogViewer.tests.js +3 -5
  193. package/lib/test/LogViewer.tests.js.map +1 -1
  194. package/lib/test/NumericUuid.perf.tests.js +4 -4
  195. package/lib/test/NumericUuid.perf.tests.js.map +1 -1
  196. package/lib/test/NumericUuid.tests.js +5 -4
  197. package/lib/test/NumericUuid.tests.js.map +1 -1
  198. package/lib/test/RevisionValueCache.tests.js.map +1 -1
  199. package/lib/test/RevisionView.tests.js.map +1 -1
  200. package/lib/test/SessionIdNormalizer.tests.d.ts +6 -0
  201. package/lib/test/SessionIdNormalizer.tests.d.ts.map +1 -0
  202. package/lib/test/SessionIdNormalizer.tests.js +299 -0
  203. package/lib/test/SessionIdNormalizer.tests.js.map +1 -0
  204. package/lib/test/Summary.tests.js +1 -1
  205. package/lib/test/Summary.tests.js.map +1 -1
  206. package/lib/test/TreeCompression.tests.js +1 -1
  207. package/lib/test/TreeCompression.tests.js.map +1 -1
  208. package/lib/test/Virtualization.tests.js +1 -1
  209. package/lib/test/Virtualization.tests.js.map +1 -1
  210. package/lib/test/fuzz/Generators.d.ts +3 -14
  211. package/lib/test/fuzz/Generators.d.ts.map +1 -1
  212. package/lib/test/fuzz/Generators.js +60 -151
  213. package/lib/test/fuzz/Generators.js.map +1 -1
  214. package/lib/test/fuzz/SharedTreeFuzzTests.d.ts +10 -7
  215. package/lib/test/fuzz/SharedTreeFuzzTests.d.ts.map +1 -1
  216. package/lib/test/fuzz/SharedTreeFuzzTests.js +94 -104
  217. package/lib/test/fuzz/SharedTreeFuzzTests.js.map +1 -1
  218. package/lib/test/fuzz/Types.d.ts +2 -9
  219. package/lib/test/fuzz/Types.d.ts.map +1 -1
  220. package/lib/test/fuzz/Types.js +1 -1
  221. package/lib/test/fuzz/Types.js.map +1 -1
  222. package/lib/test/utilities/IdCompressorTestUtilities.d.ts +57 -11
  223. package/lib/test/utilities/IdCompressorTestUtilities.d.ts.map +1 -1
  224. package/lib/test/utilities/IdCompressorTestUtilities.js +112 -98
  225. package/lib/test/utilities/IdCompressorTestUtilities.js.map +1 -1
  226. package/lib/test/utilities/PendingLocalStateTests.d.ts.map +1 -1
  227. package/lib/test/utilities/PendingLocalStateTests.js +2 -1
  228. package/lib/test/utilities/PendingLocalStateTests.js.map +1 -1
  229. package/lib/test/utilities/SharedTreeTests.d.ts.map +1 -1
  230. package/lib/test/utilities/SharedTreeTests.js +30 -1
  231. package/lib/test/utilities/SharedTreeTests.js.map +1 -1
  232. package/lib/test/utilities/SharedTreeVersioningTests.d.ts.map +1 -1
  233. package/lib/test/utilities/SharedTreeVersioningTests.js +20 -0
  234. package/lib/test/utilities/SharedTreeVersioningTests.js.map +1 -1
  235. package/lib/test/utilities/SummaryLoadPerfTests.d.ts.map +1 -1
  236. package/lib/test/utilities/SummaryLoadPerfTests.js +6 -3
  237. package/lib/test/utilities/SummaryLoadPerfTests.js.map +1 -1
  238. package/lib/test/utilities/TestNode.js.map +1 -1
  239. package/lib/test/utilities/TestUtilities.d.ts +9 -1
  240. package/lib/test/utilities/TestUtilities.d.ts.map +1 -1
  241. package/lib/test/utilities/TestUtilities.js +27 -13
  242. package/lib/test/utilities/TestUtilities.js.map +1 -1
  243. package/package.json +19 -17
  244. package/src/Common.ts +42 -4
  245. package/src/EditLog.ts +1 -1
  246. package/src/Identifiers.ts +5 -0
  247. package/src/LogViewer.ts +4 -20
  248. package/src/RevisionValueCache.ts +11 -8
  249. package/src/SharedTree.ts +222 -75
  250. package/src/SharedTreeEncoder.ts +17 -11
  251. package/src/TreeCompressor.ts +2 -4
  252. package/src/UuidUtilities.ts +123 -0
  253. package/src/id-compressor/AppendOnlySortedMap.ts +183 -94
  254. package/src/id-compressor/IdCompressor.ts +144 -132
  255. package/src/id-compressor/NumericUuid.ts +11 -80
  256. package/src/id-compressor/SessionIdNormalizer.ts +497 -0
  257. package/src/id-compressor/persisted-types/0.0.1.ts +12 -15
  258. package/src/index.ts +5 -0
@@ -1 +1 @@
1
- {"version":3,"file":"TestUtilities.js","sourceRoot":"","sources":["../../../src/test/utilities/TestUtilities.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 { resolve } from 'path';\nimport { v5 as uuidv5 } from 'uuid';\nimport { expect } from 'chai';\nimport { SummaryCollection } from '@fluidframework/container-runtime';\nimport { Container, Loader, waitContainerToCatchUp } from '@fluidframework/container-loader';\nimport { requestFluidObject } from '@fluidframework/runtime-utils';\nimport {\n\tMockContainerRuntimeFactory,\n\tMockFluidDataStoreRuntime,\n\tMockStorage,\n} from '@fluidframework/test-runtime-utils';\nimport {\n\tChannelFactoryRegistry,\n\tITestFluidObject,\n\tTestObjectProvider,\n\tTestContainerRuntimeFactory,\n\tTestFluidObjectFactory,\n\tcreateAndAttachContainer,\n} from '@fluidframework/test-utils';\nimport { LocalServerTestDriver } from '@fluidframework/test-drivers';\nimport { ITelemetryBaseLogger } from '@fluidframework/common-definitions';\nimport { TelemetryNullLogger } from '@fluidframework/common-utils';\nimport type { IContainer, IHostLoader } from '@fluidframework/container-definitions';\nimport type { IFluidCodeDetails, IFluidHandle, IRequestHeader } from '@fluidframework/core-interfaces';\nimport { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';\nimport { IContainerRuntimeBase } from '@fluidframework/runtime-definitions';\nimport { IRequest } from '@fluidframework/core-interfaces';\nimport { DetachedSequenceId, EditId, NodeId, OpSpaceNodeId, SessionId, StableNodeId } from '../../Identifiers';\nimport { assert, fail, identity, ReplaceRecursive } from '../../Common';\nimport { IdCompressor } from '../../id-compressor';\nimport { createSessionId } from '../../id-compressor/NumericUuid';\nimport { getChangeNodeFromViewNode } from '../../SerializationUtilities';\nimport { initialTree } from '../../InitialTree';\nimport {\n\tChangeInternal,\n\tEdit,\n\tNodeData,\n\tPayload,\n\treservedIdCount,\n\tSharedTreeOp,\n\tSharedTreeOp_0_0_2,\n\tWriteFormat,\n} from '../../persisted-types';\nimport { TraitLocation, TreeView } from '../../TreeView';\nimport { SharedTreeDiagnosticEvent } from '../../EventTypes';\nimport { getNodeId, getNodeIdContext, NodeIdContext, NodeIdConverter, NodeIdNormalizer } from '../../NodeIdUtilities';\nimport { newEdit, setTrait } from '../../EditUtilities';\nimport { SharedTree } from '../../SharedTree';\nimport { BuildNode, Change, StablePlace } from '../../ChangeTypes';\nimport { convertEditIds } from '../../IdConversion';\nimport { OrderedEditSet } from '../../EditLog';\nimport { buildLeaf, RefreshingTestTree, SimpleTestTree, TestTree } from './TestNode';\n\n/** Objects returned by setUpTestSharedTree */\nexport interface SharedTreeTestingComponents {\n\t/** The MockFluidDataStoreRuntime used to created the SharedTree. */\n\tcomponentRuntime: MockFluidDataStoreRuntime;\n\t/**\n\t * The MockContainerRuntimeFactory created if one was not provided in the options.\n\t * Only connected to the SharedTree if the localMode option was set to false.\n\t * */\n\tcontainerRuntimeFactory: MockContainerRuntimeFactory;\n\t/** The SharedTree created and set up. */\n\ttree: SharedTree;\n}\n\n/** Options used to customize setUpTestSharedTree */\nexport interface SharedTreeTestingOptions {\n\t/**\n\t * Id for the SharedTree to be created.\n\t * If two SharedTrees have the same id and the same containerRuntimeFactory,\n\t * they will collaborate (send edits to each other)\n\t */\n\tid?: string;\n\t/** Node to initialize the SharedTree with. */\n\tinitialTree?: BuildNode;\n\t/** If false, a MockContainerRuntimeFactory connected to the SharedTree will be returned. */\n\tlocalMode?: boolean;\n\t/**\n\t * MockContainerRuntimeFactory to connect the SharedTree to. A new one will not be created if one is provided.\n\t * If localMode is set to true, it will not be connected to the created SharedTree.\n\t * */\n\tcontainerRuntimeFactory?: MockContainerRuntimeFactory;\n\t/** Iff true, do not `fail` on invalid edits */\n\tallowInvalid?: boolean;\n\t/** Iff true, do not `fail` on malformed edits */\n\tallowMalformed?: boolean;\n\t/** Unless set to true, a SharedTree error causes the test to fail */\n\tnoFailOnError?: boolean;\n\t/**\n\t * If not set, full history will be preserved.\n\t */\n\tsummarizeHistory?: boolean;\n\t/**\n\t * If not set, summaries will be written in format 0.1.1.\n\t */\n\twriteFormat?: WriteFormat;\n\t/**\n\t * If set, uses the given id as the edit id for tree setup. Only has an effect if initialTree is also set.\n\t */\n\tsetupEditId?: EditId;\n\n\t/**\n\t * Telemetry logger injected into the SharedTree.\n\t */\n\tlogger?: ITelemetryBaseLogger;\n}\n\nexport const testTraitLabel = SimpleTestTree.traitLabel;\nexport function testTrait(view: TreeView): TraitLocation {\n\treturn {\n\t\tlabel: testTraitLabel,\n\t\tparent: view.root,\n\t};\n}\n\n/** Sets up and returns an object of components useful for testing SharedTree. */\nexport function setUpTestSharedTree(\n\toptions: SharedTreeTestingOptions = { localMode: true }\n): SharedTreeTestingComponents {\n\tconst { id, initialTree, localMode, containerRuntimeFactory, setupEditId, summarizeHistory, writeFormat } = options;\n\tlet componentRuntime: MockFluidDataStoreRuntime;\n\tif (options.logger) {\n\t\tconst proxyHandler: ProxyHandler<MockFluidDataStoreRuntime> = {\n\t\t\tget: (target, prop, receiver) => {\n\t\t\t\tif (prop === 'logger' && options.logger) {\n\t\t\t\t\treturn options.logger;\n\t\t\t\t}\n\t\t\t\treturn target[prop as keyof MockFluidDataStoreRuntime];\n\t\t\t},\n\t\t};\n\t\tcomponentRuntime = new Proxy(new MockFluidDataStoreRuntime(), proxyHandler);\n\t} else {\n\t\tcomponentRuntime = new MockFluidDataStoreRuntime();\n\t}\n\n\t// Enable expensiveValidation\n\tconst factory = SharedTree.getFactory(\n\t\twriteFormat ?? WriteFormat.v0_1_1,\n\t\tsummarizeHistory === undefined || summarizeHistory === true ? { uploadEditChunks: true } : false\n\t);\n\tconst tree = factory.create(componentRuntime, id === undefined ? 'testSharedTree' : id, true);\n\n\tif (options.allowInvalid === undefined || !options.allowInvalid) {\n\t\ttree.on(SharedTreeDiagnosticEvent.DroppedInvalidEdit, () => fail('unexpected invalid edit'));\n\t}\n\n\tif (options.allowMalformed === undefined || !options.allowMalformed) {\n\t\ttree.on(SharedTreeDiagnosticEvent.DroppedMalformedEdit, () => fail('unexpected malformed edit'));\n\t}\n\n\tif (options.noFailOnError === undefined || !options.noFailOnError) {\n\t\t// any errors thrown by a SharedObject event listener will be caught and\n\t\t// reemitted on this event. For testing purposes, rethrow so that it\n\t\t// actually causes the test to fail.\n\t\ttree.on('error', (error) => {\n\t\t\tthrow error;\n\t\t});\n\t}\n\n\tconst newContainerRuntimeFactory = containerRuntimeFactory || new MockContainerRuntimeFactory();\n\n\tif (localMode === true) {\n\t\tcomponentRuntime.local = true;\n\t} else {\n\t\tconst containerRuntime = newContainerRuntimeFactory.createContainerRuntime(componentRuntime);\n\t\tconst services = {\n\t\t\tdeltaConnection: containerRuntime.createDeltaConnection(),\n\t\t\tobjectStorage: new MockStorage(undefined),\n\t\t};\n\t\ttree.connect(services);\n\t}\n\n\tif (initialTree !== undefined) {\n\t\tsetTestTree(tree, initialTree, setupEditId);\n\t}\n\n\treturn {\n\t\tcomponentRuntime,\n\t\tcontainerRuntimeFactory: newContainerRuntimeFactory,\n\t\ttree,\n\t};\n}\n\nconst TestDataStoreType = '@fluid-example/test-dataStore';\n\n/** Objects returned by setUpLocalServerTestSharedTree */\nexport interface LocalServerSharedTreeTestingComponents {\n\t/** The testObjectProvider created if one was not set in the options. */\n\ttestObjectProvider: TestObjectProvider;\n\t/** The SharedTree created and set up. */\n\ttree: SharedTree;\n\t/** The container created and set up. */\n\tcontainer: Container;\n\t/** Handles to any blobs uploaded via `blobs` */\n\tuploadedBlobs: IFluidHandle<ArrayBufferLike>[];\n}\n\n/** Options used to customize setUpLocalServerTestSharedTree */\nexport interface LocalServerSharedTreeTestingOptions {\n\t/** Contents of blobs that should be uploaded to the runtime upon creation. Handles to these blobs will be returned. */\n\tblobs?: ArrayBufferLike[];\n\t/** Headers to include on the container load request. */\n\theaders?: IRequestHeader;\n\t/**\n\t * Id for the SharedTree to be created.\n\t * If two SharedTrees have the same id and the same testObjectProvider,\n\t * they will collaborate (send edits to each other)\n\t */\n\tid?: string;\n\t/** Node to initialize the SharedTree with. */\n\tinitialTree?: BuildNode;\n\t/** If set, uses the provider to create the container and create the SharedTree. */\n\ttestObjectProvider?: TestObjectProvider;\n\t/**\n\t * If not set, full history will be preserved.\n\t */\n\tsummarizeHistory?: boolean;\n\t/**\n\t * If not set, summaries will be written in format 0.0.2.\n\t */\n\twriteFormat?: WriteFormat;\n\t/**\n\t * If not set, will upload edit chunks when they are full.\n\t */\n\tuploadEditChunks?: boolean;\n\t/**\n\t * If set, uses the given id as the edit id for tree setup. Only has an effect if initialTree is also set.\n\t */\n\tsetupEditId?: EditId;\n}\n\nconst testObjectProviders: TestObjectProvider[] = [];\nafterEach(() => {\n\tfor (const provider of testObjectProviders) {\n\t\tprovider.reset();\n\t}\n\ttestObjectProviders.length = 0;\n});\n\n/**\n * Sets up and returns an object of components useful for testing SharedTree with a local server.\n * Required for tests that involve the uploadBlob API.\n *\n * Any TestObjectProvider created by this function will be reset after the test completes (via afterEach) hook.\n */\nexport async function setUpLocalServerTestSharedTree(\n\toptions: LocalServerSharedTreeTestingOptions\n): Promise<LocalServerSharedTreeTestingComponents> {\n\tconst {\n\t\tblobs,\n\t\theaders,\n\t\tid,\n\t\tinitialTree,\n\t\ttestObjectProvider,\n\t\tsetupEditId,\n\t\tsummarizeHistory,\n\t\twriteFormat,\n\t\tuploadEditChunks,\n\t} = options;\n\n\tconst treeId = id ?? 'test';\n\tconst registry: ChannelFactoryRegistry = [\n\t\t[\n\t\t\ttreeId,\n\t\t\tSharedTree.getFactory(\n\t\t\t\twriteFormat ?? WriteFormat.v0_1_1,\n\t\t\t\tsummarizeHistory === undefined || summarizeHistory === true\n\t\t\t\t\t? { uploadEditChunks: uploadEditChunks ?? true }\n\t\t\t\t\t: false\n\t\t\t),\n\t\t],\n\t];\n\tconst innerRequestHandler = async (request: IRequest, runtime: IContainerRuntimeBase) =>\n\t\truntime.IFluidHandleContext.resolveHandle(request);\n\n\tconst runtimeFactory = () =>\n\t\tnew TestContainerRuntimeFactory(\n\t\t\tTestDataStoreType,\n\t\t\tnew TestFluidObjectFactory(registry),\n\t\t\t{\n\t\t\t\tsummaryOptions: {\n\t\t\t\t\tsummaryConfigOverrides: {\n\t\t\t\t\t\tidleTime: 1000, // Current default idleTime is 15000 which will cause some SharedTree tests to timeout.\n\t\t\t\t\t},\n\t\t\t\t\tinitialSummarizerDelayMs: 0,\n\t\t\t\t},\n\t\t\t},\n\t\t\t[innerRequestHandler]\n\t\t);\n\n\tconst defaultCodeDetails: IFluidCodeDetails = {\n\t\tpackage: 'defaultTestPackage',\n\t\tconfig: {},\n\t};\n\n\tfunction makeTestLoader(provider: TestObjectProvider): IHostLoader {\n\t\tconst fluidEntryPoint = runtimeFactory();\n\t\treturn provider.createLoader([[defaultCodeDetails, fluidEntryPoint]], {\n\t\t\toptions: { maxClientLeaveWaitTime: 1000 },\n\t\t});\n\t}\n\n\tlet provider: TestObjectProvider;\n\tlet container: Container;\n\n\tif (testObjectProvider !== undefined) {\n\t\tprovider = testObjectProvider;\n\t\tconst driver = new LocalServerTestDriver();\n\t\tconst loader = makeTestLoader(provider);\n\t\t// Once ILoaderOptions is specificable, this should use `provider.loadTestContainer` instead.\n\t\tcontainer = (await loader.resolve({ url: await driver.createContainerUrl(treeId), headers })) as Container;\n\t\tawait waitContainerToCatchUp(container);\n\t} else {\n\t\tconst driver = new LocalServerTestDriver();\n\t\tprovider = new TestObjectProvider(Loader, driver, runtimeFactory);\n\t\ttestObjectProviders.push(provider);\n\t\t// Once ILoaderOptions is specificable, this should use `provider.makeTestContainer` instead.\n\t\tconst loader = makeTestLoader(provider);\n\t\tcontainer = (await createAndAttachContainer(\n\t\t\tdefaultCodeDetails,\n\t\t\tloader,\n\t\t\tdriver.createCreateNewRequest(treeId)\n\t\t)) as Container;\n\t}\n\n\tconst dataObject = await requestFluidObject<ITestFluidObject>(container, '/');\n\n\tconst uploadedBlobs =\n\t\tblobs === undefined ? [] : await Promise.all(blobs.map(async (blob) => dataObject.context.uploadBlob(blob)));\n\tconst tree = await dataObject.getSharedObject<SharedTree>(treeId);\n\n\tif (initialTree !== undefined && testObjectProvider === undefined) {\n\t\tsetTestTree(tree, initialTree, setupEditId);\n\t}\n\n\treturn { container, tree, testObjectProvider: provider, uploadedBlobs };\n}\n\n/** Sets testTrait to contain `node`. */\nfunction setTestTree(tree: SharedTree, node: BuildNode, overrideId?: EditId): EditId {\n\tconst trait = testTrait(tree.currentView);\n\tif (overrideId === undefined) {\n\t\treturn tree.applyEdit(...setTrait(trait, node)).id;\n\t} else {\n\t\tconst changes = setTrait(trait, node).map((c) => tree.internalizeChange(c));\n\t\treturn tree.applyEditInternal({ changes, id: overrideId }).id;\n\t}\n}\n\n/**\n * Creates a list of edits with stable IDs that can be processed by a SharedTree.\n * @returns the list of created edits\n */\nexport function createStableEdits(\n\tnumberOfEdits: number,\n\tidContext: NodeIdContext = makeNodeIdContext(),\n\tpayload: (i: number) => Payload = identity\n): Edit<ChangeInternal>[] {\n\tif (numberOfEdits === 0) {\n\t\treturn [];\n\t}\n\n\tconst uuidNamespace = '44864298-500e-4cf8-9f44-a249e5b3a286';\n\tconst nodeId = idContext.generateNodeId('ae6b24eb-6fa8-42cc-abd2-48f250b7798f');\n\tconst node = buildLeaf(nodeId);\n\tconst insertEmptyNode = newEdit([\n\t\tChangeInternal.build([node], 0 as DetachedSequenceId),\n\t\tChangeInternal.insert(\n\t\t\t0 as DetachedSequenceId,\n\t\t\tStablePlace.atEndOf({ label: testTraitLabel, parent: idContext.convertToNodeId(initialTree.identifier) })\n\t\t),\n\t]);\n\n\tconst edits: Edit<ChangeInternal>[] = [{ ...insertEmptyNode, id: uuidv5('test', uuidNamespace) as EditId }];\n\n\t// Every subsequent edit is a set payload\n\tfor (let i = 1; i < numberOfEdits; i++) {\n\t\tconst edit = newEdit([ChangeInternal.setPayload(nodeId, payload(i))]);\n\t\tedits.push({ ...edit, id: uuidv5(i.toString(), uuidNamespace) as EditId });\n\t}\n\n\treturn edits;\n}\n\n/** Asserts that changes to SharedTree in editor() function do not cause any observable state change */\nexport function assertNoDelta(tree: SharedTree, editor: () => void) {\n\tconst viewA = tree.currentView;\n\teditor();\n\tconst viewB = tree.currentView;\n\tconst delta = viewA.delta(viewB);\n\texpect(delta).deep.equals({\n\t\tchanged: [],\n\t\tadded: [],\n\t\tremoved: [],\n\t});\n}\n\n/**\n * Used to test error throwing in async functions.\n */\nexport async function asyncFunctionThrowsCorrectly(\n\tasyncFunction: () => Promise<unknown>,\n\texpectedError: string\n): Promise<boolean> {\n\tlet errorMessage: string | undefined;\n\n\ttry {\n\t\tawait asyncFunction();\n\t} catch (error) {\n\t\terrorMessage = (error as Error).message;\n\t}\n\n\treturn errorMessage === expectedError;\n}\n\n/*\n * Returns true if two nodes have equivalent data, otherwise false.\n * Does not compare children or payloads.\n * @param nodes - two or more nodes to compare\n */\nexport function areNodesEquivalent(...nodes: NodeData<unknown>[]): boolean {\n\tif (nodes.length < 2) {\n\t\tfail('Too few nodes to compare');\n\t}\n\n\tfor (let i = 1; i < nodes.length; i++) {\n\t\tif (nodes[i].definition !== nodes[0].definition) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (nodes[i].identifier !== nodes[0].identifier) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n// This accounts for this file being executed after compilation. If many tests want to leverage resources, we should unify\n// resource path logic to a single place.\nexport const testDocumentsPathBase = resolve(__dirname, '../../../src/test/documents/');\n\nexport const versionComparator = (versionA: string, versionB: string): number => {\n\tconst versionASplit = versionA.split('.');\n\tconst versionBSplit = versionB.split('.');\n\n\tassert(\n\t\tversionASplit.length === versionBSplit.length && versionASplit.length === 3,\n\t\t'Version numbers should follow semantic versioning.'\n\t);\n\n\tfor (let i = 0; i < 3; ++i) {\n\t\tconst numberA = parseInt(versionASplit[i], 10);\n\t\tconst numberB = parseInt(versionBSplit[i], 10);\n\n\t\tif (numberA > numberB) {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (numberA < numberB) {\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\treturn 0;\n};\n\n/**\n * Create a {@link SimpleTestTree} from the given {@link SharedTree} or {@link IdCompressor}\n */\nexport function setUpTestTree(idSource?: IdCompressor | SharedTree, expensiveValidation = false): TestTree {\n\tconst source = idSource ?? new IdCompressor(createSessionId(), reservedIdCount);\n\tif (source instanceof SharedTree) {\n\t\tassert(source.edits.length === 0, 'tree must be a new SharedTree');\n\t\tconst getNormalizer = () => getIdNormalizerFromSharedTree(source);\n\t\tconst contextWrapper = {\n\t\t\tnormalizeToOpSpace: (id: NodeId) => getNormalizer().normalizeToOpSpace(id),\n\t\t\tnormalizeToSessionSpace: (id: OpSpaceNodeId, sessionId: SessionId) =>\n\t\t\t\tgetNormalizer().normalizeToSessionSpace(id, sessionId),\n\t\t\tget localSessionId() {\n\t\t\t\treturn getNormalizer().localSessionId;\n\t\t\t},\n\t\t};\n\t\tconst simpleTestTree = new SimpleTestTree(source, contextWrapper, expensiveValidation);\n\t\tsetTestTree(source, simpleTestTree);\n\t\treturn simpleTestTree;\n\t}\n\n\tconst context = makeNodeIdContext(source);\n\treturn new SimpleTestTree(context, context, expensiveValidation);\n}\n\n/**\n * Gets an id normalizer from the provided shared-tree. This is\n */\nexport function getIdNormalizerFromSharedTree(sharedTree: SharedTree): NodeIdNormalizer<OpSpaceNodeId> {\n\treturn (\n\t\t((sharedTree as any).idNormalizer as NodeIdNormalizer<OpSpaceNodeId>) ??\n\t\tfail('Failed to find SharedTree normalizer')\n\t);\n}\n\n/**\n * Create a {@link SimpleTestTree} before each test\n */\nexport function refreshTestTree(\n\tidSourceFactory?: (() => IdCompressor) | (() => SharedTree),\n\tfn?: (testTree: TestTree) => void,\n\texpensiveValidation = false\n): TestTree {\n\tconst factory = idSourceFactory ?? (() => new IdCompressor(createSessionId(), reservedIdCount));\n\treturn new RefreshingTestTree(() => {\n\t\treturn setUpTestTree(factory(), expensiveValidation);\n\t}, fn);\n}\n\nexport function makeNodeIdContext(idCompressor?: IdCompressor): NodeIdContext & NodeIdNormalizer<OpSpaceNodeId> {\n\tconst compressor = idCompressor ?? new IdCompressor(createSessionId(), reservedIdCount);\n\treturn getNodeIdContext(compressor);\n}\n\n/**\n * Applies an arbitrary edit to the given SharedTree which leaves the tree in the same state that it was before the edit.\n * This is useful for test scenarios that want to apply edits but don't care what they do.\n */\nexport function applyNoop(tree: SharedTree): Edit<unknown> {\n\treturn tree.applyEdit(...noopEdit(tree.currentView));\n}\n\n/**\n * Creates an arbitrary edit which leaves a tree in the same state that it was before the edit.\n * This is useful for test scenarios that want to create edits but don't care what they do.\n */\nexport function noopEdit(view: TreeView): Change[] {\n\tconst traitLocation = testTrait(view);\n\tconst trait = view.getTrait(traitLocation);\n\t// Set the test trait to the same thing that it already was\n\treturn setTrait(\n\t\ttraitLocation,\n\t\ttrait.map((id) => getChangeNodeFromViewNode(view, id))\n\t);\n}\n\n/** Translate an ID in one context to an ID in another */\nexport function translateId(id: NodeId | NodeData<NodeId>, from: NodeIdConverter, to: NodeIdConverter): NodeId {\n\treturn to.convertToNodeId(from.convertToStableNodeId(getNodeId(id)));\n}\n\nexport function normalizeId(tree: SharedTree, id: NodeId): OpSpaceNodeId {\n\tconst normalizer = getIdNormalizerFromSharedTree(tree);\n\treturn normalizer.normalizeToOpSpace(id);\n}\n\nexport function normalizeIds(tree: SharedTree, ...ids: NodeId[]): OpSpaceNodeId[] {\n\tconst normalizer = getIdNormalizerFromSharedTree(tree);\n\treturn ids.map((id) => normalizer.normalizeToOpSpace(id));\n}\n\nexport function idsAreEqual(treeA: SharedTree, idsA: NodeId[], treeB: SharedTree, idsB: NodeId[]): boolean {\n\tif (idsA.length !== idsB.length) {\n\t\treturn false;\n\t}\n\tconst contextA = getIdNormalizerFromSharedTree(treeA);\n\tconst contextB = getIdNormalizerFromSharedTree(treeB);\n\tfor (let i = 0; i < idsA.length; i++) {\n\t\tif (contextA.normalizeToOpSpace(idsA[i]) !== contextB.normalizeToOpSpace(idsB[i])) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nexport function normalizeEdit(\n\ttree: SharedTree,\n\tedit: Edit<ChangeInternal>\n): Edit<ReplaceRecursive<ChangeInternal, NodeId, OpSpaceNodeId>> {\n\tconst context = getIdNormalizerFromSharedTree(tree);\n\treturn convertEditIds(edit, (id) => context.normalizeToOpSpace(id));\n}\n\nexport function stabilizeEdit(\n\ttree: SharedTree,\n\tedit: Edit<ChangeInternal>\n): Edit<ReplaceRecursive<ChangeInternal, NodeId, StableNodeId>> {\n\treturn convertEditIds(edit, (id) => tree.convertToStableNodeId(id));\n}\n\nexport function getEditLogInternal(tree: SharedTree): OrderedEditSet<ChangeInternal> {\n\treturn tree.edits as unknown as OrderedEditSet<ChangeInternal>;\n}\n\n/**\n * Spies on all future ops submitted to `containerRuntimeFactory`. When ops are submitted, they will be `push`ed into the\n * returned array.\n */\nexport function spyOnSubmittedOps<Op extends SharedTreeOp | SharedTreeOp_0_0_2>(\n\tcontainerRuntimeFactory: MockContainerRuntimeFactory\n): Op[] {\n\tconst ops: Op[] = [];\n\tconst originalPush = containerRuntimeFactory.pushMessage.bind(containerRuntimeFactory);\n\tcontainerRuntimeFactory.pushMessage = (message: Partial<ISequencedDocumentMessage>) => {\n\t\tconst { contents } = message;\n\t\tops.push(contents as Op);\n\t\toriginalPush(message);\n\t};\n\treturn ops;\n}\n\n/**\n * Waits for summarization to occur, and returns a version that can be passed into newly loaded containers\n * to ensure they load this summary version. Use the `LoaderHeader.version` header.\n */\nexport async function waitForSummary(mainContainer: IContainer): Promise<string> {\n\tconst { deltaManager } = mainContainer;\n\tconst summaryCollection = new SummaryCollection(deltaManager, new TelemetryNullLogger());\n\tconst ackedSummary = await summaryCollection.waitSummaryAck(deltaManager.lastSequenceNumber);\n\treturn ackedSummary.summaryAck.contents.handle;\n}\n"]}
1
+ {"version":3,"file":"TestUtilities.js","sourceRoot":"","sources":["../../../src/test/utilities/TestUtilities.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 { resolve } from 'path';\nimport { v5 as uuidv5 } from 'uuid';\nimport { expect } from 'chai';\nimport { SummaryCollection } from '@fluidframework/container-runtime';\nimport { Container, Loader, waitContainerToCatchUp } from '@fluidframework/container-loader';\nimport { requestFluidObject } from '@fluidframework/runtime-utils';\nimport {\n\tMockContainerRuntimeFactory,\n\tMockFluidDataStoreRuntime,\n\tMockStorage,\n} from '@fluidframework/test-runtime-utils';\nimport {\n\tChannelFactoryRegistry,\n\tITestFluidObject,\n\tTestObjectProvider,\n\tTestContainerRuntimeFactory,\n\tTestFluidObjectFactory,\n\tcreateAndAttachContainer,\n} from '@fluidframework/test-utils';\nimport { LocalServerTestDriver } from '@fluidframework/test-drivers';\nimport { ITelemetryBaseLogger } from '@fluidframework/common-definitions';\nimport { TelemetryNullLogger } from '@fluidframework/common-utils';\nimport type { IContainer, IHostLoader } from '@fluidframework/container-definitions';\nimport type { IFluidCodeDetails, IFluidHandle, IRequestHeader } from '@fluidframework/core-interfaces';\nimport { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';\nimport { IContainerRuntimeBase } from '@fluidframework/runtime-definitions';\nimport { IRequest } from '@fluidframework/core-interfaces';\nimport {\n\tAttributionId,\n\tDetachedSequenceId,\n\tEditId,\n\tNodeId,\n\tOpSpaceNodeId,\n\tSessionId,\n\tStableNodeId,\n} from '../../Identifiers';\nimport { assert, fail, identity, ReplaceRecursive } from '../../Common';\nimport { IdCompressor } from '../../id-compressor';\nimport { createSessionId } from '../../id-compressor/NumericUuid';\nimport { getChangeNodeFromViewNode } from '../../SerializationUtilities';\nimport { initialTree } from '../../InitialTree';\nimport {\n\tChangeInternal,\n\tEdit,\n\tNodeData,\n\tPayload,\n\treservedIdCount,\n\tSharedTreeOp,\n\tSharedTreeOp_0_0_2,\n\tWriteFormat,\n} from '../../persisted-types';\nimport { TraitLocation, TreeView } from '../../TreeView';\nimport { SharedTreeDiagnosticEvent } from '../../EventTypes';\nimport { getNodeId, getNodeIdContext, NodeIdContext, NodeIdConverter, NodeIdNormalizer } from '../../NodeIdUtilities';\nimport { newEdit, setTrait } from '../../EditUtilities';\nimport { SharedTree, SharedTreeFactory } from '../../SharedTree';\nimport { BuildNode, Change, StablePlace } from '../../ChangeTypes';\nimport { convertEditIds } from '../../IdConversion';\nimport { OrderedEditSet } from '../../EditLog';\nimport { buildLeaf, RefreshingTestTree, SimpleTestTree, TestTree } from './TestNode';\n\n/** Objects returned by setUpTestSharedTree */\nexport interface SharedTreeTestingComponents {\n\t/** The MockFluidDataStoreRuntime used to created the SharedTree. */\n\tcomponentRuntime: MockFluidDataStoreRuntime;\n\t/**\n\t * The MockContainerRuntimeFactory created if one was not provided in the options.\n\t * Only connected to the SharedTree if the localMode option was set to false.\n\t * */\n\tcontainerRuntimeFactory: MockContainerRuntimeFactory;\n\t/** The SharedTree created and set up. */\n\ttree: SharedTree;\n}\n\n/** Options used to customize setUpTestSharedTree */\nexport interface SharedTreeTestingOptions {\n\t/**\n\t * Id for the SharedTree to be created.\n\t * If two SharedTrees have the same id and the same containerRuntimeFactory,\n\t * they will collaborate (send edits to each other)\n\t */\n\tid?: string;\n\t/** Node to initialize the SharedTree with. */\n\tinitialTree?: BuildNode;\n\t/** If false, a MockContainerRuntimeFactory connected to the SharedTree will be returned. */\n\tlocalMode?: boolean;\n\t/**\n\t * MockContainerRuntimeFactory to connect the SharedTree to. A new one will not be created if one is provided.\n\t * If localMode is set to true, it will not be connected to the created SharedTree.\n\t * */\n\tcontainerRuntimeFactory?: MockContainerRuntimeFactory;\n\t/** Iff true, do not `fail` on invalid edits */\n\tallowInvalid?: boolean;\n\t/** Iff true, do not `fail` on malformed edits */\n\tallowMalformed?: boolean;\n\t/** Unless set to true, a SharedTree error causes the test to fail */\n\tnoFailOnError?: boolean;\n\t/**\n\t * If not set, full history will be preserved.\n\t */\n\tsummarizeHistory?: boolean;\n\t/**\n\t * If not set, summaries will be written in format 0.1.1.\n\t */\n\twriteFormat?: WriteFormat;\n\t/**\n\t * Optional attribution ID to give to the new tree\n\t */\n\tattributionId?: AttributionId;\n\t/**\n\t * If set, uses the given id as the edit id for tree setup. Only has an effect if initialTree is also set.\n\t */\n\tsetupEditId?: EditId;\n\n\t/**\n\t * Telemetry logger injected into the SharedTree.\n\t */\n\tlogger?: ITelemetryBaseLogger;\n}\n\nexport const testTraitLabel = SimpleTestTree.traitLabel;\nexport function testTrait(view: TreeView): TraitLocation {\n\treturn {\n\t\tlabel: testTraitLabel,\n\t\tparent: view.root,\n\t};\n}\n\n/** Sets up and returns an object of components useful for testing SharedTree. */\nexport function setUpTestSharedTree(\n\toptions: SharedTreeTestingOptions = { localMode: true }\n): SharedTreeTestingComponents {\n\tconst {\n\t\tid,\n\t\tinitialTree,\n\t\tlocalMode,\n\t\tcontainerRuntimeFactory,\n\t\tsetupEditId,\n\t\tsummarizeHistory,\n\t\twriteFormat,\n\t\tattributionId,\n\t} = options;\n\tlet componentRuntime: MockFluidDataStoreRuntime;\n\tif (options.logger) {\n\t\tconst proxyHandler: ProxyHandler<MockFluidDataStoreRuntime> = {\n\t\t\tget: (target, prop, receiver) => {\n\t\t\t\tif (prop === 'logger' && options.logger) {\n\t\t\t\t\treturn options.logger;\n\t\t\t\t}\n\t\t\t\treturn target[prop as keyof MockFluidDataStoreRuntime];\n\t\t\t},\n\t\t};\n\t\tcomponentRuntime = new Proxy(new MockFluidDataStoreRuntime(), proxyHandler);\n\t} else {\n\t\tcomponentRuntime = new MockFluidDataStoreRuntime();\n\t}\n\n\t// Enable expensiveValidation\n\tlet factory: SharedTreeFactory;\n\tif (writeFormat === WriteFormat.v0_0_2) {\n\t\tfactory = SharedTree.getFactory(writeFormat, { summarizeHistory: summarizeHistory ?? true });\n\t} else {\n\t\tconst options = {\n\t\t\tsummarizeHistory: summarizeHistory ?? true ? { uploadEditChunks: true } : false,\n\t\t\tattributionId,\n\t\t};\n\t\tfactory = SharedTree.getFactory(writeFormat ?? WriteFormat.v0_1_1, options);\n\t}\n\tconst tree = factory.create(componentRuntime, id === undefined ? 'testSharedTree' : id);\n\n\tif (options.allowInvalid === undefined || !options.allowInvalid) {\n\t\ttree.on(SharedTreeDiagnosticEvent.DroppedInvalidEdit, () => fail('unexpected invalid edit'));\n\t}\n\n\tif (options.allowMalformed === undefined || !options.allowMalformed) {\n\t\ttree.on(SharedTreeDiagnosticEvent.DroppedMalformedEdit, () => fail('unexpected malformed edit'));\n\t}\n\n\tif (options.noFailOnError === undefined || !options.noFailOnError) {\n\t\t// any errors thrown by a SharedObject event listener will be caught and\n\t\t// reemitted on this event. For testing purposes, rethrow so that it\n\t\t// actually causes the test to fail.\n\t\ttree.on('error', (error) => {\n\t\t\tthrow error;\n\t\t});\n\t}\n\n\tconst newContainerRuntimeFactory = containerRuntimeFactory || new MockContainerRuntimeFactory();\n\n\tif (localMode === true) {\n\t\tcomponentRuntime.local = true;\n\t} else {\n\t\tconst containerRuntime = newContainerRuntimeFactory.createContainerRuntime(componentRuntime);\n\t\tconst services = {\n\t\t\tdeltaConnection: containerRuntime.createDeltaConnection(),\n\t\t\tobjectStorage: new MockStorage(undefined),\n\t\t};\n\t\ttree.connect(services);\n\t}\n\n\tif (initialTree !== undefined) {\n\t\tsetTestTree(tree, initialTree, setupEditId);\n\t}\n\n\treturn {\n\t\tcomponentRuntime,\n\t\tcontainerRuntimeFactory: newContainerRuntimeFactory,\n\t\ttree,\n\t};\n}\n\nconst TestDataStoreType = '@fluid-example/test-dataStore';\n\n/** Objects returned by setUpLocalServerTestSharedTree */\nexport interface LocalServerSharedTreeTestingComponents {\n\t/** The testObjectProvider created if one was not set in the options. */\n\ttestObjectProvider: TestObjectProvider;\n\t/** The SharedTree created and set up. */\n\ttree: SharedTree;\n\t/** The container created and set up. */\n\tcontainer: Container;\n\t/** Handles to any blobs uploaded via `blobs` */\n\tuploadedBlobs: IFluidHandle<ArrayBufferLike>[];\n}\n\n/** Options used to customize setUpLocalServerTestSharedTree */\nexport interface LocalServerSharedTreeTestingOptions {\n\t/** Contents of blobs that should be uploaded to the runtime upon creation. Handles to these blobs will be returned. */\n\tblobs?: ArrayBufferLike[];\n\t/** Headers to include on the container load request. */\n\theaders?: IRequestHeader;\n\t/**\n\t * Id for the SharedTree to be created.\n\t * If two SharedTrees have the same id and the same testObjectProvider,\n\t * they will collaborate (send edits to each other)\n\t */\n\tid?: string;\n\t/** Node to initialize the SharedTree with. */\n\tinitialTree?: BuildNode;\n\t/** If set, uses the provider to create the container and create the SharedTree. */\n\ttestObjectProvider?: TestObjectProvider;\n\t/**\n\t * If not set, full history will be preserved.\n\t */\n\tsummarizeHistory?: boolean;\n\t/**\n\t * If not set, summaries will be written in format 0.0.2.\n\t */\n\twriteFormat?: WriteFormat;\n\t/**\n\t * Optional attribution ID to give to the new tree\n\t */\n\tattributionId?: AttributionId;\n\t/**\n\t * If not set, will upload edit chunks when they are full.\n\t */\n\tuploadEditChunks?: boolean;\n\t/**\n\t * If set, uses the given id as the edit id for tree setup. Only has an effect if initialTree is also set.\n\t */\n\tsetupEditId?: EditId;\n}\n\nconst testObjectProviders: TestObjectProvider[] = [];\nafterEach(() => {\n\tfor (const provider of testObjectProviders) {\n\t\tprovider.reset();\n\t}\n\ttestObjectProviders.length = 0;\n});\n\n/**\n * Sets up and returns an object of components useful for testing SharedTree with a local server.\n * Required for tests that involve the uploadBlob API.\n *\n * Any TestObjectProvider created by this function will be reset after the test completes (via afterEach) hook.\n */\nexport async function setUpLocalServerTestSharedTree(\n\toptions: LocalServerSharedTreeTestingOptions\n): Promise<LocalServerSharedTreeTestingComponents> {\n\tconst {\n\t\tblobs,\n\t\theaders,\n\t\tid,\n\t\tinitialTree,\n\t\ttestObjectProvider,\n\t\tsetupEditId,\n\t\tsummarizeHistory,\n\t\twriteFormat,\n\t\tuploadEditChunks,\n\t\tattributionId,\n\t} = options;\n\n\tconst treeId = id ?? 'test';\n\tlet factory: SharedTreeFactory;\n\tif (writeFormat === WriteFormat.v0_0_2) {\n\t\tfactory = SharedTree.getFactory(writeFormat, { summarizeHistory: summarizeHistory ?? true });\n\t} else {\n\t\tconst options = {\n\t\t\tsummarizeHistory: summarizeHistory ?? true ? { uploadEditChunks: uploadEditChunks ?? true } : false,\n\t\t\tattributionId,\n\t\t};\n\t\tfactory = SharedTree.getFactory(writeFormat ?? WriteFormat.v0_1_1, options);\n\t}\n\tconst registry: ChannelFactoryRegistry = [[treeId, factory]];\n\tconst innerRequestHandler = async (request: IRequest, runtime: IContainerRuntimeBase) =>\n\t\truntime.IFluidHandleContext.resolveHandle(request);\n\n\tconst runtimeFactory = () =>\n\t\tnew TestContainerRuntimeFactory(\n\t\t\tTestDataStoreType,\n\t\t\tnew TestFluidObjectFactory(registry),\n\t\t\t{\n\t\t\t\tsummaryOptions: {\n\t\t\t\t\tsummaryConfigOverrides: {\n\t\t\t\t\t\tidleTime: 1000, // Current default idleTime is 15000 which will cause some SharedTree tests to timeout.\n\t\t\t\t\t},\n\t\t\t\t\tinitialSummarizerDelayMs: 0,\n\t\t\t\t},\n\t\t\t},\n\t\t\t[innerRequestHandler]\n\t\t);\n\n\tconst defaultCodeDetails: IFluidCodeDetails = {\n\t\tpackage: 'defaultTestPackage',\n\t\tconfig: {},\n\t};\n\n\tfunction makeTestLoader(provider: TestObjectProvider): IHostLoader {\n\t\tconst fluidEntryPoint = runtimeFactory();\n\t\treturn provider.createLoader([[defaultCodeDetails, fluidEntryPoint]], {\n\t\t\toptions: { maxClientLeaveWaitTime: 1000 },\n\t\t});\n\t}\n\n\tlet provider: TestObjectProvider;\n\tlet container: Container;\n\n\tif (testObjectProvider !== undefined) {\n\t\tprovider = testObjectProvider;\n\t\tconst driver = new LocalServerTestDriver();\n\t\tconst loader = makeTestLoader(provider);\n\t\t// Once ILoaderOptions is specificable, this should use `provider.loadTestContainer` instead.\n\t\tcontainer = (await loader.resolve({ url: await driver.createContainerUrl(treeId), headers })) as Container;\n\t\tawait waitContainerToCatchUp(container);\n\t} else {\n\t\tconst driver = new LocalServerTestDriver();\n\t\tprovider = new TestObjectProvider(Loader, driver, runtimeFactory);\n\t\ttestObjectProviders.push(provider);\n\t\t// Once ILoaderOptions is specificable, this should use `provider.makeTestContainer` instead.\n\t\tconst loader = makeTestLoader(provider);\n\t\tcontainer = (await createAndAttachContainer(\n\t\t\tdefaultCodeDetails,\n\t\t\tloader,\n\t\t\tdriver.createCreateNewRequest(treeId)\n\t\t)) as Container;\n\t}\n\n\tconst dataObject = await requestFluidObject<ITestFluidObject>(container, '/');\n\n\tconst uploadedBlobs =\n\t\tblobs === undefined ? [] : await Promise.all(blobs.map(async (blob) => dataObject.context.uploadBlob(blob)));\n\tconst tree = await dataObject.getSharedObject<SharedTree>(treeId);\n\n\tif (initialTree !== undefined && testObjectProvider === undefined) {\n\t\tsetTestTree(tree, initialTree, setupEditId);\n\t}\n\n\treturn { container, tree, testObjectProvider: provider, uploadedBlobs };\n}\n\n/** Sets testTrait to contain `node`. */\nfunction setTestTree(tree: SharedTree, node: BuildNode, overrideId?: EditId): EditId {\n\tconst trait = testTrait(tree.currentView);\n\tif (overrideId === undefined) {\n\t\treturn tree.applyEdit(...setTrait(trait, node)).id;\n\t} else {\n\t\tconst changes = setTrait(trait, node).map((c) => tree.internalizeChange(c));\n\t\treturn tree.applyEditInternal({ changes, id: overrideId }).id;\n\t}\n}\n\n/**\n * Creates a list of edits with stable IDs that can be processed by a SharedTree.\n * @returns the list of created edits\n */\nexport function createStableEdits(\n\tnumberOfEdits: number,\n\tidContext: NodeIdContext = makeNodeIdContext(),\n\tpayload: (i: number) => Payload = identity\n): Edit<ChangeInternal>[] {\n\tif (numberOfEdits === 0) {\n\t\treturn [];\n\t}\n\n\tconst uuidNamespace = '44864298-500e-4cf8-9f44-a249e5b3a286';\n\tconst nodeId = idContext.generateNodeId('ae6b24eb-6fa8-42cc-abd2-48f250b7798f');\n\tconst node = buildLeaf(nodeId);\n\tconst insertEmptyNode = newEdit([\n\t\tChangeInternal.build([node], 0 as DetachedSequenceId),\n\t\tChangeInternal.insert(\n\t\t\t0 as DetachedSequenceId,\n\t\t\tStablePlace.atEndOf({ label: testTraitLabel, parent: idContext.convertToNodeId(initialTree.identifier) })\n\t\t),\n\t]);\n\n\tconst edits: Edit<ChangeInternal>[] = [{ ...insertEmptyNode, id: uuidv5('test', uuidNamespace) as EditId }];\n\n\t// Every subsequent edit is a set payload\n\tfor (let i = 1; i < numberOfEdits; i++) {\n\t\tconst edit = newEdit([ChangeInternal.setPayload(nodeId, payload(i))]);\n\t\tedits.push({ ...edit, id: uuidv5(i.toString(), uuidNamespace) as EditId });\n\t}\n\n\treturn edits;\n}\n\n/** Asserts that changes to SharedTree in editor() function do not cause any observable state change */\nexport function assertNoDelta(tree: SharedTree, editor: () => void) {\n\tconst viewA = tree.currentView;\n\teditor();\n\tconst viewB = tree.currentView;\n\tconst delta = viewA.delta(viewB);\n\texpect(delta).deep.equals({\n\t\tchanged: [],\n\t\tadded: [],\n\t\tremoved: [],\n\t});\n}\n\n/**\n * Used to test error throwing in async functions.\n */\nexport async function asyncFunctionThrowsCorrectly(\n\tasyncFunction: () => Promise<unknown>,\n\texpectedError: string\n): Promise<boolean> {\n\tlet errorMessage: string | undefined;\n\n\ttry {\n\t\tawait asyncFunction();\n\t} catch (error) {\n\t\terrorMessage = (error as Error).message;\n\t}\n\n\treturn errorMessage === expectedError;\n}\n\n/*\n * Returns true if two nodes have equivalent data, otherwise false.\n * Does not compare children or payloads.\n * @param nodes - two or more nodes to compare\n */\nexport function areNodesEquivalent(...nodes: NodeData<unknown>[]): boolean {\n\tif (nodes.length < 2) {\n\t\tfail('Too few nodes to compare');\n\t}\n\n\tfor (let i = 1; i < nodes.length; i++) {\n\t\tif (nodes[i].definition !== nodes[0].definition) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (nodes[i].identifier !== nodes[0].identifier) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n// This accounts for this file being executed after compilation. If many tests want to leverage resources, we should unify\n// resource path logic to a single place.\nexport const testDocumentsPathBase = resolve(__dirname, '../../../src/test/documents/');\n\nexport const versionComparator = (versionA: string, versionB: string): number => {\n\tconst versionASplit = versionA.split('.');\n\tconst versionBSplit = versionB.split('.');\n\n\tassert(\n\t\tversionASplit.length === versionBSplit.length && versionASplit.length === 3,\n\t\t'Version numbers should follow semantic versioning.'\n\t);\n\n\tfor (let i = 0; i < 3; ++i) {\n\t\tconst numberA = parseInt(versionASplit[i], 10);\n\t\tconst numberB = parseInt(versionBSplit[i], 10);\n\n\t\tif (numberA > numberB) {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (numberA < numberB) {\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\treturn 0;\n};\n\n/**\n * Create a {@link SimpleTestTree} from the given {@link SharedTree} or {@link IdCompressor}\n */\nexport function setUpTestTree(idSource?: IdCompressor | SharedTree, expensiveValidation = false): TestTree {\n\tconst source = idSource ?? new IdCompressor(createSessionId(), reservedIdCount);\n\tif (source instanceof SharedTree) {\n\t\tassert(source.edits.length === 0, 'tree must be a new SharedTree');\n\t\tconst getNormalizer = () => getIdNormalizerFromSharedTree(source);\n\t\tconst contextWrapper = {\n\t\t\tnormalizeToOpSpace: (id: NodeId) => getNormalizer().normalizeToOpSpace(id),\n\t\t\tnormalizeToSessionSpace: (id: OpSpaceNodeId, sessionId: SessionId) =>\n\t\t\t\tgetNormalizer().normalizeToSessionSpace(id, sessionId),\n\t\t\tget localSessionId() {\n\t\t\t\treturn getNormalizer().localSessionId;\n\t\t\t},\n\t\t};\n\t\tconst simpleTestTree = new SimpleTestTree(source, contextWrapper, expensiveValidation);\n\t\tsetTestTree(source, simpleTestTree);\n\t\treturn simpleTestTree;\n\t}\n\n\tconst context = makeNodeIdContext(source);\n\treturn new SimpleTestTree(context, context, expensiveValidation);\n}\n\n/**\n * Gets an id normalizer from the provided shared-tree. This is\n */\nexport function getIdNormalizerFromSharedTree(sharedTree: SharedTree): NodeIdNormalizer<OpSpaceNodeId> {\n\treturn (\n\t\t((sharedTree as any).idNormalizer as NodeIdNormalizer<OpSpaceNodeId>) ??\n\t\tfail('Failed to find SharedTree normalizer')\n\t);\n}\n\n/**\n * Create a {@link SimpleTestTree} before each test\n */\nexport function refreshTestTree(\n\tidSourceFactory?: (() => IdCompressor) | (() => SharedTree),\n\tfn?: (testTree: TestTree) => void,\n\texpensiveValidation = false\n): TestTree {\n\tconst factory = idSourceFactory ?? (() => new IdCompressor(createSessionId(), reservedIdCount));\n\treturn new RefreshingTestTree(() => {\n\t\treturn setUpTestTree(factory(), expensiveValidation);\n\t}, fn);\n}\n\nexport function makeNodeIdContext(idCompressor?: IdCompressor): NodeIdContext & NodeIdNormalizer<OpSpaceNodeId> {\n\tconst compressor = idCompressor ?? new IdCompressor(createSessionId(), reservedIdCount);\n\treturn getNodeIdContext(compressor);\n}\n\n/**\n * Applies an arbitrary edit to the given SharedTree which leaves the tree in the same state that it was before the edit.\n * This is useful for test scenarios that want to apply edits but don't care what they do.\n */\nexport function applyNoop(tree: SharedTree): Edit<unknown> {\n\treturn tree.applyEdit(...noopEdit(tree.currentView));\n}\n\n/**\n * Creates an arbitrary edit which leaves a tree in the same state that it was before the edit.\n * This is useful for test scenarios that want to create edits but don't care what they do.\n */\nexport function noopEdit(view: TreeView): Change[] {\n\tconst traitLocation = testTrait(view);\n\tconst trait = view.getTrait(traitLocation);\n\t// Set the test trait to the same thing that it already was\n\treturn setTrait(\n\t\ttraitLocation,\n\t\ttrait.map((id) => getChangeNodeFromViewNode(view, id))\n\t);\n}\n\n/** Translate an ID in one context to an ID in another */\nexport function translateId(id: NodeId | NodeData<NodeId>, from: NodeIdConverter, to: NodeIdConverter): NodeId {\n\treturn to.convertToNodeId(from.convertToStableNodeId(getNodeId(id)));\n}\n\nexport function normalizeId(tree: SharedTree, id: NodeId): OpSpaceNodeId {\n\tconst normalizer = getIdNormalizerFromSharedTree(tree);\n\treturn normalizer.normalizeToOpSpace(id);\n}\n\nexport function normalizeIds(tree: SharedTree, ...ids: NodeId[]): OpSpaceNodeId[] {\n\tconst normalizer = getIdNormalizerFromSharedTree(tree);\n\treturn ids.map((id) => normalizer.normalizeToOpSpace(id));\n}\n\nexport function idsAreEqual(treeA: SharedTree, idsA: NodeId[], treeB: SharedTree, idsB: NodeId[]): boolean {\n\tif (idsA.length !== idsB.length) {\n\t\treturn false;\n\t}\n\tconst contextA = getIdNormalizerFromSharedTree(treeA);\n\tconst contextB = getIdNormalizerFromSharedTree(treeB);\n\tfor (let i = 0; i < idsA.length; i++) {\n\t\tif (contextA.normalizeToOpSpace(idsA[i]) !== contextB.normalizeToOpSpace(idsB[i])) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\nexport function normalizeEdit(\n\ttree: SharedTree,\n\tedit: Edit<ChangeInternal>\n): Edit<ReplaceRecursive<ChangeInternal, NodeId, OpSpaceNodeId>> {\n\tconst context = getIdNormalizerFromSharedTree(tree);\n\treturn convertEditIds(edit, (id) => context.normalizeToOpSpace(id));\n}\n\nexport function stabilizeEdit(\n\ttree: SharedTree,\n\tedit: Edit<ChangeInternal>\n): Edit<ReplaceRecursive<ChangeInternal, NodeId, StableNodeId>> {\n\treturn convertEditIds(edit, (id) => tree.convertToStableNodeId(id));\n}\n\nexport function getEditLogInternal(tree: SharedTree): OrderedEditSet<ChangeInternal> {\n\treturn tree.edits as unknown as OrderedEditSet<ChangeInternal>;\n}\n\n/**\n * Spies on all future ops submitted to `containerRuntimeFactory`. When ops are submitted, they will be `push`ed into the\n * returned array.\n */\nexport function spyOnSubmittedOps<Op extends SharedTreeOp | SharedTreeOp_0_0_2>(\n\tcontainerRuntimeFactory: MockContainerRuntimeFactory\n): Op[] {\n\tconst ops: Op[] = [];\n\tconst originalPush = containerRuntimeFactory.pushMessage.bind(containerRuntimeFactory);\n\tcontainerRuntimeFactory.pushMessage = (message: Partial<ISequencedDocumentMessage>) => {\n\t\tconst { contents } = message;\n\t\tops.push(contents as Op);\n\t\toriginalPush(message);\n\t};\n\treturn ops;\n}\n\n/**\n * Waits for summarization to occur, and returns a version that can be passed into newly loaded containers\n * to ensure they load this summary version. Use the `LoaderHeader.version` header.\n */\nexport async function waitForSummary(mainContainer: IContainer): Promise<string> {\n\tconst { deltaManager } = mainContainer;\n\tconst summaryCollection = new SummaryCollection(deltaManager, new TelemetryNullLogger());\n\tconst ackedSummary = await summaryCollection.waitSummaryAck(deltaManager.lastSequenceNumber);\n\treturn ackedSummary.summaryAck.contents.handle;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-experimental/tree",
3
- "version": "0.59.2001",
3
+ "version": "0.59.3000",
4
4
  "description": "Distributed tree",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -38,11 +38,11 @@
38
38
  "@fluidframework/common-utils": "^0.32.1",
39
39
  "@fluidframework/container-definitions": "^0.48.1000",
40
40
  "@fluidframework/core-interfaces": "^0.43.1000",
41
- "@fluidframework/datastore-definitions": "^0.59.2001",
41
+ "@fluidframework/datastore-definitions": "^0.59.3000",
42
42
  "@fluidframework/protocol-definitions": "^0.1028.1000",
43
- "@fluidframework/runtime-definitions": "^0.59.2001",
44
- "@fluidframework/shared-object-base": "^0.59.2001",
45
- "@fluidframework/telemetry-utils": "^0.59.2001",
43
+ "@fluidframework/runtime-definitions": "^0.59.3000",
44
+ "@fluidframework/shared-object-base": "^0.59.3000",
45
+ "@fluidframework/telemetry-utils": "^0.59.3000",
46
46
  "buffer": "^6.0.3",
47
47
  "denque": "^1.5.1",
48
48
  "lru-cache": "^6.0.0",
@@ -50,21 +50,23 @@
50
50
  "uuid": "^8.3.1"
51
51
  },
52
52
  "devDependencies": {
53
+ "@fluid-internal/stochastic-test-utils": "^0.59.3000",
53
54
  "@fluid-tools/benchmark": "^0.40.0",
54
55
  "@fluidframework/build-common": "^0.23.0",
55
- "@fluidframework/container-loader": "^0.59.2001",
56
- "@fluidframework/container-runtime": "^0.59.2001",
57
- "@fluidframework/eslint-config-fluid": "^0.28.1000",
58
- "@fluidframework/mocha-test-setup": "^0.59.2001",
59
- "@fluidframework/runtime-utils": "^0.59.2001",
60
- "@fluidframework/test-driver-definitions": "^0.59.2001",
61
- "@fluidframework/test-drivers": "^0.59.2001",
62
- "@fluidframework/test-runtime-utils": "^0.59.2001",
63
- "@fluidframework/test-utils": "^0.59.2001",
64
- "@fluidframework/undo-redo": "^0.59.2001",
56
+ "@fluidframework/container-loader": "^0.59.3000",
57
+ "@fluidframework/container-runtime": "^0.59.3000",
58
+ "@fluidframework/eslint-config-fluid": "^0.28.2000",
59
+ "@fluidframework/mocha-test-setup": "^0.59.3000",
60
+ "@fluidframework/runtime-utils": "^0.59.3000",
61
+ "@fluidframework/test-driver-definitions": "^0.59.3000",
62
+ "@fluidframework/test-drivers": "^0.59.3000",
63
+ "@fluidframework/test-runtime-utils": "^0.59.3000",
64
+ "@fluidframework/test-utils": "^0.59.3000",
65
+ "@fluidframework/undo-redo": "^0.59.3000",
65
66
  "@microsoft/api-extractor": "^7.22.2",
66
67
  "@rushstack/eslint-config": "^2.5.1",
67
68
  "@types/lru-cache": "^5.1.0",
69
+ "@types/random-js": "^1.0.31",
68
70
  "@typescript-eslint/eslint-plugin": "~5.9.0",
69
71
  "@typescript-eslint/parser": "~5.9.0",
70
72
  "chai": "^4.2.0",
@@ -84,9 +86,9 @@
84
86
  "eslint-plugin-unicorn": "~40.0.0",
85
87
  "mocha": "^8.4.0",
86
88
  "nyc": "^15.0.0",
87
- "prando": "^6.0.1",
88
89
  "prettier": "^2.3.1",
90
+ "random-js": "^1.0.8",
89
91
  "rimraf": "^2.6.2",
90
- "typescript": "~4.1.3"
92
+ "typescript": "~4.5.5"
91
93
  }
92
94
  }
package/src/Common.ts CHANGED
@@ -48,7 +48,7 @@ class SharedTreeAssertionError extends Error {
48
48
  }
49
49
 
50
50
  /**
51
- * Compares finite numbers to form a strict partial ordering.
51
+ * A numeric comparator used for sorting in ascending order.
52
52
  *
53
53
  * Handles +/-0 like Map: -0 is equal to +0.
54
54
  */
@@ -56,6 +56,15 @@ export function compareFiniteNumbers<T extends number>(a: T, b: T): number {
56
56
  return a - b;
57
57
  }
58
58
 
59
+ /**
60
+ * A numeric comparator used for sorting in descending order.
61
+ *
62
+ * Handles +/-0 like Map: -0 is equal to +0.
63
+ */
64
+ export function compareFiniteNumbersReversed<T extends number>(a: T, b: T): number {
65
+ return b - a;
66
+ }
67
+
59
68
  /**
60
69
  * Compares strings lexically to form a strict partial ordering.
61
70
  */
@@ -317,13 +326,13 @@ export function compareMaps<K, V>(
317
326
  * Retrieve a value from a map with the given key, or create a new entry if the key is not in the map.
318
327
  * @param map - the map to query/update
319
328
  * @param key - the key to lookup in the map
320
- * @param defaultValue - a function which returns a default value. This is called and used to set an initial value in the map if none exists
329
+ * @param defaultValue - a function which returns a default value. This is called and used to set an initial value for the given key in the map if none exists
321
330
  * @returns either the existing value for the given key, or the newly-created value (the result of `defaultValue`)
322
331
  */
323
- export function getOrCreate<K, V>(map: Map<K, V>, key: K, defaultValue: () => V): V {
332
+ export function getOrCreate<K, V>(map: Map<K, V>, key: K, defaultValue: (key: K) => V): V {
324
333
  let value = map.get(key);
325
334
  if (value === undefined) {
326
- value = defaultValue();
335
+ value = defaultValue(key);
327
336
  map.set(key, value);
328
337
  }
329
338
  return value;
@@ -369,6 +378,7 @@ export function setPropertyIfDefined<TDst, P extends keyof TDst>(
369
378
  }
370
379
 
371
380
  /**
381
+ * ```
372
382
  * function (thing: ObjectWithMaybeFoo) {
373
383
  * const x: MyActualType = {
374
384
  * bar: 3
@@ -377,6 +387,7 @@ export function setPropertyIfDefined<TDst, P extends keyof TDst>(
377
387
  *
378
388
  * copyPropertyIfDefined(thing, x, 'foo');
379
389
  * }
390
+ * ```
380
391
  * @returns
381
392
  */
382
393
 
@@ -533,3 +544,30 @@ export type ReplaceRecursive<T, TReplace, TWith> = T extends TReplace
533
544
  : {
534
545
  [P in keyof T]: ReplaceRecursive<T[P], TReplace, TWith>;
535
546
  };
547
+
548
+ /** A union type of the first `N` positive integers */
549
+ export type TakeWholeNumbers<N extends number, A extends never[] = []> = N extends A['length']
550
+ ? never
551
+ : A['length'] | TakeWholeNumbers<N, [never, ...A]>;
552
+ /** Returns a tuple type with exactly `Length` elements of type `T` */
553
+ export type ArrayOfLength<T, Length extends number, A extends T[] = []> = Length extends A['length']
554
+ ? A
555
+ : ArrayOfLength<T, Length, [T, ...A]>;
556
+ /**
557
+ * Fails if `array` does not have exactly `length` elements
558
+ */
559
+ export function hasExactlyLength<T, Len extends TakeWholeNumbers<16>>(
560
+ array: readonly T[],
561
+ length: Len
562
+ ): array is ArrayOfLength<T, Len> {
563
+ return array.length === length;
564
+ }
565
+ /**
566
+ * Fails if `array` does not have at least `length` elements
567
+ */
568
+ export function hasLength<T, Len extends TakeWholeNumbers<16>>(
569
+ array: readonly T[],
570
+ length: Len
571
+ ): array is [...ArrayOfLength<T, Len>, ...T[]] {
572
+ return array.length >= length;
573
+ }
package/src/EditLog.ts CHANGED
@@ -331,7 +331,7 @@ export class EditLog<TChange = unknown> extends TypedEventEmitter<IEditLogEvents
331
331
  */
332
332
  public isLocalEdit(editId: EditId): boolean {
333
333
  const entry = this.allEditIds.get(editId);
334
- return entry !== undefined && entry.isLocal;
334
+ return entry?.isLocal ?? false;
335
335
  }
336
336
 
337
337
  /**
@@ -15,6 +15,11 @@
15
15
  */
16
16
  export type UuidString = string & { readonly UuidString: '9d40d0ae-90d9-44b1-9482-9f55d59d5465' };
17
17
 
18
+ /**
19
+ * An identifier associated with a session for the purpose of attributing its created content to some user/entity.
20
+ */
21
+ export type AttributionId = UuidString;
22
+
18
23
  /**
19
24
  * A version 4, variant 2 uuid (https://datatracker.ietf.org/doc/html/rfc4122).
20
25
  * @internal
package/src/LogViewer.ts CHANGED
@@ -205,11 +205,6 @@ export class CachingLogViewer implements LogViewer {
205
205
  */
206
206
  private readonly processEditStatus: EditStatusCallback;
207
207
 
208
- /**
209
- * Iff true, additional correctness assertions will be run during LogViewer operations.
210
- */
211
- private readonly expensiveValidation: boolean;
212
-
213
208
  /**
214
209
  * The ordered queue of edits that originated from this client that have never been applied (by this log viewer) in a sequenced state.
215
210
  * This means these edits may be local or sequenced, and may have been applied (possibly multiple times) while still local.
@@ -258,21 +253,15 @@ export class CachingLogViewer implements LogViewer {
258
253
  log: EditLog<ChangeInternal>,
259
254
  baseView: RevisionView,
260
255
  knownRevisions: [Revision, EditCacheEntry][] = [],
261
- expensiveValidation = false,
262
256
  processEditStatus: EditStatusCallback = noop,
263
257
  processSequencedEditResult: SequencedEditResultCallback = noop,
264
258
  minimumSequenceNumber = 0
265
259
  ) {
266
260
  this.log = log;
267
- if (expensiveValidation) {
268
- knownRevisions.forEach(([revision]) => {
269
- assert(Number.isInteger(revision), 'revision must be an integer');
270
- assert(
271
- this.log.isSequencedRevision(revision),
272
- 'revision must correspond to the result of a SequencedEdit'
273
- );
274
- });
275
- }
261
+ knownRevisions.forEach(([revision]) => {
262
+ assert(Number.isInteger(revision), 'revision must be an integer');
263
+ assert(this.log.isSequencedRevision(revision), 'revision must correspond to the result of a SequencedEdit');
264
+ });
276
265
 
277
266
  this.sequencedRevisionCache = new RevisionValueCache(
278
267
  CachingLogViewer.sequencedCacheSizeMax,
@@ -281,7 +270,6 @@ export class CachingLogViewer implements LogViewer {
281
270
  );
282
271
  this.processEditStatus = processEditStatus ?? noop;
283
272
  this.processSequencedEditResult = processSequencedEditResult ?? noop;
284
- this.expensiveValidation = expensiveValidation;
285
273
  this.detachFromEditLog = this.log.registerEditAddedHandler(this.handleEditAdded.bind(this));
286
274
  }
287
275
 
@@ -503,10 +491,6 @@ export class CachingLogViewer implements LogViewer {
503
491
  if (edit.id === this.unappliedSelfEdits.peekFront()) {
504
492
  wasLocal = true;
505
493
  this.unappliedSelfEdits.shift();
506
- } else if (this.expensiveValidation) {
507
- for (let i = 0; i < this.unappliedSelfEdits.length; i++) {
508
- assert(this.unappliedSelfEdits.peekAt(i) !== edit.id, 'Local edits processed out of order.');
509
- }
510
494
  }
511
495
  }
512
496
  this.processSequencedEditResult({ edit, wasLocal, result, reconciliationPath });
@@ -21,10 +21,12 @@ export type Revision = number;
21
21
  * A cache of `TValue`s corresponding to `Revision`s.
22
22
  *
23
23
  * A value is kept in cache if it meets any of the following criteria:
24
- * - The revision is >= `retentionWindowStart`
25
- * - The value has been used recently, meaning getClosestEntry or cacheValue was called with its revision. Note that being returned
26
- * when a large revision was passed to getClosestEntry does not count.
27
- * - The value is `retained` meaning it was provided to to constructor in retainedEntries or passed to `cacheRetainedValue`
24
+ *
25
+ * - The revision is \>= `retentionWindowStart`
26
+ * - The value has been used recently, meaning getClosestEntry or cacheValue was called with its revision. Note that
27
+ * being returned when a large revision was passed to getClosestEntry does not count.
28
+ * - The value is `retained` meaning it was provided to to constructor in retainedEntries or passed to
29
+ * `cacheRetainedValue`
28
30
  */
29
31
  export class RevisionValueCache<TValue> {
30
32
  /**
@@ -36,7 +38,7 @@ export class RevisionValueCache<TValue> {
36
38
 
37
39
  /**
38
40
  * Cache of most recently used evictable entries.
39
- * Subset of 'sortedValues` eligible for eviction:
41
+ * Subset of `sortedValues` eligible for eviction:
40
42
  * All entries are also in `sortedValues`, and are removed from `sortedValues` when evicted from this cache.
41
43
  * Evicts least recently used entries.
42
44
  */
@@ -53,8 +55,8 @@ export class RevisionValueCache<TValue> {
53
55
  */
54
56
  evictableSize: number,
55
57
  /**
56
- * The first revision within the retention window. All entries with revisions >= retentionWindowStart will be retained.
57
- * Must be >= 0.
58
+ * The first revision within the retention window. All entries with revisions \>= retentionWindowStart will be retained.
59
+ * Must be \>= 0.
58
60
  */
59
61
  private retentionWindowStart: Revision,
60
62
  /**
@@ -117,7 +119,8 @@ export class RevisionValueCache<TValue> {
117
119
  }
118
120
 
119
121
  /**
120
- * @returns a [cachedRevision, value] where cachedRevision <= requestedRevision, or undefined if no such revision is cached.
122
+ * @returns a [cachedRevision, value] where cachedRevision \<= requestedRevision, or undefined if no such revision
123
+ * is cached.
121
124
  */
122
125
  public getClosestEntry(requestedRevision: Revision): [revision: Revision, value: TValue] | undefined {
123
126
  const fromLRU = this.evictableRevisions.get(requestedRevision);