@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
@@ -180,8 +180,7 @@ describe('CachingLogViewer', () => {
180
180
  arbitraryRevisionView = RevisionView.fromTree(t.buildLeaf(t.generateNodeId()));
181
181
  });
182
182
  function getCachingLogViewerAssumeAppliedEdits(log, baseView, editStatusCallback, sequencedEditResultCallback, knownRevisions) {
183
- return new CachingLogViewer(log, baseView, knownRevisions === null || knownRevisions === void 0 ? void 0 : knownRevisions.map((pair) => [pair[0], { view: pair[1], result: EditStatus.Applied }]),
184
- /* expensiveValidation */ true, editStatusCallback, sequencedEditResultCallback, log.numberOfSequencedEdits);
183
+ return new CachingLogViewer(log, baseView, knownRevisions === null || knownRevisions === void 0 ? void 0 : knownRevisions.map((pair) => [pair[0], { view: pair[1], result: EditStatus.Applied }]), editStatusCallback, sequencedEditResultCallback, log.numberOfSequencedEdits);
185
184
  }
186
185
  runLogViewerCorrectnessTests(getCachingLogViewerAssumeAppliedEdits);
187
186
  it('detects non-integer revisions when setting revision views', async () => {
@@ -416,8 +415,7 @@ describe('CachingLogViewer', () => {
416
415
  function getViewer() {
417
416
  const log = getTestTreeLog(testTree);
418
417
  const events = [];
419
- const viewer = new CachingLogViewer(log, simpleLogBaseView, [],
420
- /* expensiveValidation */ true, undefined, (args) => events.push(args));
418
+ const viewer = new CachingLogViewer(log, simpleLogBaseView, [], undefined, (args) => events.push(args));
421
419
  return { log, viewer, events };
422
420
  }
423
421
  function addInvalidEdit(log) {
@@ -473,7 +471,7 @@ describe('CachingLogViewer', () => {
473
471
  return edit;
474
472
  }
475
473
  function minimalLogViewer() {
476
- return new CachingLogViewer(new EditLog(), simpleLogBaseView, [], /* expensiveValidation */ true);
474
+ return new CachingLogViewer(new EditLog(), simpleLogBaseView, []);
477
475
  }
478
476
  it('tracks the earliest sequenced edit in the session', () => {
479
477
  const logViewer = minimalLogViewer();
@@ -1 +1 @@
1
- {"version":3,"file":"LogViewer.tests.js","sourceRoot":"","sources":["../../src/test/LogViewer.tests.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { expect } from 'chai';\nimport { v4 as uuidv4 } from 'uuid';\nimport { EditLog } from '../EditLog';\nimport {\n\tCachingLogViewer,\n\tEditStatusCallback,\n\tLogViewer,\n\tSequencedEditResult,\n\tSequencedEditResultCallback,\n} from '../LogViewer';\nimport { EditId } from '../Identifiers';\nimport { assert, copyPropertyIfDefined } from '../Common';\nimport { initialTree } from '../InitialTree';\nimport {\n\tChangeInternal,\n\tChangeNode,\n\tChangeTypeInternal,\n\tConstraintEffect,\n\tEdit,\n\tEditStatus,\n\tSetValueInternal,\n\tStablePlaceInternal,\n} from '../persisted-types';\nimport { areRevisionViewsSemanticallyEqual, newEdit } from '../EditUtilities';\nimport { NodeIdContext } from '../NodeIdUtilities';\nimport { RevisionView } from '../RevisionView';\nimport { TransactionInternal } from '../TransactionInternal';\nimport { Change, ChangeType, StableRange } from '../ChangeTypes';\nimport { expectDefined } from './utilities/TestCommon';\nimport { buildLeaf, TestTree } from './utilities/TestNode';\nimport { refreshTestTree, testTraitLabel } from './utilities/TestUtilities';\n\n/**\n * Creates an {@link EditLog} and accompanying {@link RevisionView} with pre-existing edits.\n *\n * @remarks Intended to be used with {@link getSimpleLogBaseView}\n * @param testTree - Test tree to work on\n * @param numEdits - The number of edits to make to the base tree\n */\nfunction getTestTreeLog(testTree: TestTree): EditLog<ChangeInternal> {\n\tconst log = new EditLog<ChangeInternal>();\n\tlog.addSequencedEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeaf(testTree.left.identifier)],\n\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t),\n\t\t{ sequenceNumber: 1, referenceSequenceNumber: 0 }\n\t);\n\tlog.addSequencedEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeaf(testTree.right.identifier)],\n\t\t\t\tStablePlaceInternal.atStartOf(testTree.right.traitLocation)\n\t\t\t)\n\t\t),\n\t\t{ sequenceNumber: 2, referenceSequenceNumber: 1 }\n\t);\n\n\treturn log;\n}\n\nfunction getLogWithNumEdits(nodeIdContext: NodeIdContext, numEdits: number): EditLog<ChangeInternal> {\n\tconst log = new EditLog<ChangeInternal>();\n\tfor (let i = 0; i < numEdits; i++) {\n\t\tlog.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[buildLeaf(nodeIdContext.generateNodeId())],\n\t\t\t\t\tStablePlaceInternal.atStartOf({\n\t\t\t\t\t\tlabel: testTraitLabel,\n\t\t\t\t\t\tparent: nodeIdContext.convertToNodeId(initialTree.identifier),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t),\n\t\t\t{\n\t\t\t\tsequenceNumber: i + 1,\n\t\t\t\treferenceSequenceNumber: i,\n\t\t\t}\n\t\t);\n\t}\n\n\treturn log;\n}\n\n/**\n * Get a base view for a log created with {@link getTestTreeLog}.\n * This can then be used to construct a {@link LogViewer} for that log.\n *\n * @param testTree - Test tree to work from\n */\nfunction getSimpleLogBaseView(testTree: TestTree): RevisionView {\n\tconst node: ChangeNode = { definition: testTree.definition, identifier: testTree.identifier, traits: {} };\n\tcopyPropertyIfDefined(testTree, node, 'payload');\n\treturn RevisionView.fromTree(node);\n}\n\nfunction getSimpleLogWithLocalEdits(testTree: TestTree): EditLog<ChangeInternal> {\n\tconst logWithLocalEdits = getTestTreeLog(testTree);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\treturn logWithLocalEdits;\n}\n\nfunction getViewsForLog(log: EditLog<ChangeInternal>, baseView: RevisionView): RevisionView[] {\n\tconst views: RevisionView[] = [baseView];\n\tfor (let i = 0; i < log.length; i++) {\n\t\tconst edit = log.getEditInSessionAtIndex(i);\n\t\tconst result = TransactionInternal.factory(views[i]).applyChanges(edit.changes).close();\n\t\tif (result.status === EditStatus.Applied) {\n\t\t\tviews.push(result.after);\n\t\t} else {\n\t\t\texpect.fail('edit failed to apply');\n\t\t}\n\t}\n\treturn views;\n}\n\nfunction runLogViewerCorrectnessTests(\n\tviewerCreator: (log: EditLog<ChangeInternal>, baseView: RevisionView) => LogViewer\n): Mocha.Suite {\n\treturn describe('LogViewer', () => {\n\t\tlet simpleLog: EditLog<ChangeInternal>;\n\t\tlet simpleLogBaseView: RevisionView;\n\t\tlet simpleLogInitialView: RevisionView;\n\t\tconst testTree = refreshTestTree(undefined, (t) => {\n\t\t\tsimpleLogBaseView = getSimpleLogBaseView(t);\n\t\t\tsimpleLog = getTestTreeLog(t);\n\t\t\tsimpleLogInitialView = t.view;\n\t\t});\n\n\t\tit('generates initialTree by default for the 0th revision', () => {\n\t\t\tconst viewer = viewerCreator(new EditLog(), simpleLogBaseView);\n\t\t\tconst headView = viewer.getRevisionViewInSession(0);\n\t\t\texpect(headView.equals(expectDefined(RevisionView.fromTree(initialTree, testTree))));\n\t\t});\n\n\t\tit('can be constructed from a non-empty EditLog', () => {\n\t\t\tconst viewer = viewerCreator(simpleLog, simpleLogBaseView);\n\t\t\tconst headView = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\t\texpect(areRevisionViewsSemanticallyEqual(headView, testTree, simpleLogInitialView, testTree));\n\t\t\texpect(headView.equals(simpleLogInitialView)).to.be.true;\n\t\t});\n\n\t\tit('can generate all revision views for an EditLog', () => {\n\t\t\tconst baseView = expectDefined(RevisionView.fromTree(initialTree, testTree));\n\t\t\tconst numNodes = 10;\n\t\t\tconst viewer = viewerCreator(getLogWithNumEdits(testTree, numNodes), baseView);\n\t\t\tconst initialRevision = viewer.getRevisionViewInSession(0);\n\t\t\texpect(initialRevision.equals(baseView)).to.be.true;\n\t\t\texpect(initialRevision.size).to.equal(1);\n\t\t\tconst oneNodeView = viewer.getRevisionViewInSession(1);\n\t\t\tconst testTrait = {\n\t\t\t\tlabel: testTraitLabel,\n\t\t\t\tparent: testTree.convertToNodeId(initialTree.identifier),\n\t\t\t};\n\t\t\texpect(oneNodeView.getTrait(testTrait).length).to.equal(1);\n\t\t\tconst twoNodeView = viewer.getRevisionViewInSession(2);\n\t\t\texpect(twoNodeView.getTrait(testTrait).length).to.equal(2);\n\t\t\tconst finalView = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\t\texpect(finalView.getTrait(testTrait).length).to.equal(numNodes);\n\t\t});\n\n\t\tit('produces correct revision views when the log is mutated', () => {\n\t\t\tconst mutableLog = new EditLog<ChangeInternal>();\n\t\t\tconst viewer = viewerCreator(mutableLog, simpleLogBaseView);\n\t\t\tconst viewsForLog = getViewsForLog(simpleLog, simpleLogBaseView);\n\t\t\t// This test takes an empty log (A) and a log with edits in it (B), and adds the edits from B to A.\n\t\t\t// After each addition, the test code will iterate from [0, length_of_A] and get a view for each revision via LogViewer\n\t\t\t// and assert that none of the views differ from those created via pure Transaction APIs.\n\t\t\tfor (let i = 0; i <= simpleLog.length; i++) {\n\t\t\t\tfor (let j = 0; j <= mutableLog.length; j++) {\n\t\t\t\t\tconst viewerView = viewer.getRevisionViewInSession(j);\n\t\t\t\t\texpect(viewerView.equals(viewsForLog[j])).to.be.true;\n\t\t\t\t}\n\t\t\t\t// Revisions are from [0, simpleLog.length], edits are at indices [0, simpleLog.length)\n\t\t\t\tif (i < simpleLog.length) {\n\t\t\t\t\tconst edit = simpleLog.getEditInSessionAtIndex(i);\n\t\t\t\t\tmutableLog.addSequencedEdit(edit, { sequenceNumber: i + 1, referenceSequenceNumber: i });\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tit('produces correct revision views when local edits are shifted in the log due to sequenced edits being added', () => {\n\t\t\tfunction getViewsFromViewer(viewer: LogViewer, lastRevision: number): RevisionView[] {\n\t\t\t\tconst views: RevisionView[] = [];\n\t\t\t\tfor (let i = 0; i <= lastRevision; i++) {\n\t\t\t\t\tviews.push(viewer.getRevisionViewInSession(i));\n\t\t\t\t}\n\t\t\t\treturn views;\n\t\t\t}\n\n\t\t\tfunction expectViewsAreEqual(log: EditLog<ChangeInternal>, viewer: LogViewer): void {\n\t\t\t\tconst viewsForLog = getViewsForLog(log, simpleLogBaseView);\n\t\t\t\tconst viewsForViewer = getViewsFromViewer(viewer, log.length);\n\t\t\t\texpect(viewsForLog.length).to.equal(viewsForViewer.length);\n\t\t\t\tfor (let i = 0; i < viewsForLog.length; i++) {\n\t\t\t\t\texpect(viewsForLog[i].equals(viewsForViewer[i])).to.be.true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\t\tconst viewer = viewerCreator(logWithLocalEdits, simpleLogBaseView);\n\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\n\t\t\tlet seqNumber = 1;\n\t\t\t// Sequence the existing local edits and ensure viewer generates the correct views\n\t\t\twhile (logWithLocalEdits.numberOfLocalEdits > 0) {\n\t\t\t\t// Add a remote sequenced edit\n\t\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\t\tnewEdit(\n\t\t\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.right.traitLocation)\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t\t);\n\t\t\t\t++seqNumber;\n\t\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\t\t\t\t// Sequence a local edit\n\t\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\t\tlogWithLocalEdits.getEditInSessionAtIndex(logWithLocalEdits.numberOfSequencedEdits),\n\t\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t\t);\n\t\t\t\t++seqNumber;\n\t\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\t\t\t}\n\t\t});\n\t});\n}\n\ndescribe('CachingLogViewer', () => {\n\t// TODO: Dedupe? shared hook for getting all of this stuff?\n\tlet simpleLog: EditLog<ChangeInternal>;\n\tlet simpleLogBaseView: RevisionView;\n\tlet simpleLogInitialView: RevisionView;\n\t// An arbitrary revision view which can be used to check to see if it gets used when provided as a cached value.\n\tlet arbitraryRevisionView: RevisionView;\n\tconst testTree = refreshTestTree(undefined, (t) => {\n\t\tsimpleLogBaseView = getSimpleLogBaseView(t);\n\t\tsimpleLog = getTestTreeLog(t);\n\t\tsimpleLogInitialView = t.view;\n\t\tarbitraryRevisionView = RevisionView.fromTree(t.buildLeaf(t.generateNodeId()));\n\t});\n\n\tfunction getCachingLogViewerAssumeAppliedEdits(\n\t\tlog: EditLog<ChangeInternal>,\n\t\tbaseView: RevisionView,\n\t\teditStatusCallback?: EditStatusCallback,\n\t\tsequencedEditResultCallback?: SequencedEditResultCallback,\n\t\tknownRevisions?: [number, RevisionView][]\n\t): CachingLogViewer {\n\t\treturn new CachingLogViewer(\n\t\t\tlog,\n\t\t\tbaseView,\n\t\t\tknownRevisions?.map((pair) => [pair[0], { view: pair[1], result: EditStatus.Applied }]),\n\t\t\t/* expensiveValidation */ true,\n\t\t\teditStatusCallback,\n\t\t\tsequencedEditResultCallback,\n\t\t\tlog.numberOfSequencedEdits\n\t\t);\n\t}\n\n\trunLogViewerCorrectnessTests(getCachingLogViewerAssumeAppliedEdits);\n\n\tit('detects non-integer revisions when setting revision views', async () => {\n\t\texpect(() => {\n\t\t\treturn getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, undefined, undefined, [\n\t\t\t\t[2.4, simpleLogInitialView],\n\t\t\t]);\n\t\t}).to.throw('revision must be an integer');\n\t});\n\n\tit('detects out-of-bounds revisions when setting revision views', async () => {\n\t\texpect(() => {\n\t\t\treturn getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, undefined, undefined, [\n\t\t\t\t[1000, simpleLogInitialView],\n\t\t\t]);\n\t\t}).to.throw('revision must correspond to the result of a SequencedEdit');\n\t});\n\n\tit('can be created with known revisions', async () => {\n\t\tconst views = getViewsForLog(simpleLog, simpleLogBaseView);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tsimpleLog,\n\t\t\tsimpleLogBaseView,\n\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\tArray.from(views.keys()).map((revision) => [revision, views[revision]])\n\t\t);\n\t\tfor (let i = simpleLog.length; i >= 0; i--) {\n\t\t\texpect(viewer.getRevisionViewInSession(i).equals(views[i])).to.be.true;\n\t\t}\n\t});\n\n\tasync function requestAllRevisionViews(viewer: CachingLogViewer, log: EditLog<ChangeInternal>): Promise<void> {\n\t\tfor (let i = 0; i <= log.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t}\n\n\tit('caches revision views for sequenced edits', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, () => editsProcessed++);\n\t\tassert(simpleLog.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\n\t\t// Ask for every view; no edit application should occur, since the views will be cached.\n\t\tfor (let i = 0; i <= simpleLog.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\t});\n\n\tit('caches edit results for sequenced edits', async () => {\n\t\t// Add an invalid edit\n\t\tsimpleLog.addSequencedEdit(\n\t\t\tnewEdit([\n\t\t\t\t{\n\t\t\t\t\ttype: ChangeTypeInternal.Constraint,\n\t\t\t\t\ttoConstrain: StableRange.only(testTree.left),\n\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\tlength: 0,\n\t\t\t\t},\n\t\t\t]),\n\t\t\t{ sequenceNumber: 3, referenceSequenceNumber: 2, minimumSequenceNumber: 2 }\n\t\t);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, () => editsProcessed++);\n\t\tassert(simpleLog.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\n\t\texpect((await viewer.getEditResult(0)).status).equals(undefined);\n\t\texpect((await viewer.getEditResult(1)).status).equals(EditStatus.Applied);\n\t\texpect((await viewer.getEditResult(2)).status).equals(EditStatus.Applied);\n\t\texpect((await viewer.getEditResult(3)).status).equals(EditStatus.Invalid);\n\n\t\texpect(viewer.getEditResultInSession(0).status).equals(undefined);\n\t\texpect(viewer.getEditResultInSession(1).status).equals(EditStatus.Applied);\n\t\texpect(viewer.getEditResultInSession(2).status).equals(EditStatus.Applied);\n\t\texpect(viewer.getEditResultInSession(3).status).equals(EditStatus.Invalid);\n\t});\n\n\tit('caches the highest revision', async () => {\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView);\n\t\texpect(viewer.highestRevisionCached()).to.be.false;\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(viewer.highestRevisionCached()).to.be.true;\n\t\tsimpleLog.addLocalEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t\tsimpleLog.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t),\n\t\t\t{\n\t\t\t\tsequenceNumber: 3,\n\t\t\t\treferenceSequenceNumber: 2,\n\t\t\t\tminimumSequenceNumber: 2,\n\t\t\t}\n\t\t);\n\t\texpect(viewer.highestRevisionCached()).to.be.false;\n\t});\n\n\tit('evicts least recently set cached revision views for sequenced edits', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst log = getLogWithNumEdits(testTree, CachingLogViewer.sequencedCacheSizeMax * 2);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlog,\n\t\t\texpectDefined(RevisionView.fromTree(initialTree, testTree)),\n\t\t\t() => editsProcessed++\n\t\t);\n\t\tviewer.setMinimumSequenceNumber(log.length + 1); // simulate all edits being subject to eviction\n\n\t\tawait requestAllRevisionViews(viewer, log);\n\t\texpect(editsProcessed).to.equal(log.length);\n\n\t\teditsProcessed = 0;\n\t\tfor (let i = CachingLogViewer.sequencedCacheSizeMax + 1; i <= log.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(0);\n\n\t\tawait viewer.getRevisionView(CachingLogViewer.sequencedCacheSizeMax);\n\t\texpect(editsProcessed).to.equal(CachingLogViewer.sequencedCacheSizeMax);\n\t});\n\n\tit('never evicts the revision view for the most recent sequenced edit', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst log = getLogWithNumEdits(testTree, CachingLogViewer.sequencedCacheSizeMax * 2);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlog,\n\t\t\texpectDefined(RevisionView.fromTree(initialTree, testTree)),\n\t\t\t() => editsProcessed++\n\t\t);\n\n\t\t// Simulate all clients being caught up.\n\t\tviewer.setMinimumSequenceNumber(log.numberOfSequencedEdits);\n\n\t\tawait requestAllRevisionViews(viewer, log);\n\t\texpect(editsProcessed).to.equal(log.length);\n\n\t\teditsProcessed = 0;\n\t\tfor (let i = 0; i <= CachingLogViewer.sequencedCacheSizeMax; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(CachingLogViewer.sequencedCacheSizeMax);\n\n\t\teditsProcessed = 0;\n\t\tawait viewer.getRevisionView(log.numberOfSequencedEdits);\n\t\texpect(editsProcessed).to.equal(0);\n\t});\n\n\tit('caches revision views for local revisions', async () => {\n\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlogWithLocalEdits,\n\t\t\tsimpleLogBaseView,\n\t\t\t() => editsProcessed++\n\t\t);\n\t\tassert(logWithLocalEdits.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, logWithLocalEdits);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.length);\n\n\t\t// Local edits should now be cached until next remote sequenced edit arrives\n\t\teditsProcessed = 0;\n\t\tfor (let i = logWithLocalEdits.numberOfSequencedEdits + 1; i <= logWithLocalEdits.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t\texpect(editsProcessed).to.equal(0);\n\t\t}\n\n\t\t// Add a new local edit, and request the latest view.\n\t\t// This should apply only a single edit, as the most recent HEAD should be cached.\n\t\teditsProcessed = 0;\n\t\tlogWithLocalEdits.addLocalEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t\tawait requestAllRevisionViews(viewer, logWithLocalEdits);\n\t\texpect(editsProcessed).to.equal(1);\n\n\t\teditsProcessed = 0;\n\t\tlet seqNumber = 1;\n\t\twhile (logWithLocalEdits.numberOfLocalEdits > 0) {\n\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\tlogWithLocalEdits.getEditInSessionAtIndex(logWithLocalEdits.numberOfSequencedEdits),\n\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t);\n\t\t\t++seqNumber;\n\t\t\tawait viewer.getRevisionView(logWithLocalEdits.numberOfSequencedEdits); // get the latest (just added) sequenced edit\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY); // get the last view, which is a local revision\n\t\t\texpect(editsProcessed).to.equal(0);\n\t\t}\n\t});\n\n\tit('invalidates cached revision views for local revisions when remote edits are received', () => {\n\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlogWithLocalEdits,\n\t\t\tsimpleLogBaseView,\n\t\t\t() => editsProcessed++\n\t\t);\n\n\t\t// Request twice, should only process edits once\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.length);\n\n\t\t// Remote edit arrives\n\t\teditsProcessed = 0;\n\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t),\n\t\t\t{ sequenceNumber: 3, referenceSequenceNumber: 2, minimumSequenceNumber: 2 }\n\t\t);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.numberOfLocalEdits + 1);\n\t});\n\n\tit('uses known editing result', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(edit, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([true]);\n\t\texpect(after).equal(arbitraryRevisionView);\n\t});\n\n\tit('ignores known editing if for wrong before revision view', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(edit, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore: arbitraryRevisionView,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\texpect(after).not.equal(arbitraryRevisionView);\n\t});\n\n\tit('ignores known editing if for wrong edit', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(newEdit([]), {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\texpect(after).not.equal(arbitraryRevisionView);\n\t});\n\n\tit('uses known editing result with multiple edits', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst edit1 = newEdit([]);\n\t\tconst edit2 = newEdit([]);\n\t\tconst edit3 = newEdit([]);\n\t\tlog.addLocalEdit(edit1);\n\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\tlog.addLocalEdit(edit2);\n\t\tviewer.setKnownEditingResult(edit2, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit2.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false, true]);\n\t\texpect(after).equal(arbitraryRevisionView);\n\t\tlog.addLocalEdit(edit3);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false, true, false]);\n\t});\n\n\tdescribe('Callbacks', () => {\n\t\tfunction getViewer(): {\n\t\t\tlog: EditLog<ChangeInternal>;\n\t\t\tviewer: CachingLogViewer;\n\t\t\tevents: SequencedEditResult[];\n\t\t} {\n\t\t\tconst log = getTestTreeLog(testTree);\n\t\t\tconst events: SequencedEditResult[] = [];\n\t\t\tconst viewer = new CachingLogViewer(\n\t\t\t\tlog,\n\t\t\t\tsimpleLogBaseView,\n\t\t\t\t[],\n\t\t\t\t/* expensiveValidation */ true,\n\t\t\t\tundefined,\n\t\t\t\t(args: SequencedEditResult) => events.push(args)\n\t\t\t);\n\t\t\treturn { log, viewer, events };\n\t\t}\n\n\t\tfunction addInvalidEdit(log: EditLog<ChangeInternal>): Edit<ChangeInternal> {\n\t\t\t// Add a local edit that will be invalid (inserts a node at a location that doesn't exist)\n\t\t\tconst edit = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\texpectDefined(\n\t\t\t\t\t\tStablePlaceInternal.atEndOf({\n\t\t\t\t\t\t\tlabel: testTraitLabel,\n\t\t\t\t\t\t\tparent: testTree.generateNodeId(),\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addLocalEdit(edit);\n\t\t\treturn edit;\n\t\t}\n\n\t\tit('processSequencedEditResult is called when a sequenced edit is applied', async () => {\n\t\t\tconst { log, events, viewer } = getViewer();\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\tevents.splice(0);\n\n\t\t\t// Non-sequenced edit should not trigger a call\n\t\t\tconst invalidEdit = addInvalidEdit(log);\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(0);\n\n\t\t\tlog.addSequencedEdit(invalidEdit, { sequenceNumber: 3, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(1);\n\t\t\texpect(events[0].edit.id).equals(invalidEdit.id);\n\t\t\texpect(events[0].wasLocal).equals(true);\n\t\t\texpect(events[0].result.status).equals(EditStatus.Invalid);\n\t\t\texpect(events[0].reconciliationPath.length).equals(0);\n\n\t\t\tconst validEdit1 = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addSequencedEdit(validEdit1, { sequenceNumber: 3, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(2);\n\t\t\texpect(events[1].edit.id).equals(validEdit1.id);\n\t\t\texpect(events[1].wasLocal).equals(false);\n\t\t\texpect(events[1].result.status).equals(EditStatus.Applied);\n\t\t\texpect(events[1].reconciliationPath.length).equals(0);\n\n\t\t\tconst validEdit2 = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addSequencedEdit(validEdit2, { sequenceNumber: 4, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(3);\n\t\t\texpect(events[2].edit.id).equals(validEdit2.id);\n\t\t\texpect(events[2].wasLocal).equals(false);\n\t\t\texpect(events[2].result.status).equals(EditStatus.Applied);\n\t\t\texpect(events[2].reconciliationPath.length).equals(1);\n\t\t});\n\t});\n\n\tdescribe('Sequencing', () => {\n\t\tfunction addFakeEdit(\n\t\t\tlogViewer: CachingLogViewer,\n\t\t\tsequenceNumber: number,\n\t\t\treferenceSequenceNumber?: number\n\t\t): Edit<unknown> {\n\t\t\tconst id = String(sequenceNumber ?? uuidv4()) as EditId;\n\t\t\tconst edit = { changes: [ChangeInternal.setPayload(simpleLogBaseView.root, id)], id };\n\t\t\tlogViewer.log.addSequencedEdit(edit, {\n\t\t\t\tsequenceNumber,\n\t\t\t\treferenceSequenceNumber: referenceSequenceNumber ?? sequenceNumber - 1,\n\t\t\t});\n\t\t\treturn edit;\n\t\t}\n\n\t\tfunction minimalLogViewer(): CachingLogViewer {\n\t\t\treturn new CachingLogViewer(new EditLog(), simpleLogBaseView, [], /* expensiveValidation */ true);\n\t\t}\n\n\t\tit('tracks the earliest sequenced edit in the session', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).undefined;\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).undefined;\n\n\t\t\t// First sequenced edit\n\t\t\tconst edit = addFakeEdit(logViewer, 123);\n\t\t\tconst expected = { edit, sequenceNumber: 123 };\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\n\t\t\t// Second sequenced edit\n\t\t\taddFakeEdit(logViewer, 456);\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\t\t});\n\n\t\tit('can provide edit results for sequenced edits', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\n\t\t\t// First sequenced edit\n\t\t\tconst edit1 = addFakeEdit(logViewer, 123);\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\t\t\tconst expected1 = {\n\t\t\t\tid: edit1.id,\n\t\t\t};\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(123)).contains(expected1);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(124)).contains(expected1);\n\n\t\t\t// Second sequenced edit\n\t\t\t// Note that this edit is given a greater sequence number than simply incrementing after edit 1.\n\t\t\t// This is deliberately done to simulate scenarios where a given DDS may not be sent all sequenced ops (because an other DDS\n\t\t\t// might be receiving them).\n\t\t\tconst edit2 = addFakeEdit(logViewer, 456);\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(123)).contains(expected1);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(124)).contains(expected1);\n\t\t\tconst expected2 = {\n\t\t\t\tid: edit2.id,\n\t\t\t};\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(456)).contains(expected2);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(457)).contains(expected2);\n\t\t});\n\n\t\tit('can provide the reconciliation path for an edit', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\n\t\t\tfunction expectReconciliationPath(edit: Edit<unknown>, path: Edit<unknown>[]) {\n\t\t\t\tconst actual = logViewer.reconciliationPathFromEdit(edit.id);\n\t\t\t\texpect(actual.length).equals(path.length);\n\t\t\t\tfor (let i = 0; i < path.length; ++i) {\n\t\t\t\t\texpect(actual[i].length).equals(1);\n\t\t\t\t\tconst change = actual[i][0].resolvedChange as SetValueInternal;\n\t\t\t\t\texpect(change.payload).equals(path[i].id);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Non-sequenced edit\n\t\t\tconst nonSeqEdit = { id: uuidv4() as EditId, changes: [] };\n\t\t\tlogViewer.log.addLocalEdit(nonSeqEdit);\n\t\t\texpectReconciliationPath(nonSeqEdit, []);\n\n\t\t\tconst edit1 = addFakeEdit(logViewer, 1001);\n\t\t\texpectReconciliationPath(edit1, []);\n\n\t\t\t// Note that this edit is given a greater sequence number than simply incrementing after edit 1.\n\t\t\t// This is deliberately done to simulate scenarios where a given DDS may not be sent all sequenced ops (because an other DDS\n\t\t\t// might be receiving them).\n\t\t\tconst edit2 = addFakeEdit(logViewer, 2001, 1001);\n\t\t\texpectReconciliationPath(edit2, []);\n\n\t\t\tconst edit3 = addFakeEdit(logViewer, 3001, 2000);\n\t\t\texpectReconciliationPath(edit3, [edit2]);\n\n\t\t\tconst edit4 = addFakeEdit(logViewer, 4001, 2500);\n\t\t\texpectReconciliationPath(edit4, [edit3]);\n\n\t\t\tconst edit5 = addFakeEdit(logViewer, 5001, 500);\n\t\t\texpectReconciliationPath(edit5, [edit1, edit2, edit3, edit4]);\n\t\t});\n\t});\n});\n"]}
1
+ {"version":3,"file":"LogViewer.tests.js","sourceRoot":"","sources":["../../src/test/LogViewer.tests.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { expect } from 'chai';\nimport { v4 as uuidv4 } from 'uuid';\nimport { EditLog } from '../EditLog';\nimport {\n\tCachingLogViewer,\n\tEditStatusCallback,\n\tLogViewer,\n\tSequencedEditResult,\n\tSequencedEditResultCallback,\n} from '../LogViewer';\nimport { EditId } from '../Identifiers';\nimport { assert, copyPropertyIfDefined } from '../Common';\nimport { initialTree } from '../InitialTree';\nimport {\n\tChangeInternal,\n\tChangeNode,\n\tChangeTypeInternal,\n\tConstraintEffect,\n\tEdit,\n\tEditStatus,\n\tSetValueInternal,\n\tStablePlaceInternal,\n} from '../persisted-types';\nimport { areRevisionViewsSemanticallyEqual, newEdit } from '../EditUtilities';\nimport { NodeIdContext } from '../NodeIdUtilities';\nimport { RevisionView } from '../RevisionView';\nimport { TransactionInternal } from '../TransactionInternal';\nimport { StableRange } from '../ChangeTypes';\nimport { expectDefined } from './utilities/TestCommon';\nimport { buildLeaf, TestTree } from './utilities/TestNode';\nimport { refreshTestTree, testTraitLabel } from './utilities/TestUtilities';\n\n/**\n * Creates an {@link EditLog} and accompanying {@link RevisionView} with pre-existing edits.\n *\n * @remarks Intended to be used with {@link getSimpleLogBaseView}\n * @param testTree - Test tree to work on\n * @param numEdits - The number of edits to make to the base tree\n */\nfunction getTestTreeLog(testTree: TestTree): EditLog<ChangeInternal> {\n\tconst log = new EditLog<ChangeInternal>();\n\tlog.addSequencedEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeaf(testTree.left.identifier)],\n\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t),\n\t\t{ sequenceNumber: 1, referenceSequenceNumber: 0 }\n\t);\n\tlog.addSequencedEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeaf(testTree.right.identifier)],\n\t\t\t\tStablePlaceInternal.atStartOf(testTree.right.traitLocation)\n\t\t\t)\n\t\t),\n\t\t{ sequenceNumber: 2, referenceSequenceNumber: 1 }\n\t);\n\n\treturn log;\n}\n\nfunction getLogWithNumEdits(nodeIdContext: NodeIdContext, numEdits: number): EditLog<ChangeInternal> {\n\tconst log = new EditLog<ChangeInternal>();\n\tfor (let i = 0; i < numEdits; i++) {\n\t\tlog.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[buildLeaf(nodeIdContext.generateNodeId())],\n\t\t\t\t\tStablePlaceInternal.atStartOf({\n\t\t\t\t\t\tlabel: testTraitLabel,\n\t\t\t\t\t\tparent: nodeIdContext.convertToNodeId(initialTree.identifier),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t),\n\t\t\t{\n\t\t\t\tsequenceNumber: i + 1,\n\t\t\t\treferenceSequenceNumber: i,\n\t\t\t}\n\t\t);\n\t}\n\n\treturn log;\n}\n\n/**\n * Get a base view for a log created with {@link getTestTreeLog}.\n * This can then be used to construct a {@link LogViewer} for that log.\n *\n * @param testTree - Test tree to work from\n */\nfunction getSimpleLogBaseView(testTree: TestTree): RevisionView {\n\tconst node: ChangeNode = { definition: testTree.definition, identifier: testTree.identifier, traits: {} };\n\tcopyPropertyIfDefined(testTree, node, 'payload');\n\treturn RevisionView.fromTree(node);\n}\n\nfunction getSimpleLogWithLocalEdits(testTree: TestTree): EditLog<ChangeInternal> {\n\tconst logWithLocalEdits = getTestTreeLog(testTree);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\tlogWithLocalEdits.addLocalEdit(\n\t\tnewEdit(\n\t\t\tChangeInternal.insertTree(\n\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\tStablePlaceInternal.atEndOf(testTree.left.traitLocation)\n\t\t\t)\n\t\t)\n\t);\n\treturn logWithLocalEdits;\n}\n\nfunction getViewsForLog(log: EditLog<ChangeInternal>, baseView: RevisionView): RevisionView[] {\n\tconst views: RevisionView[] = [baseView];\n\tfor (let i = 0; i < log.length; i++) {\n\t\tconst edit = log.getEditInSessionAtIndex(i);\n\t\tconst result = TransactionInternal.factory(views[i]).applyChanges(edit.changes).close();\n\t\tif (result.status === EditStatus.Applied) {\n\t\t\tviews.push(result.after);\n\t\t} else {\n\t\t\texpect.fail('edit failed to apply');\n\t\t}\n\t}\n\treturn views;\n}\n\nfunction runLogViewerCorrectnessTests(\n\tviewerCreator: (log: EditLog<ChangeInternal>, baseView: RevisionView) => LogViewer\n): Mocha.Suite {\n\treturn describe('LogViewer', () => {\n\t\tlet simpleLog: EditLog<ChangeInternal>;\n\t\tlet simpleLogBaseView: RevisionView;\n\t\tlet simpleLogInitialView: RevisionView;\n\t\tconst testTree = refreshTestTree(undefined, (t) => {\n\t\t\tsimpleLogBaseView = getSimpleLogBaseView(t);\n\t\t\tsimpleLog = getTestTreeLog(t);\n\t\t\tsimpleLogInitialView = t.view;\n\t\t});\n\n\t\tit('generates initialTree by default for the 0th revision', () => {\n\t\t\tconst viewer = viewerCreator(new EditLog(), simpleLogBaseView);\n\t\t\tconst headView = viewer.getRevisionViewInSession(0);\n\t\t\texpect(headView.equals(expectDefined(RevisionView.fromTree(initialTree, testTree))));\n\t\t});\n\n\t\tit('can be constructed from a non-empty EditLog', () => {\n\t\t\tconst viewer = viewerCreator(simpleLog, simpleLogBaseView);\n\t\t\tconst headView = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\t\texpect(areRevisionViewsSemanticallyEqual(headView, testTree, simpleLogInitialView, testTree));\n\t\t\texpect(headView.equals(simpleLogInitialView)).to.be.true;\n\t\t});\n\n\t\tit('can generate all revision views for an EditLog', () => {\n\t\t\tconst baseView = expectDefined(RevisionView.fromTree(initialTree, testTree));\n\t\t\tconst numNodes = 10;\n\t\t\tconst viewer = viewerCreator(getLogWithNumEdits(testTree, numNodes), baseView);\n\t\t\tconst initialRevision = viewer.getRevisionViewInSession(0);\n\t\t\texpect(initialRevision.equals(baseView)).to.be.true;\n\t\t\texpect(initialRevision.size).to.equal(1);\n\t\t\tconst oneNodeView = viewer.getRevisionViewInSession(1);\n\t\t\tconst testTrait = {\n\t\t\t\tlabel: testTraitLabel,\n\t\t\t\tparent: testTree.convertToNodeId(initialTree.identifier),\n\t\t\t};\n\t\t\texpect(oneNodeView.getTrait(testTrait).length).to.equal(1);\n\t\t\tconst twoNodeView = viewer.getRevisionViewInSession(2);\n\t\t\texpect(twoNodeView.getTrait(testTrait).length).to.equal(2);\n\t\t\tconst finalView = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\t\texpect(finalView.getTrait(testTrait).length).to.equal(numNodes);\n\t\t});\n\n\t\tit('produces correct revision views when the log is mutated', () => {\n\t\t\tconst mutableLog = new EditLog<ChangeInternal>();\n\t\t\tconst viewer = viewerCreator(mutableLog, simpleLogBaseView);\n\t\t\tconst viewsForLog = getViewsForLog(simpleLog, simpleLogBaseView);\n\t\t\t// This test takes an empty log (A) and a log with edits in it (B), and adds the edits from B to A.\n\t\t\t// After each addition, the test code will iterate from [0, length_of_A] and get a view for each revision via LogViewer\n\t\t\t// and assert that none of the views differ from those created via pure Transaction APIs.\n\t\t\tfor (let i = 0; i <= simpleLog.length; i++) {\n\t\t\t\tfor (let j = 0; j <= mutableLog.length; j++) {\n\t\t\t\t\tconst viewerView = viewer.getRevisionViewInSession(j);\n\t\t\t\t\texpect(viewerView.equals(viewsForLog[j])).to.be.true;\n\t\t\t\t}\n\t\t\t\t// Revisions are from [0, simpleLog.length], edits are at indices [0, simpleLog.length)\n\t\t\t\tif (i < simpleLog.length) {\n\t\t\t\t\tconst edit = simpleLog.getEditInSessionAtIndex(i);\n\t\t\t\t\tmutableLog.addSequencedEdit(edit, { sequenceNumber: i + 1, referenceSequenceNumber: i });\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tit('produces correct revision views when local edits are shifted in the log due to sequenced edits being added', () => {\n\t\t\tfunction getViewsFromViewer(viewer: LogViewer, lastRevision: number): RevisionView[] {\n\t\t\t\tconst views: RevisionView[] = [];\n\t\t\t\tfor (let i = 0; i <= lastRevision; i++) {\n\t\t\t\t\tviews.push(viewer.getRevisionViewInSession(i));\n\t\t\t\t}\n\t\t\t\treturn views;\n\t\t\t}\n\n\t\t\tfunction expectViewsAreEqual(log: EditLog<ChangeInternal>, viewer: LogViewer): void {\n\t\t\t\tconst viewsForLog = getViewsForLog(log, simpleLogBaseView);\n\t\t\t\tconst viewsForViewer = getViewsFromViewer(viewer, log.length);\n\t\t\t\texpect(viewsForLog.length).to.equal(viewsForViewer.length);\n\t\t\t\tfor (let i = 0; i < viewsForLog.length; i++) {\n\t\t\t\t\texpect(viewsForLog[i].equals(viewsForViewer[i])).to.be.true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\t\tconst viewer = viewerCreator(logWithLocalEdits, simpleLogBaseView);\n\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\n\t\t\tlet seqNumber = 1;\n\t\t\t// Sequence the existing local edits and ensure viewer generates the correct views\n\t\t\twhile (logWithLocalEdits.numberOfLocalEdits > 0) {\n\t\t\t\t// Add a remote sequenced edit\n\t\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\t\tnewEdit(\n\t\t\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.right.traitLocation)\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t\t);\n\t\t\t\t++seqNumber;\n\t\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\t\t\t\t// Sequence a local edit\n\t\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\t\tlogWithLocalEdits.getEditInSessionAtIndex(logWithLocalEdits.numberOfSequencedEdits),\n\t\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t\t);\n\t\t\t\t++seqNumber;\n\t\t\t\texpectViewsAreEqual(logWithLocalEdits, viewer);\n\t\t\t}\n\t\t});\n\t});\n}\n\ndescribe('CachingLogViewer', () => {\n\t// TODO: Dedupe? shared hook for getting all of this stuff?\n\tlet simpleLog: EditLog<ChangeInternal>;\n\tlet simpleLogBaseView: RevisionView;\n\tlet simpleLogInitialView: RevisionView;\n\t// An arbitrary revision view which can be used to check to see if it gets used when provided as a cached value.\n\tlet arbitraryRevisionView: RevisionView;\n\tconst testTree = refreshTestTree(undefined, (t) => {\n\t\tsimpleLogBaseView = getSimpleLogBaseView(t);\n\t\tsimpleLog = getTestTreeLog(t);\n\t\tsimpleLogInitialView = t.view;\n\t\tarbitraryRevisionView = RevisionView.fromTree(t.buildLeaf(t.generateNodeId()));\n\t});\n\n\tfunction getCachingLogViewerAssumeAppliedEdits(\n\t\tlog: EditLog<ChangeInternal>,\n\t\tbaseView: RevisionView,\n\t\teditStatusCallback?: EditStatusCallback,\n\t\tsequencedEditResultCallback?: SequencedEditResultCallback,\n\t\tknownRevisions?: [number, RevisionView][]\n\t): CachingLogViewer {\n\t\treturn new CachingLogViewer(\n\t\t\tlog,\n\t\t\tbaseView,\n\t\t\tknownRevisions?.map((pair) => [pair[0], { view: pair[1], result: EditStatus.Applied }]),\n\t\t\teditStatusCallback,\n\t\t\tsequencedEditResultCallback,\n\t\t\tlog.numberOfSequencedEdits\n\t\t);\n\t}\n\n\trunLogViewerCorrectnessTests(getCachingLogViewerAssumeAppliedEdits);\n\n\tit('detects non-integer revisions when setting revision views', async () => {\n\t\texpect(() => {\n\t\t\treturn getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, undefined, undefined, [\n\t\t\t\t[2.4, simpleLogInitialView],\n\t\t\t]);\n\t\t}).to.throw('revision must be an integer');\n\t});\n\n\tit('detects out-of-bounds revisions when setting revision views', async () => {\n\t\texpect(() => {\n\t\t\treturn getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, undefined, undefined, [\n\t\t\t\t[1000, simpleLogInitialView],\n\t\t\t]);\n\t\t}).to.throw('revision must correspond to the result of a SequencedEdit');\n\t});\n\n\tit('can be created with known revisions', async () => {\n\t\tconst views = getViewsForLog(simpleLog, simpleLogBaseView);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tsimpleLog,\n\t\t\tsimpleLogBaseView,\n\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\tArray.from(views.keys()).map((revision) => [revision, views[revision]])\n\t\t);\n\t\tfor (let i = simpleLog.length; i >= 0; i--) {\n\t\t\texpect(viewer.getRevisionViewInSession(i).equals(views[i])).to.be.true;\n\t\t}\n\t});\n\n\tasync function requestAllRevisionViews(viewer: CachingLogViewer, log: EditLog<ChangeInternal>): Promise<void> {\n\t\tfor (let i = 0; i <= log.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t}\n\n\tit('caches revision views for sequenced edits', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, () => editsProcessed++);\n\t\tassert(simpleLog.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\n\t\t// Ask for every view; no edit application should occur, since the views will be cached.\n\t\tfor (let i = 0; i <= simpleLog.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\t});\n\n\tit('caches edit results for sequenced edits', async () => {\n\t\t// Add an invalid edit\n\t\tsimpleLog.addSequencedEdit(\n\t\t\tnewEdit([\n\t\t\t\t{\n\t\t\t\t\ttype: ChangeTypeInternal.Constraint,\n\t\t\t\t\ttoConstrain: StableRange.only(testTree.left),\n\t\t\t\t\teffect: ConstraintEffect.InvalidAndDiscard,\n\t\t\t\t\tlength: 0,\n\t\t\t\t},\n\t\t\t]),\n\t\t\t{ sequenceNumber: 3, referenceSequenceNumber: 2, minimumSequenceNumber: 2 }\n\t\t);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView, () => editsProcessed++);\n\t\tassert(simpleLog.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(editsProcessed).to.equal(simpleLog.length);\n\n\t\texpect((await viewer.getEditResult(0)).status).equals(undefined);\n\t\texpect((await viewer.getEditResult(1)).status).equals(EditStatus.Applied);\n\t\texpect((await viewer.getEditResult(2)).status).equals(EditStatus.Applied);\n\t\texpect((await viewer.getEditResult(3)).status).equals(EditStatus.Invalid);\n\n\t\texpect(viewer.getEditResultInSession(0).status).equals(undefined);\n\t\texpect(viewer.getEditResultInSession(1).status).equals(EditStatus.Applied);\n\t\texpect(viewer.getEditResultInSession(2).status).equals(EditStatus.Applied);\n\t\texpect(viewer.getEditResultInSession(3).status).equals(EditStatus.Invalid);\n\t});\n\n\tit('caches the highest revision', async () => {\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(simpleLog, simpleLogBaseView);\n\t\texpect(viewer.highestRevisionCached()).to.be.false;\n\t\tawait requestAllRevisionViews(viewer, simpleLog);\n\t\texpect(viewer.highestRevisionCached()).to.be.true;\n\t\tsimpleLog.addLocalEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t\tsimpleLog.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t),\n\t\t\t{\n\t\t\t\tsequenceNumber: 3,\n\t\t\t\treferenceSequenceNumber: 2,\n\t\t\t\tminimumSequenceNumber: 2,\n\t\t\t}\n\t\t);\n\t\texpect(viewer.highestRevisionCached()).to.be.false;\n\t});\n\n\tit('evicts least recently set cached revision views for sequenced edits', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst log = getLogWithNumEdits(testTree, CachingLogViewer.sequencedCacheSizeMax * 2);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlog,\n\t\t\texpectDefined(RevisionView.fromTree(initialTree, testTree)),\n\t\t\t() => editsProcessed++\n\t\t);\n\t\tviewer.setMinimumSequenceNumber(log.length + 1); // simulate all edits being subject to eviction\n\n\t\tawait requestAllRevisionViews(viewer, log);\n\t\texpect(editsProcessed).to.equal(log.length);\n\n\t\teditsProcessed = 0;\n\t\tfor (let i = CachingLogViewer.sequencedCacheSizeMax + 1; i <= log.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(0);\n\n\t\tawait viewer.getRevisionView(CachingLogViewer.sequencedCacheSizeMax);\n\t\texpect(editsProcessed).to.equal(CachingLogViewer.sequencedCacheSizeMax);\n\t});\n\n\tit('never evicts the revision view for the most recent sequenced edit', async () => {\n\t\tlet editsProcessed = 0;\n\t\tconst log = getLogWithNumEdits(testTree, CachingLogViewer.sequencedCacheSizeMax * 2);\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlog,\n\t\t\texpectDefined(RevisionView.fromTree(initialTree, testTree)),\n\t\t\t() => editsProcessed++\n\t\t);\n\n\t\t// Simulate all clients being caught up.\n\t\tviewer.setMinimumSequenceNumber(log.numberOfSequencedEdits);\n\n\t\tawait requestAllRevisionViews(viewer, log);\n\t\texpect(editsProcessed).to.equal(log.length);\n\n\t\teditsProcessed = 0;\n\t\tfor (let i = 0; i <= CachingLogViewer.sequencedCacheSizeMax; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t}\n\t\texpect(editsProcessed).to.equal(CachingLogViewer.sequencedCacheSizeMax);\n\n\t\teditsProcessed = 0;\n\t\tawait viewer.getRevisionView(log.numberOfSequencedEdits);\n\t\texpect(editsProcessed).to.equal(0);\n\t});\n\n\tit('caches revision views for local revisions', async () => {\n\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlogWithLocalEdits,\n\t\t\tsimpleLogBaseView,\n\t\t\t() => editsProcessed++\n\t\t);\n\t\tassert(logWithLocalEdits.length < CachingLogViewer.sequencedCacheSizeMax);\n\n\t\tawait requestAllRevisionViews(viewer, logWithLocalEdits);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.length);\n\n\t\t// Local edits should now be cached until next remote sequenced edit arrives\n\t\teditsProcessed = 0;\n\t\tfor (let i = logWithLocalEdits.numberOfSequencedEdits + 1; i <= logWithLocalEdits.length; i++) {\n\t\t\tawait viewer.getRevisionView(i);\n\t\t\texpect(editsProcessed).to.equal(0);\n\t\t}\n\n\t\t// Add a new local edit, and request the latest view.\n\t\t// This should apply only a single edit, as the most recent HEAD should be cached.\n\t\teditsProcessed = 0;\n\t\tlogWithLocalEdits.addLocalEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t\tawait requestAllRevisionViews(viewer, logWithLocalEdits);\n\t\texpect(editsProcessed).to.equal(1);\n\n\t\teditsProcessed = 0;\n\t\tlet seqNumber = 1;\n\t\twhile (logWithLocalEdits.numberOfLocalEdits > 0) {\n\t\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\t\tlogWithLocalEdits.getEditInSessionAtIndex(logWithLocalEdits.numberOfSequencedEdits),\n\t\t\t\t{ sequenceNumber: seqNumber, referenceSequenceNumber: seqNumber - 1 }\n\t\t\t);\n\t\t\t++seqNumber;\n\t\t\tawait viewer.getRevisionView(logWithLocalEdits.numberOfSequencedEdits); // get the latest (just added) sequenced edit\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY); // get the last view, which is a local revision\n\t\t\texpect(editsProcessed).to.equal(0);\n\t\t}\n\t});\n\n\tit('invalidates cached revision views for local revisions when remote edits are received', () => {\n\t\tconst logWithLocalEdits = getSimpleLogWithLocalEdits(testTree);\n\t\tlet editsProcessed = 0;\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(\n\t\t\tlogWithLocalEdits,\n\t\t\tsimpleLogBaseView,\n\t\t\t() => editsProcessed++\n\t\t);\n\n\t\t// Request twice, should only process edits once\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.length);\n\n\t\t// Remote edit arrives\n\t\teditsProcessed = 0;\n\t\tlogWithLocalEdits.addSequencedEdit(\n\t\t\tnewEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atEndOf(testTree.right.traitLocation)\n\t\t\t\t)\n\t\t\t),\n\t\t\t{ sequenceNumber: 3, referenceSequenceNumber: 2, minimumSequenceNumber: 2 }\n\t\t);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).to.equal(logWithLocalEdits.numberOfLocalEdits + 1);\n\t});\n\n\tit('uses known editing result', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(edit, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([true]);\n\t\texpect(after).equal(arbitraryRevisionView);\n\t});\n\n\tit('ignores known editing if for wrong before revision view', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(edit, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore: arbitraryRevisionView,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\texpect(after).not.equal(arbitraryRevisionView);\n\t});\n\n\tit('ignores known editing if for wrong edit', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\tconst edit = newEdit([]);\n\t\tlog.addLocalEdit(edit);\n\t\tviewer.setKnownEditingResult(newEdit([]), {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\texpect(after).not.equal(arbitraryRevisionView);\n\t});\n\n\tit('uses known editing result with multiple edits', () => {\n\t\tconst log = new EditLog<ChangeInternal>();\n\t\tconst editsProcessed: boolean[] = [];\n\t\tconst viewer = getCachingLogViewerAssumeAppliedEdits(log, simpleLogBaseView, (_, _2, wasCached) =>\n\t\t\teditsProcessed.push(wasCached)\n\t\t);\n\t\tconst edit1 = newEdit([]);\n\t\tconst edit2 = newEdit([]);\n\t\tconst edit3 = newEdit([]);\n\t\tlog.addLocalEdit(edit1);\n\n\t\tconst before = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false]);\n\t\tlog.addLocalEdit(edit2);\n\t\tviewer.setKnownEditingResult(edit2, {\n\t\t\tstatus: EditStatus.Applied,\n\t\t\tchanges: edit2.changes,\n\t\t\tbefore,\n\t\t\tafter: arbitraryRevisionView,\n\t\t\tsteps: [],\n\t\t});\n\t\tconst after = viewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false, true]);\n\t\texpect(after).equal(arbitraryRevisionView);\n\t\tlog.addLocalEdit(edit3);\n\t\tviewer.getRevisionViewInSession(Number.POSITIVE_INFINITY);\n\t\texpect(editsProcessed).deep.equal([false, true, false]);\n\t});\n\n\tdescribe('Callbacks', () => {\n\t\tfunction getViewer(): {\n\t\t\tlog: EditLog<ChangeInternal>;\n\t\t\tviewer: CachingLogViewer;\n\t\t\tevents: SequencedEditResult[];\n\t\t} {\n\t\t\tconst log = getTestTreeLog(testTree);\n\t\t\tconst events: SequencedEditResult[] = [];\n\t\t\tconst viewer = new CachingLogViewer(log, simpleLogBaseView, [], undefined, (args: SequencedEditResult) =>\n\t\t\t\tevents.push(args)\n\t\t\t);\n\t\t\treturn { log, viewer, events };\n\t\t}\n\n\t\tfunction addInvalidEdit(log: EditLog<ChangeInternal>): Edit<ChangeInternal> {\n\t\t\t// Add a local edit that will be invalid (inserts a node at a location that doesn't exist)\n\t\t\tconst edit = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\texpectDefined(\n\t\t\t\t\t\tStablePlaceInternal.atEndOf({\n\t\t\t\t\t\t\tlabel: testTraitLabel,\n\t\t\t\t\t\t\tparent: testTree.generateNodeId(),\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addLocalEdit(edit);\n\t\t\treturn edit;\n\t\t}\n\n\t\tit('processSequencedEditResult is called when a sequenced edit is applied', async () => {\n\t\t\tconst { log, events, viewer } = getViewer();\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\tevents.splice(0);\n\n\t\t\t// Non-sequenced edit should not trigger a call\n\t\t\tconst invalidEdit = addInvalidEdit(log);\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(0);\n\n\t\t\tlog.addSequencedEdit(invalidEdit, { sequenceNumber: 3, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(1);\n\t\t\texpect(events[0].edit.id).equals(invalidEdit.id);\n\t\t\texpect(events[0].wasLocal).equals(true);\n\t\t\texpect(events[0].result.status).equals(EditStatus.Invalid);\n\t\t\texpect(events[0].reconciliationPath.length).equals(0);\n\n\t\t\tconst validEdit1 = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addSequencedEdit(validEdit1, { sequenceNumber: 3, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(2);\n\t\t\texpect(events[1].edit.id).equals(validEdit1.id);\n\t\t\texpect(events[1].wasLocal).equals(false);\n\t\t\texpect(events[1].result.status).equals(EditStatus.Applied);\n\t\t\texpect(events[1].reconciliationPath.length).equals(0);\n\n\t\t\tconst validEdit2 = newEdit(\n\t\t\t\tChangeInternal.insertTree(\n\t\t\t\t\t[testTree.buildLeafInternal()],\n\t\t\t\t\tStablePlaceInternal.atStartOf(testTree.left.traitLocation)\n\t\t\t\t)\n\t\t\t);\n\t\t\tlog.addSequencedEdit(validEdit2, { sequenceNumber: 4, referenceSequenceNumber: 2 });\n\t\t\tawait viewer.getRevisionView(Number.POSITIVE_INFINITY);\n\t\t\texpect(events.length).equals(3);\n\t\t\texpect(events[2].edit.id).equals(validEdit2.id);\n\t\t\texpect(events[2].wasLocal).equals(false);\n\t\t\texpect(events[2].result.status).equals(EditStatus.Applied);\n\t\t\texpect(events[2].reconciliationPath.length).equals(1);\n\t\t});\n\t});\n\n\tdescribe('Sequencing', () => {\n\t\tfunction addFakeEdit(\n\t\t\tlogViewer: CachingLogViewer,\n\t\t\tsequenceNumber: number,\n\t\t\treferenceSequenceNumber?: number\n\t\t): Edit<unknown> {\n\t\t\tconst id = String(sequenceNumber ?? uuidv4()) as EditId;\n\t\t\tconst edit = { changes: [ChangeInternal.setPayload(simpleLogBaseView.root, id)], id };\n\t\t\tlogViewer.log.addSequencedEdit(edit, {\n\t\t\t\tsequenceNumber,\n\t\t\t\treferenceSequenceNumber: referenceSequenceNumber ?? sequenceNumber - 1,\n\t\t\t});\n\t\t\treturn edit;\n\t\t}\n\n\t\tfunction minimalLogViewer(): CachingLogViewer {\n\t\t\treturn new CachingLogViewer(new EditLog(), simpleLogBaseView, []);\n\t\t}\n\n\t\tit('tracks the earliest sequenced edit in the session', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).undefined;\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).undefined;\n\n\t\t\t// First sequenced edit\n\t\t\tconst edit = addFakeEdit(logViewer, 123);\n\t\t\tconst expected = { edit, sequenceNumber: 123 };\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\n\t\t\t// Second sequenced edit\n\t\t\taddFakeEdit(logViewer, 456);\n\t\t\texpect(logViewer.earliestSequencedEditInSession()).deep.equals(expected);\n\t\t});\n\n\t\tit('can provide edit results for sequenced edits', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\n\t\t\t// Non-sequenced edit\n\t\t\tlogViewer.log.addLocalEdit({ id: uuidv4() as EditId, changes: [] });\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\n\t\t\t// First sequenced edit\n\t\t\tconst edit1 = addFakeEdit(logViewer, 123);\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(42)).undefined;\n\t\t\tconst expected1 = {\n\t\t\t\tid: edit1.id,\n\t\t\t};\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(123)).contains(expected1);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(124)).contains(expected1);\n\n\t\t\t// Second sequenced edit\n\t\t\t// Note that this edit is given a greater sequence number than simply incrementing after edit 1.\n\t\t\t// This is deliberately done to simulate scenarios where a given DDS may not be sent all sequenced ops (because an other DDS\n\t\t\t// might be receiving them).\n\t\t\tconst edit2 = addFakeEdit(logViewer, 456);\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(123)).contains(expected1);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(124)).contains(expected1);\n\t\t\tconst expected2 = {\n\t\t\t\tid: edit2.id,\n\t\t\t};\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(456)).contains(expected2);\n\t\t\t// Check that when no such sequence number exists, the closest earlier edit is returned\n\t\t\texpect(logViewer.getEditResultFromSequenceNumber(457)).contains(expected2);\n\t\t});\n\n\t\tit('can provide the reconciliation path for an edit', () => {\n\t\t\tconst logViewer = minimalLogViewer();\n\n\t\t\tfunction expectReconciliationPath(edit: Edit<unknown>, path: Edit<unknown>[]) {\n\t\t\t\tconst actual = logViewer.reconciliationPathFromEdit(edit.id);\n\t\t\t\texpect(actual.length).equals(path.length);\n\t\t\t\tfor (let i = 0; i < path.length; ++i) {\n\t\t\t\t\texpect(actual[i].length).equals(1);\n\t\t\t\t\tconst change = actual[i][0].resolvedChange as SetValueInternal;\n\t\t\t\t\texpect(change.payload).equals(path[i].id);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Non-sequenced edit\n\t\t\tconst nonSeqEdit = { id: uuidv4() as EditId, changes: [] };\n\t\t\tlogViewer.log.addLocalEdit(nonSeqEdit);\n\t\t\texpectReconciliationPath(nonSeqEdit, []);\n\n\t\t\tconst edit1 = addFakeEdit(logViewer, 1001);\n\t\t\texpectReconciliationPath(edit1, []);\n\n\t\t\t// Note that this edit is given a greater sequence number than simply incrementing after edit 1.\n\t\t\t// This is deliberately done to simulate scenarios where a given DDS may not be sent all sequenced ops (because an other DDS\n\t\t\t// might be receiving them).\n\t\t\tconst edit2 = addFakeEdit(logViewer, 2001, 1001);\n\t\t\texpectReconciliationPath(edit2, []);\n\n\t\t\tconst edit3 = addFakeEdit(logViewer, 3001, 2000);\n\t\t\texpectReconciliationPath(edit3, [edit2]);\n\n\t\t\tconst edit4 = addFakeEdit(logViewer, 4001, 2500);\n\t\t\texpectReconciliationPath(edit4, [edit3]);\n\n\t\t\tconst edit5 = addFakeEdit(logViewer, 5001, 500);\n\t\t\texpectReconciliationPath(edit5, [edit1, edit2, edit3, edit4]);\n\t\t});\n\t});\n});\n"]}
@@ -3,9 +3,9 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { benchmark, BenchmarkType } from '@fluid-tools/benchmark';
6
- import { v4 } from 'uuid';
7
6
  import { defaultClusterCapacity } from '../id-compressor/IdCompressor';
8
- import { getPositiveDelta, incrementUuid, numericUuidFromStableId, stableIdFromNumericUuid, assertIsStableId, } from '../id-compressor/NumericUuid';
7
+ import { getPositiveDelta, incrementUuid, numericUuidFromStableId, stableIdFromNumericUuid, } from '../id-compressor/NumericUuid';
8
+ import { assertIsStableId, generateStableId } from '../UuidUtilities';
9
9
  describe('NumericUuid Perf', () => {
10
10
  const stableId = assertIsStableId('4779fbf2-2012-4510-b4f0-28a99a9f8946');
11
11
  const stableId2 = assertIsStableId('5ccf492c-6a82-438c-9129-d76467525912');
@@ -59,9 +59,9 @@ describe('NumericUuid Perf', () => {
59
59
  });
60
60
  benchmark({
61
61
  type,
62
- title: `generate a random v4 uuid string and remove separators`,
62
+ title: `generate a random v4 uuid string`,
63
63
  benchmarkFn: () => {
64
- v4();
64
+ generateStableId();
65
65
  },
66
66
  });
67
67
  });
@@ -1 +1 @@
1
- {"version":3,"file":"NumericUuid.perf.tests.js","sourceRoot":"","sources":["../../src/test/NumericUuid.perf.tests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,uBAAuB,EACvB,uBAAuB,EACvB,gBAAgB,GAChB,MAAM,8BAA8B,CAAC;AAGtC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IACjC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,sCAAsC,CAAC,CAAC;IAC1E,MAAM,SAAS,GAAG,gBAAgB,CAAC,sCAAsC,CAAC,CAAC;IAC3E,MAAM,SAAS,GAAG,gBAAgB,CAAC,sCAAsC,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,aAAa,CAAC,WAAW,CAAC;IACvC,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,qCAAqC;QAC5C,WAAW,EAAE,GAAG,EAAE;YACjB,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,GAAG,EAAE;YACjB,aAAa,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;QAC7C,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,2CAA2C;QAClD,WAAW,EAAE,GAAG,EAAE;YACjB,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,4CAA4C;QACnD,WAAW,EAAE,GAAG,EAAE;YACjB,uBAAuB,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,qDAAqD;QAC5D,WAAW,EAAE,GAAG,EAAE;YACjB,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,mDAAmD;QAC1D,WAAW,EAAE,GAAG,EAAE;YACjB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,wDAAwD;QAC/D,WAAW,EAAE,GAAG,EAAE;YACjB,EAAE,EAAgB,CAAC;QACpB,CAAC;KACD,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { benchmark, BenchmarkType } from '@fluid-tools/benchmark';\nimport { v4 } from 'uuid';\nimport { defaultClusterCapacity } from '../id-compressor/IdCompressor';\nimport {\n\tgetPositiveDelta,\n\tincrementUuid,\n\tnumericUuidFromStableId,\n\tstableIdFromNumericUuid,\n\tassertIsStableId,\n} from '../id-compressor/NumericUuid';\nimport { UuidString } from '../Identifiers';\n\ndescribe('NumericUuid Perf', () => {\n\tconst stableId = assertIsStableId('4779fbf2-2012-4510-b4f0-28a99a9f8946');\n\tconst stableId2 = assertIsStableId('5ccf492c-6a82-438c-9129-d76467525912');\n\tconst stableId3 = assertIsStableId('5ccf492c-6a82-438c-9129-d76467515912');\n\tconst uuid = numericUuidFromStableId(stableId);\n\tconst uuid2 = numericUuidFromStableId(stableId2);\n\tconst uuid3 = numericUuidFromStableId(stableId3);\n\tconst deltaMax = 2 ** 52 - 1;\n\tconst type = BenchmarkType.Measurement;\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `convert uuid string to numeric uuid`,\n\t\tbenchmarkFn: () => {\n\t\t\tnumericUuidFromStableId(stableId);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `incrementing a uuid`,\n\t\tbenchmarkFn: () => {\n\t\t\tincrementUuid(uuid, defaultClusterCapacity);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `convert a uuid string into a session uuid`,\n\t\tbenchmarkFn: () => {\n\t\t\tnumericUuidFromStableId(stableId);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `convert an numeric uuid into a uuid string`,\n\t\tbenchmarkFn: () => {\n\t\t\tstableIdFromNumericUuid(uuid);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `compute the delta between two distant numeric uuids`,\n\t\tbenchmarkFn: () => {\n\t\t\tgetPositiveDelta(uuid, uuid2, deltaMax);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `compute the delta between two close numeric uuids`,\n\t\tbenchmarkFn: () => {\n\t\t\tgetPositiveDelta(uuid2, uuid3, deltaMax);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `generate a random v4 uuid string and remove separators`,\n\t\tbenchmarkFn: () => {\n\t\t\tv4() as UuidString;\n\t\t},\n\t});\n});\n"]}
1
+ {"version":3,"file":"NumericUuid.perf.tests.js","sourceRoot":"","sources":["../../src/test/NumericUuid.perf.tests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,uBAAuB,EACvB,uBAAuB,GACvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEtE,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IACjC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,sCAAsC,CAAC,CAAC;IAC1E,MAAM,SAAS,GAAG,gBAAgB,CAAC,sCAAsC,CAAC,CAAC;IAC3E,MAAM,SAAS,GAAG,gBAAgB,CAAC,sCAAsC,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,aAAa,CAAC,WAAW,CAAC;IACvC,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,qCAAqC;QAC5C,WAAW,EAAE,GAAG,EAAE;YACjB,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,GAAG,EAAE;YACjB,aAAa,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC;QAC7C,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,2CAA2C;QAClD,WAAW,EAAE,GAAG,EAAE;YACjB,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,4CAA4C;QACnD,WAAW,EAAE,GAAG,EAAE;YACjB,uBAAuB,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,qDAAqD;QAC5D,WAAW,EAAE,GAAG,EAAE;YACjB,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,mDAAmD;QAC1D,WAAW,EAAE,GAAG,EAAE;YACjB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC;KACD,CAAC,CAAC;IACH,SAAS,CAAC;QACT,IAAI;QACJ,KAAK,EAAE,kCAAkC;QACzC,WAAW,EAAE,GAAG,EAAE;YACjB,gBAAgB,EAAE,CAAC;QACpB,CAAC;KACD,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { benchmark, BenchmarkType } from '@fluid-tools/benchmark';\nimport { defaultClusterCapacity } from '../id-compressor/IdCompressor';\nimport {\n\tgetPositiveDelta,\n\tincrementUuid,\n\tnumericUuidFromStableId,\n\tstableIdFromNumericUuid,\n} from '../id-compressor/NumericUuid';\nimport { assertIsStableId, generateStableId } from '../UuidUtilities';\n\ndescribe('NumericUuid Perf', () => {\n\tconst stableId = assertIsStableId('4779fbf2-2012-4510-b4f0-28a99a9f8946');\n\tconst stableId2 = assertIsStableId('5ccf492c-6a82-438c-9129-d76467525912');\n\tconst stableId3 = assertIsStableId('5ccf492c-6a82-438c-9129-d76467515912');\n\tconst uuid = numericUuidFromStableId(stableId);\n\tconst uuid2 = numericUuidFromStableId(stableId2);\n\tconst uuid3 = numericUuidFromStableId(stableId3);\n\tconst deltaMax = 2 ** 52 - 1;\n\tconst type = BenchmarkType.Measurement;\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `convert uuid string to numeric uuid`,\n\t\tbenchmarkFn: () => {\n\t\t\tnumericUuidFromStableId(stableId);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `incrementing a uuid`,\n\t\tbenchmarkFn: () => {\n\t\t\tincrementUuid(uuid, defaultClusterCapacity);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `convert a uuid string into a session uuid`,\n\t\tbenchmarkFn: () => {\n\t\t\tnumericUuidFromStableId(stableId);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `convert an numeric uuid into a uuid string`,\n\t\tbenchmarkFn: () => {\n\t\t\tstableIdFromNumericUuid(uuid);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `compute the delta between two distant numeric uuids`,\n\t\tbenchmarkFn: () => {\n\t\t\tgetPositiveDelta(uuid, uuid2, deltaMax);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `compute the delta between two close numeric uuids`,\n\t\tbenchmarkFn: () => {\n\t\t\tgetPositiveDelta(uuid2, uuid3, deltaMax);\n\t\t},\n\t});\n\tbenchmark({\n\t\ttype,\n\t\ttitle: `generate a random v4 uuid string`,\n\t\tbenchmarkFn: () => {\n\t\t\tgenerateStableId();\n\t\t},\n\t});\n});\n"]}
@@ -4,9 +4,10 @@
4
4
  */
5
5
  /* eslint-disable no-bitwise */
6
6
  import { expect } from 'chai';
7
- import Prando from 'prando';
7
+ import { makeRandom } from '@fluid-internal/stochastic-test-utils';
8
8
  import { compareStrings } from '../Common';
9
- import { numericUuidEquals, createSessionId, getPositiveDelta, incrementUuid, numericUuidFromStableId, stableIdFromNumericUuid, ensureSessionUuid, isStableId, assertIsStableId, } from '../id-compressor/NumericUuid';
9
+ import { numericUuidEquals, createSessionId, getPositiveDelta, incrementUuid, numericUuidFromStableId, stableIdFromNumericUuid, ensureSessionUuid, } from '../id-compressor/NumericUuid';
10
+ import { assertIsStableId, isStableId } from '../UuidUtilities';
10
11
  import { integerToStableId } from './utilities/IdCompressorTestUtilities';
11
12
  describe('NumericUuid', () => {
12
13
  it('can detect non-v4 variant 2 UUIDs', () => {
@@ -106,10 +107,10 @@ describe('NumericUuid', () => {
106
107
  integerToStableId(Number.MAX_SAFE_INTEGER - 1),
107
108
  ];
108
109
  describe('incrementing', () => {
109
- const prando = new Prando('incrementing');
110
+ const rand = makeRandom(0);
110
111
  const incrementAmounts = [
111
112
  ...[...new Array(53).keys()].map((n) => 2 ** n - 1),
112
- ...[...new Array(10).keys()].map((_) => prando.nextInt(0, Number.MAX_SAFE_INTEGER)),
113
+ ...[...new Array(10).keys()].map((_) => rand.integer(0, Number.MAX_SAFE_INTEGER)),
113
114
  ];
114
115
  stableIds.forEach((stableId) => {
115
116
  it(`can increment ${stableId}`, () => {
@@ -1 +1 @@
1
- {"version":3,"file":"NumericUuid.tests.js","sourceRoot":"","sources":["../../src/test/NumericUuid.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\n/* eslint-disable no-bitwise */\n\nimport { expect } from 'chai';\nimport Prando from 'prando';\nimport { compareStrings } from '../Common';\nimport {\n\tnumericUuidEquals,\n\tcreateSessionId,\n\tgetPositiveDelta,\n\tincrementUuid,\n\tnumericUuidFromStableId,\n\tstableIdFromNumericUuid,\n\tensureSessionUuid,\n\tisStableId,\n\tassertIsStableId,\n} from '../id-compressor/NumericUuid';\nimport { StableId } from '../Identifiers';\nimport { integerToStableId } from './utilities/IdCompressorTestUtilities';\n\ndescribe('NumericUuid', () => {\n\tit('can detect non-v4 variant 2 UUIDs', () => {\n\t\texpect(isStableId('00000000-0000-0000-0000-000000000000')).to.be.false;\n\t\texpect(isStableId('ffffffff-ffff-ffff-ffff-ffffffffffff')).to.be.false;\n\t\texpect(isStableId('8e8fec9a10ea4d158308ed35bc7f1e66')).to.be.false;\n\t\texpect(isStableId('8e8fec9a-10ea-4d15-8308-ed35bc7f1e66')).to.be.true;\n\t\t[...new Array(16).keys()]\n\t\t\t.map((n) => [n, n.toString(16)])\n\t\t\t.forEach(([n, char]) => {\n\t\t\t\tconst expectUuidVersion = expect(isStableId(`00000000-0000-${char}000-b000-000000000000`));\n\t\t\t\tif (char === '4') {\n\t\t\t\t\texpectUuidVersion.to.be.true;\n\t\t\t\t} else {\n\t\t\t\t\texpectUuidVersion.to.be.false;\n\t\t\t\t}\n\n\t\t\t\tconst expectUuidVariant = expect(isStableId(`00000000-0000-4000-${char}000-000000000000`));\n\t\t\t\tif (n >= 8 && n <= 11) {\n\t\t\t\t\texpectUuidVariant.to.be.true;\n\t\t\t\t} else {\n\t\t\t\t\texpectUuidVariant.to.be.false;\n\t\t\t\t}\n\t\t\t});\n\t});\n\n\tconst maxStableId = assertIsStableId('ffffffff-ffff-4fff-bfff-ffffffffffff');\n\n\tit('detects increment overflow', () => {\n\t\tconst uuid = numericUuidFromStableId(maxStableId);\n\t\texpect(() => stableIdFromNumericUuid(uuid, 1)).to.throw('Exceeded maximum numeric UUID');\n\t\texpect(() => stableIdFromNumericUuid(incrementUuid(uuid, 1))).to.throw('Exceeded maximum numeric UUID');\n\t\texpect(() => stableIdFromNumericUuid(uuid, 256)).to.throw('Exceeded maximum numeric UUID');\n\t\texpect(() => stableIdFromNumericUuid(incrementUuid(uuid, 256))).to.throw('Exceeded maximum numeric UUID');\n\t\texpect(() => stableIdFromNumericUuid(uuid, Number.MAX_SAFE_INTEGER)).to.throw('Exceeded maximum numeric UUID');\n\t\texpect(() => stableIdFromNumericUuid(incrementUuid(uuid, Number.MAX_SAFE_INTEGER))).to.throw(\n\t\t\t'Exceeded maximum numeric UUID'\n\t\t);\n\t});\n\n\tit('can rehydrate a valid session UUID', () => {\n\t\tconst uuid = assertIsStableId('44f95a8b-c52b-4828-a000-0000f0000003');\n\t\tconst sessionUuid = numericUuidFromStableId(uuid);\n\t\texpect(stableIdFromNumericUuid(sessionUuid)).to.equal(uuid);\n\t});\n\n\tit('can create valid session UUIDs', () => {\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tconst sessionId = createSessionId();\n\t\t\texpect(sessionId.length).to.equal(36);\n\t\t\texpect(() => {\n\t\t\t\tconst sessionNumericUuid = numericUuidFromStableId(sessionId);\n\t\t\t\texpect(stableIdFromNumericUuid(sessionNumericUuid)).to.equal(sessionId);\n\t\t\t}).to.not.throw();\n\t\t}\n\t});\n\n\tconst maxUuidBigint = bigIntFromStableId(maxStableId);\n\n\tit('ensures that session UUIDs are resistant to overflow', () => {\n\t\tconst uuid = assertIsStableId('ffffffff-ffff-4fff-bfff-ffffffffffff');\n\t\tfor (let i = 0; i < 128; i++) {\n\t\t\tconst ensuredUuid = ensureSessionUuid(uuid);\n\t\t\texpect(isStableId(ensuredUuid)).to.be.true;\n\t\t\tconst ensuredBigint = bigIntFromStableId(ensuredUuid);\n\t\t\texpect(maxUuidBigint - ensuredBigint > Number.MAX_SAFE_INTEGER).to.be.true;\n\t\t}\n\t});\n\n\tit('correctly adjusts session UUIDs that are in danger of overflow', () => {\n\t\tconst dangerous = [\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-bfff-ffffffffffff'),\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-bff0-000000000000'),\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-bf00-000000000000'),\n\t\t];\n\n\t\tconst safe = [\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-beff-ffffffffffff'),\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-bef0-000000000000'),\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-be00-000000000000'),\n\t\t];\n\n\t\tdangerous.forEach((stableId) => expect(ensureSessionUuid(stableId)).to.not.equal(stableId));\n\t\tsafe.forEach((stableId) => expect(ensureSessionUuid(stableId)).to.equal(stableId));\n\t});\n\n\tconst stableIds = [\n\t\tassertIsStableId('748540ca-b7c5-4c99-83ff-c1b8e02c09d6'),\n\t\tassertIsStableId('748540ca-b7c5-4c99-83ef-c1b8e02c09d6'),\n\t\tassertIsStableId('748540ca-b7c5-4c99-831f-c1b8e02c09d6'),\n\t\tassertIsStableId('0002c79e-b536-4776-b000-000266c252d5'),\n\t\tassertIsStableId('082533b9-6d05-4068-a008-fe2cc43543f7'),\n\t\tassertIsStableId('2c9fa1f8-48d5-4554-a466-000000000000'),\n\t\tassertIsStableId('2c9fa1f8-48d5-4000-a000-000000000000'),\n\t\tassertIsStableId('10000000-0000-4000-b000-000000000000'),\n\t\tassertIsStableId('10000000-0000-4000-b020-000000000000'), // 2^52\n\t\tassertIsStableId('10000000-0000-4000-b00f-ffffffffffff'),\n\t\tassertIsStableId('10000000-0000-4000-b040-000000000000'),\n\t\tassertIsStableId('f0000000-0000-4000-8000-000000000000'),\n\t\tassertIsStableId('efffffff-ffff-4fff-bfff-ffffffffffff'),\n\t\tintegerToStableId(0),\n\t\tintegerToStableId(1),\n\t\tintegerToStableId(77),\n\t\tintegerToStableId(1024),\n\t\tintegerToStableId(2 ** 32 - 1),\n\t\tintegerToStableId(2 ** 52 - 1),\n\t\tintegerToStableId(Number.MAX_SAFE_INTEGER),\n\t\tintegerToStableId(Number.MAX_SAFE_INTEGER - 1),\n\t];\n\n\tdescribe('incrementing', () => {\n\t\tconst prando = new Prando('incrementing');\n\t\tconst incrementAmounts = [\n\t\t\t...[...new Array(53).keys()].map((n) => 2 ** n - 1),\n\t\t\t...[...new Array(10).keys()].map((_) => prando.nextInt(0, Number.MAX_SAFE_INTEGER)),\n\t\t];\n\t\tstableIds.forEach((stableId) => {\n\t\t\tit(`can increment ${stableId}`, () => {\n\t\t\t\tconst uuid = numericUuidFromStableId(stableId);\n\n\t\t\t\tincrementAmounts.forEach((incrementAmount) => {\n\t\t\t\t\tconst bigintIncremented = bigIntFromStableId(stableId) + BigInt(incrementAmount);\n\t\t\t\t\tconst incremented = incrementUuid(uuid, incrementAmount);\n\t\t\t\t\tconst bigintStr = integerToStableId(bigintIncremented);\n\t\t\t\t\texpect(stableIdFromNumericUuid(incremented)).to.equal(bigintStr);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n\n\tit('delta calculation can calculate the integer delta between stable ids', () => {\n\t\tstableIds.forEach((stableIdA) => {\n\t\t\tconst uuidA = numericUuidFromStableId(stableIdA);\n\t\t\tconst bigintA = bigIntFromStableId(stableIdA);\n\t\t\tconst arbitraryMaxDelta = 2 ** 32 - 1;\n\t\t\tstableIds.forEach((stableIdB) => {\n\t\t\t\tconst uuidB = numericUuidFromStableId(stableIdB);\n\t\t\t\tconst bigintB = bigIntFromStableId(stableIdB);\n\t\t\t\tconst realDelta = bigintA - bigintB;\n\t\t\t\tconst numericDelta = getPositiveDelta(uuidA, uuidB, Number.MAX_SAFE_INTEGER);\n\t\t\t\tif (realDelta > Number.MAX_SAFE_INTEGER || realDelta < 0) {\n\t\t\t\t\texpect(numericDelta).to.equal(undefined);\n\t\t\t\t} else {\n\t\t\t\t\texpect(numericDelta).to.equal(Number(realDelta));\n\t\t\t\t}\n\t\t\t\tconst numericDeltaCapped = getPositiveDelta(uuidA, uuidB, arbitraryMaxDelta);\n\t\t\t\tif (realDelta >= 0 && realDelta <= arbitraryMaxDelta) {\n\t\t\t\t\texpect(numericDeltaCapped).to.equal(Number(realDelta));\n\t\t\t\t} else {\n\t\t\t\t\texpect(numericDeltaCapped).to.equal(undefined);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t});\n\n\tit('can round trip between stable ID and uuid', () => {\n\t\tstableIds.forEach((stableId) => {\n\t\t\tconst uuid = numericUuidFromStableId(stableId);\n\t\t\tconst roundTripped = stableIdFromNumericUuid(uuid);\n\t\t\texpect(stableId).to.equal(roundTripped);\n\t\t});\n\t});\n\n\tit('can compare numeric uuids', () => {\n\t\tstableIds.forEach((stableIdA) => {\n\t\t\tstableIds.forEach((stableIdB) => {\n\t\t\t\tconst numericA = numericUuidFromStableId(stableIdA);\n\t\t\t\tconst numericB = numericUuidFromStableId(stableIdB);\n\t\t\t\tconst comparedNumeric = numericUuidEquals(numericA, numericB);\n\t\t\t\tconst comparedStrings = compareStrings(stableIdA, stableIdB);\n\t\t\t\texpect(comparedNumeric).to.equal(comparedStrings === 0);\n\t\t\t});\n\t\t});\n\t});\n});\n\nfunction bigIntFromStableId(id: StableId): bigint {\n\tconst minimized = id.replace(/-/g, '');\n\t// UUID | xxxxxxxx-xxxx-Vxxx-vxxx-xxxxxxxxxxxx | The StableId passed to this function, shown here in standard UUID notation\n\t// nibbles | hhhhhhhh hhhh mmm llll llllllllllll | Whether or not each nibble is part of the \"high\", \"middle\" or \"low\" group below\n\t// bit count | 44444444-4444-0444-2444-444444444444 | The number of bits per nibble that are used to encode the number\n\n\t// Interpret numerically...\n\tconst highNibbles = BigInt(`0x${minimized.substr(0, 12)}`); // ...all nibbles above the version nibble,\n\tconst midNibbles = BigInt(`0x${minimized.substr(13, 3)}`); // the nibbles below the version nibble and above the variant nibble,\n\tconst lowNibbles = BigInt(`0x${minimized.substr(16, 16)}`); // and the variant nibble and all nibbles below\n\t// Count the number of bits that contribute to the number (i.e. are not reserved for version/variant) in...\n\tconst lowBitCount = BigInt(62); // ...the low nibbles\n\tconst midBitCount = BigInt(12); // and the mid nibbles\n\t// Shift the values of each region by the appropriate number of bits\n\tconst highNumber = highNibbles << (midBitCount + lowBitCount);\n\tconst midNumber = midNibbles << lowBitCount;\n\t// The low nibbles include the variant nibble because its two low bits are numerical (but its two upper bits are not). So mask them out:\n\tconst lowNumber = lowNibbles & BigInt('0x3fffffffffffffff'); // A nibble '0011' followed by 15 nibbles '1111'.\n\t// Now that high and mid are shifted correctly, the final number is their sum:\n\treturn highNumber + midNumber + lowNumber;\n}\n"]}
1
+ {"version":3,"file":"NumericUuid.tests.js","sourceRoot":"","sources":["../../src/test/NumericUuid.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\n/* eslint-disable no-bitwise */\n\nimport { expect } from 'chai';\nimport { makeRandom } from '@fluid-internal/stochastic-test-utils';\nimport { compareStrings } from '../Common';\nimport {\n\tnumericUuidEquals,\n\tcreateSessionId,\n\tgetPositiveDelta,\n\tincrementUuid,\n\tnumericUuidFromStableId,\n\tstableIdFromNumericUuid,\n\tensureSessionUuid,\n} from '../id-compressor/NumericUuid';\nimport { StableId } from '../Identifiers';\nimport { assertIsStableId, isStableId } from '../UuidUtilities';\nimport { integerToStableId } from './utilities/IdCompressorTestUtilities';\n\ndescribe('NumericUuid', () => {\n\tit('can detect non-v4 variant 2 UUIDs', () => {\n\t\texpect(isStableId('00000000-0000-0000-0000-000000000000')).to.be.false;\n\t\texpect(isStableId('ffffffff-ffff-ffff-ffff-ffffffffffff')).to.be.false;\n\t\texpect(isStableId('8e8fec9a10ea4d158308ed35bc7f1e66')).to.be.false;\n\t\texpect(isStableId('8e8fec9a-10ea-4d15-8308-ed35bc7f1e66')).to.be.true;\n\t\t[...new Array(16).keys()]\n\t\t\t.map((n) => [n, n.toString(16)])\n\t\t\t.forEach(([n, char]) => {\n\t\t\t\tconst expectUuidVersion = expect(isStableId(`00000000-0000-${char}000-b000-000000000000`));\n\t\t\t\tif (char === '4') {\n\t\t\t\t\texpectUuidVersion.to.be.true;\n\t\t\t\t} else {\n\t\t\t\t\texpectUuidVersion.to.be.false;\n\t\t\t\t}\n\n\t\t\t\tconst expectUuidVariant = expect(isStableId(`00000000-0000-4000-${char}000-000000000000`));\n\t\t\t\tif (n >= 8 && n <= 11) {\n\t\t\t\t\texpectUuidVariant.to.be.true;\n\t\t\t\t} else {\n\t\t\t\t\texpectUuidVariant.to.be.false;\n\t\t\t\t}\n\t\t\t});\n\t});\n\n\tconst maxStableId = assertIsStableId('ffffffff-ffff-4fff-bfff-ffffffffffff');\n\n\tit('detects increment overflow', () => {\n\t\tconst uuid = numericUuidFromStableId(maxStableId);\n\t\texpect(() => stableIdFromNumericUuid(uuid, 1)).to.throw('Exceeded maximum numeric UUID');\n\t\texpect(() => stableIdFromNumericUuid(incrementUuid(uuid, 1))).to.throw('Exceeded maximum numeric UUID');\n\t\texpect(() => stableIdFromNumericUuid(uuid, 256)).to.throw('Exceeded maximum numeric UUID');\n\t\texpect(() => stableIdFromNumericUuid(incrementUuid(uuid, 256))).to.throw('Exceeded maximum numeric UUID');\n\t\texpect(() => stableIdFromNumericUuid(uuid, Number.MAX_SAFE_INTEGER)).to.throw('Exceeded maximum numeric UUID');\n\t\texpect(() => stableIdFromNumericUuid(incrementUuid(uuid, Number.MAX_SAFE_INTEGER))).to.throw(\n\t\t\t'Exceeded maximum numeric UUID'\n\t\t);\n\t});\n\n\tit('can rehydrate a valid session UUID', () => {\n\t\tconst uuid = assertIsStableId('44f95a8b-c52b-4828-a000-0000f0000003');\n\t\tconst sessionUuid = numericUuidFromStableId(uuid);\n\t\texpect(stableIdFromNumericUuid(sessionUuid)).to.equal(uuid);\n\t});\n\n\tit('can create valid session UUIDs', () => {\n\t\tfor (let i = 0; i < 100; i++) {\n\t\t\tconst sessionId = createSessionId();\n\t\t\texpect(sessionId.length).to.equal(36);\n\t\t\texpect(() => {\n\t\t\t\tconst sessionNumericUuid = numericUuidFromStableId(sessionId);\n\t\t\t\texpect(stableIdFromNumericUuid(sessionNumericUuid)).to.equal(sessionId);\n\t\t\t}).to.not.throw();\n\t\t}\n\t});\n\n\tconst maxUuidBigint = bigIntFromStableId(maxStableId);\n\n\tit('ensures that session UUIDs are resistant to overflow', () => {\n\t\tconst uuid = assertIsStableId('ffffffff-ffff-4fff-bfff-ffffffffffff');\n\t\tfor (let i = 0; i < 128; i++) {\n\t\t\tconst ensuredUuid = ensureSessionUuid(uuid);\n\t\t\texpect(isStableId(ensuredUuid)).to.be.true;\n\t\t\tconst ensuredBigint = bigIntFromStableId(ensuredUuid);\n\t\t\texpect(maxUuidBigint - ensuredBigint > Number.MAX_SAFE_INTEGER).to.be.true;\n\t\t}\n\t});\n\n\tit('correctly adjusts session UUIDs that are in danger of overflow', () => {\n\t\tconst dangerous = [\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-bfff-ffffffffffff'),\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-bff0-000000000000'),\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-bf00-000000000000'),\n\t\t];\n\n\t\tconst safe = [\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-beff-ffffffffffff'),\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-bef0-000000000000'),\n\t\t\tassertIsStableId('ffffffff-ffff-4fff-be00-000000000000'),\n\t\t];\n\n\t\tdangerous.forEach((stableId) => expect(ensureSessionUuid(stableId)).to.not.equal(stableId));\n\t\tsafe.forEach((stableId) => expect(ensureSessionUuid(stableId)).to.equal(stableId));\n\t});\n\n\tconst stableIds = [\n\t\tassertIsStableId('748540ca-b7c5-4c99-83ff-c1b8e02c09d6'),\n\t\tassertIsStableId('748540ca-b7c5-4c99-83ef-c1b8e02c09d6'),\n\t\tassertIsStableId('748540ca-b7c5-4c99-831f-c1b8e02c09d6'),\n\t\tassertIsStableId('0002c79e-b536-4776-b000-000266c252d5'),\n\t\tassertIsStableId('082533b9-6d05-4068-a008-fe2cc43543f7'),\n\t\tassertIsStableId('2c9fa1f8-48d5-4554-a466-000000000000'),\n\t\tassertIsStableId('2c9fa1f8-48d5-4000-a000-000000000000'),\n\t\tassertIsStableId('10000000-0000-4000-b000-000000000000'),\n\t\tassertIsStableId('10000000-0000-4000-b020-000000000000'), // 2^52\n\t\tassertIsStableId('10000000-0000-4000-b00f-ffffffffffff'),\n\t\tassertIsStableId('10000000-0000-4000-b040-000000000000'),\n\t\tassertIsStableId('f0000000-0000-4000-8000-000000000000'),\n\t\tassertIsStableId('efffffff-ffff-4fff-bfff-ffffffffffff'),\n\t\tintegerToStableId(0),\n\t\tintegerToStableId(1),\n\t\tintegerToStableId(77),\n\t\tintegerToStableId(1024),\n\t\tintegerToStableId(2 ** 32 - 1),\n\t\tintegerToStableId(2 ** 52 - 1),\n\t\tintegerToStableId(Number.MAX_SAFE_INTEGER),\n\t\tintegerToStableId(Number.MAX_SAFE_INTEGER - 1),\n\t];\n\n\tdescribe('incrementing', () => {\n\t\tconst rand = makeRandom(0);\n\t\tconst incrementAmounts = [\n\t\t\t...[...new Array(53).keys()].map((n) => 2 ** n - 1),\n\t\t\t...[...new Array(10).keys()].map((_) => rand.integer(0, Number.MAX_SAFE_INTEGER)),\n\t\t];\n\t\tstableIds.forEach((stableId) => {\n\t\t\tit(`can increment ${stableId}`, () => {\n\t\t\t\tconst uuid = numericUuidFromStableId(stableId);\n\n\t\t\t\tincrementAmounts.forEach((incrementAmount) => {\n\t\t\t\t\tconst bigintIncremented = bigIntFromStableId(stableId) + BigInt(incrementAmount);\n\t\t\t\t\tconst incremented = incrementUuid(uuid, incrementAmount);\n\t\t\t\t\tconst bigintStr = integerToStableId(bigintIncremented);\n\t\t\t\t\texpect(stableIdFromNumericUuid(incremented)).to.equal(bigintStr);\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t});\n\n\tit('delta calculation can calculate the integer delta between stable ids', () => {\n\t\tstableIds.forEach((stableIdA) => {\n\t\t\tconst uuidA = numericUuidFromStableId(stableIdA);\n\t\t\tconst bigintA = bigIntFromStableId(stableIdA);\n\t\t\tconst arbitraryMaxDelta = 2 ** 32 - 1;\n\t\t\tstableIds.forEach((stableIdB) => {\n\t\t\t\tconst uuidB = numericUuidFromStableId(stableIdB);\n\t\t\t\tconst bigintB = bigIntFromStableId(stableIdB);\n\t\t\t\tconst realDelta = bigintA - bigintB;\n\t\t\t\tconst numericDelta = getPositiveDelta(uuidA, uuidB, Number.MAX_SAFE_INTEGER);\n\t\t\t\tif (realDelta > Number.MAX_SAFE_INTEGER || realDelta < 0) {\n\t\t\t\t\texpect(numericDelta).to.equal(undefined);\n\t\t\t\t} else {\n\t\t\t\t\texpect(numericDelta).to.equal(Number(realDelta));\n\t\t\t\t}\n\t\t\t\tconst numericDeltaCapped = getPositiveDelta(uuidA, uuidB, arbitraryMaxDelta);\n\t\t\t\tif (realDelta >= 0 && realDelta <= arbitraryMaxDelta) {\n\t\t\t\t\texpect(numericDeltaCapped).to.equal(Number(realDelta));\n\t\t\t\t} else {\n\t\t\t\t\texpect(numericDeltaCapped).to.equal(undefined);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t});\n\n\tit('can round trip between stable ID and uuid', () => {\n\t\tstableIds.forEach((stableId) => {\n\t\t\tconst uuid = numericUuidFromStableId(stableId);\n\t\t\tconst roundTripped = stableIdFromNumericUuid(uuid);\n\t\t\texpect(stableId).to.equal(roundTripped);\n\t\t});\n\t});\n\n\tit('can compare numeric uuids', () => {\n\t\tstableIds.forEach((stableIdA) => {\n\t\t\tstableIds.forEach((stableIdB) => {\n\t\t\t\tconst numericA = numericUuidFromStableId(stableIdA);\n\t\t\t\tconst numericB = numericUuidFromStableId(stableIdB);\n\t\t\t\tconst comparedNumeric = numericUuidEquals(numericA, numericB);\n\t\t\t\tconst comparedStrings = compareStrings(stableIdA, stableIdB);\n\t\t\t\texpect(comparedNumeric).to.equal(comparedStrings === 0);\n\t\t\t});\n\t\t});\n\t});\n});\n\nfunction bigIntFromStableId(id: StableId): bigint {\n\tconst minimized = id.replace(/-/g, '');\n\t// UUID | xxxxxxxx-xxxx-Vxxx-vxxx-xxxxxxxxxxxx | The StableId passed to this function, shown here in standard UUID notation\n\t// nibbles | hhhhhhhh hhhh mmm llll llllllllllll | Whether or not each nibble is part of the \"high\", \"middle\" or \"low\" group below\n\t// bit count | 44444444-4444-0444-2444-444444444444 | The number of bits per nibble that are used to encode the number\n\n\t// Interpret numerically...\n\tconst highNibbles = BigInt(`0x${minimized.substr(0, 12)}`); // ...all nibbles above the version nibble,\n\tconst midNibbles = BigInt(`0x${minimized.substr(13, 3)}`); // the nibbles below the version nibble and above the variant nibble,\n\tconst lowNibbles = BigInt(`0x${minimized.substr(16, 16)}`); // and the variant nibble and all nibbles below\n\t// Count the number of bits that contribute to the number (i.e. are not reserved for version/variant) in...\n\tconst lowBitCount = BigInt(62); // ...the low nibbles\n\tconst midBitCount = BigInt(12); // and the mid nibbles\n\t// Shift the values of each region by the appropriate number of bits\n\tconst highNumber = highNibbles << (midBitCount + lowBitCount);\n\tconst midNumber = midNibbles << lowBitCount;\n\t// The low nibbles include the variant nibble because its two low bits are numerical (but its two upper bits are not). So mask them out:\n\tconst lowNumber = lowNibbles & BigInt('0x3fffffffffffffff'); // A nibble '0011' followed by 15 nibbles '1111'.\n\t// Now that high and mid are shifted correctly, the final number is their sum:\n\treturn highNumber + midNumber + lowNumber;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"RevisionValueCache.tests.js","sourceRoot":"","sources":["../../src/test/RevisionValueCache.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 { fail } from '../Common';\nimport { RevisionValueCache } from '../RevisionValueCache';\n\ntype DummyValue = number;\nconst dummyValue = -1;\n\ndescribe('RevisionValueCache', () => {\n\tfunction closestEntry(cache: RevisionValueCache<DummyValue>, revision: number): number {\n\t\treturn (cache.getClosestEntry(revision) ?? fail('No prior revision'))[0];\n\t}\n\n\tit('cannot be created with a negative retention window', () => {\n\t\texpect(() => new RevisionValueCache<DummyValue>(1, -1)).to.throw(\n\t\t\t'retentionWindowStart must be initialized >= 0'\n\t\t);\n\t});\n\n\tit('cannot move the retention window backwards', () => {\n\t\tconst cache = new RevisionValueCache<DummyValue>(1, 0);\n\t\texpect(() => cache.updateRetentionWindow(-1)).to.throw('retention window boundary must not move backwards');\n\t});\n\n\tit('can find closest entry to a queried revision', () => {\n\t\tconst cache = new RevisionValueCache<DummyValue>(1, 0, [[0, dummyValue]]);\n\t\tcache.cacheValue(2, dummyValue);\n\t\texpect(closestEntry(cache, 1)).to.equal(0);\n\t\texpect(closestEntry(cache, 2)).to.equal(2);\n\t\texpect(closestEntry(cache, 3)).to.equal(2);\n\t});\n\n\tit('evicts entries when full', () => {\n\t\tconst size = 3;\n\t\tconst cache = new RevisionValueCache<DummyValue>(\n\t\t\tsize,\n\t\t\tsize * 3 /* ensure all entries are outside of window */,\n\t\t\t[[0, dummyValue]]\n\t\t);\n\n\t\t// Fill the cache\n\t\t// Start at 1 because the initial revision is never evicted\n\t\tfor (let i = 1; i <= size; i++) {\n\t\t\tcache.cacheValue(i, dummyValue);\n\t\t}\n\t\tfor (let i = size + 1; i <= size * 2; i++) {\n\t\t\tcache.cacheValue(i, dummyValue);\n\t\t\t// Should have evicted the oldest entry\n\t\t\texpect(closestEntry(cache, i - size)).to.equal(0);\n\t\t}\n\t\tfor (let i = size + 1; i <= size * 2; i++) {\n\t\t\texpect(closestEntry(cache, i)).to.equal(i);\n\t\t}\n\t});\n\n\tit('retains entries within the retention window', () => {\n\t\tconst windowStart = 3;\n\t\tconst windowEnd = windowStart + 3;\n\t\tconst cache = new RevisionValueCache<DummyValue>(1, windowStart, [[0, dummyValue]]);\n\n\t\t// Add entries within retention window\n\t\tfor (let i = windowStart; i <= windowEnd; i++) {\n\t\t\tcache.cacheValue(i, dummyValue);\n\t\t}\n\t\t// Add entries outside the retention window. These should not cause the in-window entries to be evicted.\n\t\tfor (let i = 1; i <= windowStart; i++) {\n\t\t\tcache.cacheValue(i, dummyValue);\n\t\t}\n\t\tfor (let i = windowStart; i <= windowEnd; i++) {\n\t\t\texpect(closestEntry(cache, i)).to.equal(i);\n\t\t}\n\t\tfor (let i = 1; i < windowStart - 1; i++) {\n\t\t\texpect(closestEntry(cache, i)).to.equal(0);\n\t\t}\n\t});\n\n\tit('can evict entries that move out of the retention window', () => {\n\t\tconst cache = new RevisionValueCache<DummyValue>(1, 0);\n\t\tcache.cacheValue(5, dummyValue);\n\t\tcache.cacheValue(1, dummyValue);\n\t\texpect(closestEntry(cache, 5)).to.equal(5);\n\t\tcache.updateRetentionWindow(6); // adds 5 to LRU, evicts 1\n\t\tcache.cacheValue(2, dummyValue); // evicts 5\n\t\texpect(closestEntry(cache, 5)).to.equal(2);\n\t});\n\n\tit('never evicts explicitly retained values', () => {\n\t\tconst cache = new RevisionValueCache<DummyValue>(1, 3, [[0, dummyValue]]);\n\t\tcache.cacheValue(1, dummyValue);\n\t\t// Add a retained entry outside of the retention window\n\t\tcache.cacheRetainedValue(5, dummyValue); // Should not evict 1\n\t\texpect(closestEntry(cache, 1)).to.equal(1);\n\t\texpect(closestEntry(cache, 5)).to.equal(5);\n\t\tcache.cacheValue(2, dummyValue); // Evict 1\n\t\tcache.updateRetentionWindow(10); // Should not add 5, so 2 will still be in cache\n\t\texpect(closestEntry(cache, 1)).to.equal(0);\n\t\texpect(closestEntry(cache, 2)).to.equal(2);\n\t\texpect(closestEntry(cache, 5)).to.equal(5);\n\t\tcache.cacheValue(3, dummyValue); // Evict 2\n\t\texpect(closestEntry(cache, 2)).to.equal(0);\n\t\texpect(closestEntry(cache, 5)).to.equal(5);\n\t});\n\n\tit('can update retention window to a new range that moves > evictableSize entries', () => {\n\t\tconst cacheSize = 5;\n\t\tconst cache = new RevisionValueCache<DummyValue>(cacheSize, 0);\n\t\tcache.cacheRetainedValue(0, dummyValue);\n\t\tfor (let i = 0; i < cacheSize * 3; i++) {\n\t\t\tcache.cacheValue(i, dummyValue);\n\t\t}\n\t\tfor (let i = 0; i < cacheSize * 3; i++) {\n\t\t\texpect(closestEntry(cache, i)).to.equal(i); // All entries are cached since they are in the window.\n\t\t}\n\t\tcache.updateRetentionWindow(cacheSize * 2 + 1); // adds 2 * cache size to LRU, so [0, cacheSize] should be evicted\n\t\tfor (let i = 1; i <= cacheSize; i++) {\n\t\t\texpect(closestEntry(cache, i)).to.equal(0);\n\t\t}\n\t});\n});\n"]}
1
+ {"version":3,"file":"RevisionValueCache.tests.js","sourceRoot":"","sources":["../../src/test/RevisionValueCache.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 { fail } from '../Common';\nimport { RevisionValueCache } from '../RevisionValueCache';\n\ntype DummyValue = number;\nconst dummyValue = -1;\n\ndescribe('RevisionValueCache', () => {\n\tfunction closestEntry(cache: RevisionValueCache<DummyValue>, revision: number): number {\n\t\treturn (cache.getClosestEntry(revision) ?? fail('No prior revision'))[0];\n\t}\n\n\tit('cannot be created with a negative retention window', () => {\n\t\texpect(() => new RevisionValueCache<DummyValue>(1, -1)).to.throw(\n\t\t\t'retentionWindowStart must be initialized >= 0'\n\t\t);\n\t});\n\n\tit('cannot move the retention window backwards', () => {\n\t\tconst cache = new RevisionValueCache<DummyValue>(1, 0);\n\t\texpect(() => cache.updateRetentionWindow(-1)).to.throw('retention window boundary must not move backwards');\n\t});\n\n\tit('can find closest entry to a queried revision', () => {\n\t\tconst cache = new RevisionValueCache<DummyValue>(1, 0, [[0, dummyValue]]);\n\t\tcache.cacheValue(2, dummyValue);\n\t\texpect(closestEntry(cache, 1)).to.equal(0);\n\t\texpect(closestEntry(cache, 2)).to.equal(2);\n\t\texpect(closestEntry(cache, 3)).to.equal(2);\n\t});\n\n\tit('evicts entries when full', () => {\n\t\tconst size = 3;\n\t\tconst cache = new RevisionValueCache<DummyValue>(\n\t\t\tsize,\n\t\t\tsize * 3 /* ensure all entries are outside of window */,\n\t\t\t[[0, dummyValue]]\n\t\t);\n\n\t\t// Fill the cache\n\t\t// Start at 1 because the initial revision is never evicted\n\t\tfor (let i = 1; i <= size; i++) {\n\t\t\tcache.cacheValue(i, dummyValue);\n\t\t}\n\t\tfor (let i = size + 1; i <= size * 2; i++) {\n\t\t\tcache.cacheValue(i, dummyValue);\n\t\t\t// Should have evicted the oldest entry\n\t\t\texpect(closestEntry(cache, i - size)).to.equal(0);\n\t\t}\n\t\tfor (let i = size + 1; i <= size * 2; i++) {\n\t\t\texpect(closestEntry(cache, i)).to.equal(i);\n\t\t}\n\t});\n\n\tit('retains entries within the retention window', () => {\n\t\tconst windowStart = 3;\n\t\tconst windowEnd = windowStart + 3;\n\t\tconst cache = new RevisionValueCache<DummyValue>(1, windowStart, [[0, dummyValue]]);\n\n\t\t// Add entries within retention window\n\t\tfor (let i = windowStart; i <= windowEnd; i++) {\n\t\t\tcache.cacheValue(i, dummyValue);\n\t\t}\n\t\t// Add entries outside the retention window. These should not cause the in-window entries to be evicted.\n\t\tfor (let i = 1; i <= windowStart; i++) {\n\t\t\tcache.cacheValue(i, dummyValue);\n\t\t}\n\t\tfor (let i = windowStart; i <= windowEnd; i++) {\n\t\t\texpect(closestEntry(cache, i)).to.equal(i);\n\t\t}\n\t\tfor (let i = 1; i < windowStart - 1; i++) {\n\t\t\texpect(closestEntry(cache, i)).to.equal(0);\n\t\t}\n\t});\n\n\tit('can evict entries that move out of the retention window', () => {\n\t\tconst cache = new RevisionValueCache<DummyValue>(1, 0);\n\t\tcache.cacheValue(5, dummyValue);\n\t\tcache.cacheValue(1, dummyValue);\n\t\texpect(closestEntry(cache, 5)).to.equal(5);\n\t\tcache.updateRetentionWindow(6); // adds 5 to LRU, evicts 1\n\t\tcache.cacheValue(2, dummyValue); // evicts 5\n\t\texpect(closestEntry(cache, 5)).to.equal(2);\n\t});\n\n\tit('never evicts explicitly retained values', () => {\n\t\tconst cache = new RevisionValueCache<DummyValue>(1, 3, [[0, dummyValue]]);\n\t\tcache.cacheValue(1, dummyValue);\n\t\t// Add a retained entry outside of the retention window\n\t\tcache.cacheRetainedValue(5, dummyValue); // Should not evict 1\n\t\texpect(closestEntry(cache, 1)).to.equal(1);\n\t\texpect(closestEntry(cache, 5)).to.equal(5);\n\t\tcache.cacheValue(2, dummyValue); // Evict 1\n\t\tcache.updateRetentionWindow(10); // Should not add 5, so 2 will still be in cache\n\t\texpect(closestEntry(cache, 1)).to.equal(0);\n\t\texpect(closestEntry(cache, 2)).to.equal(2);\n\t\texpect(closestEntry(cache, 5)).to.equal(5);\n\t\tcache.cacheValue(3, dummyValue); // Evict 2\n\t\texpect(closestEntry(cache, 2)).to.equal(0);\n\t\texpect(closestEntry(cache, 5)).to.equal(5);\n\t});\n\n\tit('can update retention window to a new range that moves > evictableSize entries', () => {\n\t\tconst cacheSize = 5;\n\t\tconst cache = new RevisionValueCache<DummyValue>(cacheSize, 0);\n\t\tcache.cacheRetainedValue(0, dummyValue);\n\t\tfor (let i = 0; i < cacheSize * 3; i++) {\n\t\t\tcache.cacheValue(i, dummyValue);\n\t\t}\n\t\tfor (let i = 0; i < cacheSize * 3; i++) {\n\t\t\texpect(closestEntry(cache, i)).to.equal(i); // All entries are cached since they are in the window.\n\t\t}\n\t\tcache.updateRetentionWindow(cacheSize * 2 + 1); // adds 2 * cache size to LRU, so [0, cacheSize] should be evicted\n\t\tfor (let i = 1; i <= cacheSize; i++) {\n\t\t\texpect(closestEntry(cache, i)).to.equal(0);\n\t\t}\n\t});\n});\n"]}