@fluid-experimental/tree 0.58.2001 → 0.59.1000-61898

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 (815) hide show
  1. package/README.md +9 -9
  2. package/dist/ChangeCompression.d.ts +39 -0
  3. package/dist/ChangeCompression.d.ts.map +1 -0
  4. package/dist/ChangeCompression.js +117 -0
  5. package/dist/ChangeCompression.js.map +1 -0
  6. package/{lib/default-edits/PersistedTypes.d.ts → dist/ChangeTypes.d.ts} +58 -100
  7. package/dist/ChangeTypes.d.ts.map +1 -0
  8. package/dist/{default-edits/PersistedTypes.js → ChangeTypes.js} +21 -76
  9. package/dist/ChangeTypes.js.map +1 -0
  10. package/dist/Checkout.d.ts +39 -27
  11. package/dist/Checkout.d.ts.map +1 -1
  12. package/dist/Checkout.js +59 -31
  13. package/dist/Checkout.js.map +1 -1
  14. package/dist/Common.d.ts +175 -38
  15. package/dist/Common.d.ts.map +1 -1
  16. package/dist/Common.js +240 -103
  17. package/dist/Common.js.map +1 -1
  18. package/dist/EagerCheckout.d.ts +24 -0
  19. package/dist/EagerCheckout.d.ts.map +1 -0
  20. package/dist/{BasicCheckout.js → EagerCheckout.js} +9 -6
  21. package/dist/EagerCheckout.js.map +1 -0
  22. package/dist/EditLog.d.ts +77 -63
  23. package/dist/EditLog.d.ts.map +1 -1
  24. package/dist/EditLog.js +85 -48
  25. package/dist/EditLog.js.map +1 -1
  26. package/dist/EditUtilities.d.ts +168 -0
  27. package/dist/EditUtilities.d.ts.map +1 -0
  28. package/dist/EditUtilities.js +373 -0
  29. package/dist/EditUtilities.js.map +1 -0
  30. package/dist/EventTypes.d.ts +73 -0
  31. package/dist/EventTypes.d.ts.map +1 -0
  32. package/dist/EventTypes.js +78 -0
  33. package/dist/EventTypes.js.map +1 -0
  34. package/dist/Forest.d.ts +29 -7
  35. package/dist/Forest.d.ts.map +1 -1
  36. package/dist/Forest.js +60 -36
  37. package/dist/Forest.js.map +1 -1
  38. package/dist/HistoryEditFactory.d.ts +20 -0
  39. package/dist/HistoryEditFactory.d.ts.map +1 -0
  40. package/dist/HistoryEditFactory.js +226 -0
  41. package/dist/HistoryEditFactory.js.map +1 -0
  42. package/dist/IdConversion.d.ts +12 -0
  43. package/dist/IdConversion.d.ts.map +1 -0
  44. package/dist/IdConversion.js +98 -0
  45. package/dist/IdConversion.js.map +1 -0
  46. package/dist/Identifiers.d.ts +89 -2
  47. package/dist/Identifiers.d.ts.map +1 -1
  48. package/dist/Identifiers.js +10 -0
  49. package/dist/Identifiers.js.map +1 -1
  50. package/dist/InitialTree.d.ts +2 -2
  51. package/dist/InitialTree.d.ts.map +1 -1
  52. package/dist/InitialTree.js +2 -1
  53. package/dist/InitialTree.js.map +1 -1
  54. package/dist/LazyCheckout.d.ts +28 -0
  55. package/dist/LazyCheckout.d.ts.map +1 -0
  56. package/dist/LazyCheckout.js +44 -0
  57. package/dist/LazyCheckout.js.map +1 -0
  58. package/dist/LogViewer.d.ts +130 -85
  59. package/dist/LogViewer.d.ts.map +1 -1
  60. package/dist/LogViewer.js +110 -85
  61. package/dist/LogViewer.js.map +1 -1
  62. package/dist/MergeHealth.d.ts +221 -0
  63. package/dist/MergeHealth.d.ts.map +1 -0
  64. package/dist/MergeHealth.js +263 -0
  65. package/dist/MergeHealth.js.map +1 -0
  66. package/dist/NodeIdUtilities.d.ts +90 -0
  67. package/dist/NodeIdUtilities.d.ts.map +1 -0
  68. package/dist/NodeIdUtilities.js +60 -0
  69. package/dist/NodeIdUtilities.js.map +1 -0
  70. package/dist/PayloadUtilities.d.ts +42 -0
  71. package/dist/PayloadUtilities.d.ts.map +1 -0
  72. package/dist/PayloadUtilities.js +114 -0
  73. package/dist/PayloadUtilities.js.map +1 -0
  74. package/dist/ReconciliationPath.d.ts +18 -13
  75. package/dist/ReconciliationPath.d.ts.map +1 -1
  76. package/dist/ReconciliationPath.js.map +1 -1
  77. package/dist/RevisionValueCache.d.ts +11 -2
  78. package/dist/RevisionValueCache.d.ts.map +1 -1
  79. package/dist/RevisionValueCache.js +2 -3
  80. package/dist/RevisionValueCache.js.map +1 -1
  81. package/dist/RevisionView.d.ts +83 -0
  82. package/dist/RevisionView.d.ts.map +1 -0
  83. package/dist/RevisionView.js +182 -0
  84. package/dist/RevisionView.js.map +1 -0
  85. package/dist/SerializationUtilities.d.ts +36 -0
  86. package/dist/SerializationUtilities.d.ts.map +1 -0
  87. package/dist/SerializationUtilities.js +102 -0
  88. package/dist/SerializationUtilities.js.map +1 -0
  89. package/dist/SharedTree.d.ts +400 -0
  90. package/dist/SharedTree.d.ts.map +1 -0
  91. package/dist/SharedTree.js +1074 -0
  92. package/dist/SharedTree.js.map +1 -0
  93. package/dist/SharedTreeEncoder.d.ts +102 -0
  94. package/dist/SharedTreeEncoder.d.ts.map +1 -0
  95. package/dist/SharedTreeEncoder.js +313 -0
  96. package/dist/SharedTreeEncoder.js.map +1 -0
  97. package/dist/StringInterner.d.ts +46 -0
  98. package/dist/StringInterner.d.ts.map +1 -0
  99. package/dist/StringInterner.js +61 -0
  100. package/dist/StringInterner.js.map +1 -0
  101. package/dist/Summary.d.ts +40 -0
  102. package/dist/Summary.d.ts.map +1 -0
  103. package/dist/Summary.js +23 -0
  104. package/dist/Summary.js.map +1 -0
  105. package/dist/SummaryBackCompatibility.d.ts +22 -22
  106. package/dist/SummaryBackCompatibility.d.ts.map +1 -1
  107. package/dist/SummaryBackCompatibility.js +30 -33
  108. package/dist/SummaryBackCompatibility.js.map +1 -1
  109. package/dist/SummaryTestUtilities.d.ts +31 -0
  110. package/dist/SummaryTestUtilities.d.ts.map +1 -0
  111. package/dist/SummaryTestUtilities.js +37 -0
  112. package/dist/SummaryTestUtilities.js.map +1 -0
  113. package/dist/Transaction.d.ts +53 -0
  114. package/dist/Transaction.d.ts.map +1 -0
  115. package/dist/Transaction.js +76 -0
  116. package/dist/Transaction.js.map +1 -0
  117. package/dist/TransactionInternal.d.ts +543 -0
  118. package/dist/TransactionInternal.d.ts.map +1 -0
  119. package/dist/TransactionInternal.js +622 -0
  120. package/dist/TransactionInternal.js.map +1 -0
  121. package/dist/TreeCompressor.d.ts +36 -0
  122. package/dist/TreeCompressor.d.ts.map +1 -0
  123. package/dist/TreeCompressor.js +137 -0
  124. package/dist/TreeCompressor.js.map +1 -0
  125. package/dist/TreeNodeHandle.d.ts +12 -18
  126. package/dist/TreeNodeHandle.d.ts.map +1 -1
  127. package/dist/TreeNodeHandle.js +13 -23
  128. package/dist/TreeNodeHandle.js.map +1 -1
  129. package/dist/TreeView.d.ts +166 -0
  130. package/dist/TreeView.d.ts.map +1 -0
  131. package/dist/TreeView.js +218 -0
  132. package/dist/TreeView.js.map +1 -0
  133. package/dist/TreeViewUtilities.d.ts +21 -0
  134. package/dist/TreeViewUtilities.d.ts.map +1 -0
  135. package/dist/TreeViewUtilities.js +77 -0
  136. package/dist/TreeViewUtilities.js.map +1 -0
  137. package/dist/{default-edits/UndoRedoHandler.d.ts → UndoRedoHandler.d.ts} +2 -2
  138. package/dist/UndoRedoHandler.d.ts.map +1 -0
  139. package/dist/{default-edits/UndoRedoHandler.js → UndoRedoHandler.js} +5 -9
  140. package/dist/UndoRedoHandler.js.map +1 -0
  141. package/dist/id-compressor/AppendOnlySortedMap.d.ts +127 -0
  142. package/dist/id-compressor/AppendOnlySortedMap.d.ts.map +1 -0
  143. package/dist/id-compressor/AppendOnlySortedMap.js +283 -0
  144. package/dist/id-compressor/AppendOnlySortedMap.js.map +1 -0
  145. package/dist/id-compressor/IdCompressor.d.ts +389 -0
  146. package/dist/id-compressor/IdCompressor.d.ts.map +1 -0
  147. package/dist/id-compressor/IdCompressor.js +1353 -0
  148. package/dist/id-compressor/IdCompressor.js.map +1 -0
  149. package/dist/id-compressor/IdRange.d.ts +11 -0
  150. package/dist/id-compressor/IdRange.d.ts.map +1 -0
  151. package/dist/id-compressor/IdRange.js +29 -0
  152. package/dist/id-compressor/IdRange.js.map +1 -0
  153. package/dist/id-compressor/NumericUuid.d.ts +63 -0
  154. package/dist/id-compressor/NumericUuid.d.ts.map +1 -0
  155. package/dist/id-compressor/NumericUuid.js +377 -0
  156. package/dist/id-compressor/NumericUuid.js.map +1 -0
  157. package/dist/id-compressor/index.d.ts +12 -0
  158. package/dist/id-compressor/index.d.ts.map +1 -0
  159. package/dist/id-compressor/index.js +26 -0
  160. package/dist/id-compressor/index.js.map +1 -0
  161. package/dist/id-compressor/persisted-types/0.0.1.d.ts +156 -0
  162. package/dist/id-compressor/persisted-types/0.0.1.d.ts.map +1 -0
  163. package/dist/id-compressor/persisted-types/0.0.1.js +7 -0
  164. package/dist/id-compressor/persisted-types/0.0.1.js.map +1 -0
  165. package/dist/id-compressor/persisted-types/index.d.ts +6 -0
  166. package/dist/id-compressor/persisted-types/index.d.ts.map +1 -0
  167. package/dist/id-compressor/persisted-types/index.js +18 -0
  168. package/dist/id-compressor/persisted-types/index.js.map +1 -0
  169. package/dist/index.d.ts +29 -9
  170. package/dist/index.d.ts.map +1 -1
  171. package/dist/index.js +50 -35
  172. package/dist/index.js.map +1 -1
  173. package/dist/persisted-types/0.0.2.d.ts +385 -0
  174. package/dist/persisted-types/0.0.2.d.ts.map +1 -0
  175. package/dist/persisted-types/0.0.2.js +113 -0
  176. package/dist/persisted-types/0.0.2.js.map +1 -0
  177. package/dist/persisted-types/0.1.1.d.ts +314 -0
  178. package/dist/persisted-types/0.1.1.d.ts.map +1 -0
  179. package/dist/persisted-types/0.1.1.js +153 -0
  180. package/dist/persisted-types/0.1.1.js.map +1 -0
  181. package/dist/persisted-types/index.d.ts +7 -0
  182. package/dist/persisted-types/index.d.ts.map +1 -0
  183. package/dist/persisted-types/index.js +20 -0
  184. package/dist/persisted-types/index.js.map +1 -0
  185. package/docs/0-1-1-Compression.md +228 -0
  186. package/docs/Breaking-Change-Migration.md +52 -0
  187. package/docs/Compression.md +2 -2
  188. package/docs/Telemetry.md +43 -0
  189. package/lib/ChangeCompression.d.ts +39 -0
  190. package/lib/ChangeCompression.d.ts.map +1 -0
  191. package/lib/ChangeCompression.js +111 -0
  192. package/lib/ChangeCompression.js.map +1 -0
  193. package/{dist/default-edits/PersistedTypes.d.ts → lib/ChangeTypes.d.ts} +58 -100
  194. package/lib/ChangeTypes.d.ts.map +1 -0
  195. package/lib/{default-edits/PersistedTypes.js → ChangeTypes.js} +15 -68
  196. package/lib/ChangeTypes.js.map +1 -0
  197. package/lib/Checkout.d.ts +39 -27
  198. package/lib/Checkout.d.ts.map +1 -1
  199. package/lib/Checkout.js +51 -23
  200. package/lib/Checkout.js.map +1 -1
  201. package/lib/Common.d.ts +175 -38
  202. package/lib/Common.d.ts.map +1 -1
  203. package/lib/Common.js +226 -101
  204. package/lib/Common.js.map +1 -1
  205. package/lib/EagerCheckout.d.ts +24 -0
  206. package/lib/EagerCheckout.d.ts.map +1 -0
  207. package/lib/{BasicCheckout.js → EagerCheckout.js} +7 -4
  208. package/lib/EagerCheckout.js.map +1 -0
  209. package/lib/EditLog.d.ts +77 -63
  210. package/lib/EditLog.d.ts.map +1 -1
  211. package/lib/EditLog.js +83 -47
  212. package/lib/EditLog.js.map +1 -1
  213. package/lib/EditUtilities.d.ts +168 -0
  214. package/lib/EditUtilities.d.ts.map +1 -0
  215. package/lib/EditUtilities.js +353 -0
  216. package/lib/EditUtilities.js.map +1 -0
  217. package/lib/EventTypes.d.ts +73 -0
  218. package/lib/EventTypes.d.ts.map +1 -0
  219. package/lib/EventTypes.js +75 -0
  220. package/lib/EventTypes.js.map +1 -0
  221. package/lib/Forest.d.ts +29 -7
  222. package/lib/Forest.d.ts.map +1 -1
  223. package/lib/Forest.js +58 -35
  224. package/lib/Forest.js.map +1 -1
  225. package/lib/HistoryEditFactory.d.ts +20 -0
  226. package/lib/HistoryEditFactory.d.ts.map +1 -0
  227. package/lib/{default-edits/HistoryEditFactory.js → HistoryEditFactory.js} +78 -39
  228. package/lib/HistoryEditFactory.js.map +1 -0
  229. package/lib/IdConversion.d.ts +12 -0
  230. package/lib/IdConversion.d.ts.map +1 -0
  231. package/lib/IdConversion.js +91 -0
  232. package/lib/IdConversion.js.map +1 -0
  233. package/lib/Identifiers.d.ts +89 -2
  234. package/lib/Identifiers.d.ts.map +1 -1
  235. package/lib/Identifiers.js +8 -1
  236. package/lib/Identifiers.js.map +1 -1
  237. package/lib/InitialTree.d.ts +2 -2
  238. package/lib/InitialTree.d.ts.map +1 -1
  239. package/lib/InitialTree.js +2 -1
  240. package/lib/InitialTree.js.map +1 -1
  241. package/lib/LazyCheckout.d.ts +28 -0
  242. package/lib/LazyCheckout.d.ts.map +1 -0
  243. package/lib/LazyCheckout.js +40 -0
  244. package/lib/LazyCheckout.js.map +1 -0
  245. package/lib/LogViewer.d.ts +130 -85
  246. package/lib/LogViewer.d.ts.map +1 -1
  247. package/lib/LogViewer.js +102 -77
  248. package/lib/LogViewer.js.map +1 -1
  249. package/lib/MergeHealth.d.ts +221 -0
  250. package/lib/MergeHealth.d.ts.map +1 -0
  251. package/lib/MergeHealth.js +258 -0
  252. package/lib/MergeHealth.js.map +1 -0
  253. package/lib/NodeIdUtilities.d.ts +90 -0
  254. package/lib/NodeIdUtilities.d.ts.map +1 -0
  255. package/lib/NodeIdUtilities.js +53 -0
  256. package/lib/NodeIdUtilities.js.map +1 -0
  257. package/lib/PayloadUtilities.d.ts +42 -0
  258. package/lib/PayloadUtilities.d.ts.map +1 -0
  259. package/lib/PayloadUtilities.js +110 -0
  260. package/lib/PayloadUtilities.js.map +1 -0
  261. package/lib/ReconciliationPath.d.ts +18 -13
  262. package/lib/ReconciliationPath.d.ts.map +1 -1
  263. package/lib/ReconciliationPath.js.map +1 -1
  264. package/lib/RevisionValueCache.d.ts +11 -2
  265. package/lib/RevisionValueCache.d.ts.map +1 -1
  266. package/lib/RevisionValueCache.js +2 -3
  267. package/lib/RevisionValueCache.js.map +1 -1
  268. package/lib/RevisionView.d.ts +83 -0
  269. package/lib/RevisionView.d.ts.map +1 -0
  270. package/lib/RevisionView.js +175 -0
  271. package/lib/RevisionView.js.map +1 -0
  272. package/lib/SerializationUtilities.d.ts +36 -0
  273. package/lib/SerializationUtilities.d.ts.map +1 -0
  274. package/lib/SerializationUtilities.js +95 -0
  275. package/lib/SerializationUtilities.js.map +1 -0
  276. package/lib/SharedTree.d.ts +400 -0
  277. package/lib/SharedTree.d.ts.map +1 -0
  278. package/lib/SharedTree.js +1069 -0
  279. package/lib/SharedTree.js.map +1 -0
  280. package/lib/SharedTreeEncoder.d.ts +102 -0
  281. package/lib/SharedTreeEncoder.d.ts.map +1 -0
  282. package/lib/SharedTreeEncoder.js +308 -0
  283. package/lib/SharedTreeEncoder.js.map +1 -0
  284. package/lib/StringInterner.d.ts +46 -0
  285. package/lib/StringInterner.d.ts.map +1 -0
  286. package/lib/StringInterner.js +57 -0
  287. package/lib/StringInterner.js.map +1 -0
  288. package/lib/Summary.d.ts +40 -0
  289. package/lib/Summary.d.ts.map +1 -0
  290. package/lib/Summary.js +19 -0
  291. package/lib/Summary.js.map +1 -0
  292. package/lib/SummaryBackCompatibility.d.ts +22 -22
  293. package/lib/SummaryBackCompatibility.d.ts.map +1 -1
  294. package/lib/SummaryBackCompatibility.js +29 -32
  295. package/lib/SummaryBackCompatibility.js.map +1 -1
  296. package/lib/SummaryTestUtilities.d.ts +31 -0
  297. package/lib/SummaryTestUtilities.d.ts.map +1 -0
  298. package/lib/SummaryTestUtilities.js +32 -0
  299. package/lib/SummaryTestUtilities.js.map +1 -0
  300. package/lib/Transaction.d.ts +53 -0
  301. package/lib/Transaction.d.ts.map +1 -0
  302. package/lib/Transaction.js +72 -0
  303. package/lib/Transaction.js.map +1 -0
  304. package/lib/TransactionInternal.d.ts +543 -0
  305. package/lib/TransactionInternal.d.ts.map +1 -0
  306. package/lib/TransactionInternal.js +618 -0
  307. package/lib/TransactionInternal.js.map +1 -0
  308. package/lib/TreeCompressor.d.ts +36 -0
  309. package/lib/TreeCompressor.d.ts.map +1 -0
  310. package/lib/TreeCompressor.js +133 -0
  311. package/lib/TreeCompressor.js.map +1 -0
  312. package/lib/TreeNodeHandle.d.ts +12 -18
  313. package/lib/TreeNodeHandle.d.ts.map +1 -1
  314. package/lib/TreeNodeHandle.js +14 -24
  315. package/lib/TreeNodeHandle.js.map +1 -1
  316. package/lib/TreeView.d.ts +166 -0
  317. package/lib/TreeView.d.ts.map +1 -0
  318. package/lib/TreeView.js +214 -0
  319. package/lib/TreeView.js.map +1 -0
  320. package/lib/TreeViewUtilities.d.ts +21 -0
  321. package/lib/TreeViewUtilities.d.ts.map +1 -0
  322. package/lib/TreeViewUtilities.js +71 -0
  323. package/lib/TreeViewUtilities.js.map +1 -0
  324. package/lib/{default-edits/UndoRedoHandler.d.ts → UndoRedoHandler.d.ts} +2 -2
  325. package/lib/UndoRedoHandler.d.ts.map +1 -0
  326. package/lib/{default-edits/UndoRedoHandler.js → UndoRedoHandler.js} +3 -7
  327. package/lib/UndoRedoHandler.js.map +1 -0
  328. package/lib/id-compressor/AppendOnlySortedMap.d.ts +127 -0
  329. package/lib/id-compressor/AppendOnlySortedMap.d.ts.map +1 -0
  330. package/lib/id-compressor/AppendOnlySortedMap.js +278 -0
  331. package/lib/id-compressor/AppendOnlySortedMap.js.map +1 -0
  332. package/lib/id-compressor/IdCompressor.d.ts +389 -0
  333. package/lib/id-compressor/IdCompressor.d.ts.map +1 -0
  334. package/lib/id-compressor/IdCompressor.js +1343 -0
  335. package/lib/id-compressor/IdCompressor.js.map +1 -0
  336. package/lib/id-compressor/IdRange.d.ts +11 -0
  337. package/lib/id-compressor/IdRange.d.ts.map +1 -0
  338. package/lib/id-compressor/IdRange.js +25 -0
  339. package/lib/id-compressor/IdRange.js.map +1 -0
  340. package/lib/id-compressor/NumericUuid.d.ts +63 -0
  341. package/lib/id-compressor/NumericUuid.d.ts.map +1 -0
  342. package/lib/id-compressor/NumericUuid.js +365 -0
  343. package/lib/id-compressor/NumericUuid.js.map +1 -0
  344. package/lib/id-compressor/index.d.ts +12 -0
  345. package/lib/id-compressor/index.d.ts.map +1 -0
  346. package/lib/id-compressor/index.js +12 -0
  347. package/lib/id-compressor/index.js.map +1 -0
  348. package/lib/id-compressor/persisted-types/0.0.1.d.ts +156 -0
  349. package/lib/id-compressor/persisted-types/0.0.1.d.ts.map +1 -0
  350. package/lib/{test/Snapshot.tests.d.ts → id-compressor/persisted-types/0.0.1.js} +1 -1
  351. package/lib/id-compressor/persisted-types/0.0.1.js.map +1 -0
  352. package/lib/id-compressor/persisted-types/index.d.ts +6 -0
  353. package/lib/id-compressor/persisted-types/index.d.ts.map +1 -0
  354. package/lib/id-compressor/persisted-types/index.js +6 -0
  355. package/lib/id-compressor/persisted-types/index.js.map +1 -0
  356. package/lib/index.d.ts +29 -9
  357. package/lib/index.d.ts.map +1 -1
  358. package/lib/index.js +23 -6
  359. package/lib/index.js.map +1 -1
  360. package/lib/persisted-types/0.0.2.d.ts +385 -0
  361. package/lib/persisted-types/0.0.2.d.ts.map +1 -0
  362. package/lib/persisted-types/0.0.2.js +110 -0
  363. package/lib/persisted-types/0.0.2.js.map +1 -0
  364. package/lib/persisted-types/0.1.1.d.ts +314 -0
  365. package/lib/persisted-types/0.1.1.d.ts.map +1 -0
  366. package/lib/persisted-types/0.1.1.js +150 -0
  367. package/lib/persisted-types/0.1.1.js.map +1 -0
  368. package/lib/persisted-types/index.d.ts +7 -0
  369. package/lib/persisted-types/index.d.ts.map +1 -0
  370. package/lib/persisted-types/index.js +8 -0
  371. package/lib/persisted-types/index.js.map +1 -0
  372. package/lib/test/AppendOnlySortedMap.tests.d.ts +6 -0
  373. package/lib/test/AppendOnlySortedMap.tests.d.ts.map +1 -0
  374. package/lib/test/AppendOnlySortedMap.tests.js +169 -0
  375. package/lib/test/AppendOnlySortedMap.tests.js.map +1 -0
  376. package/lib/test/{SnapshotUtilities.tests.d.ts → ChangeCompression.tests.d.ts} +1 -1
  377. package/lib/test/ChangeCompression.tests.d.ts.map +1 -0
  378. package/lib/test/ChangeCompression.tests.js +145 -0
  379. package/lib/test/ChangeCompression.tests.js.map +1 -0
  380. package/lib/test/Checkout.tests.d.ts +2 -3
  381. package/lib/test/Checkout.tests.d.ts.map +1 -1
  382. package/lib/test/Checkout.tests.js +126 -69
  383. package/lib/test/Checkout.tests.js.map +1 -1
  384. package/lib/test/Common.tests.js +60 -2
  385. package/lib/test/Common.tests.js.map +1 -1
  386. package/lib/test/{BasicCheckout.tests.d.ts → EagerCheckout.tests.d.ts} +1 -1
  387. package/lib/test/EagerCheckout.tests.d.ts.map +1 -0
  388. package/lib/test/EagerCheckout.tests.js +20 -0
  389. package/lib/test/EagerCheckout.tests.js.map +1 -0
  390. package/lib/test/Edit.tests.js +22 -14
  391. package/lib/test/Edit.tests.js.map +1 -1
  392. package/lib/test/{Anchors.glassBox.tests.d.ts → EditLog.perf.tests.d.ts} +1 -1
  393. package/lib/test/EditLog.perf.tests.d.ts.map +1 -0
  394. package/lib/test/EditLog.perf.tests.js +30 -0
  395. package/lib/test/EditLog.perf.tests.js.map +1 -0
  396. package/lib/test/EditLog.tests.js +10 -6
  397. package/lib/test/EditLog.tests.js.map +1 -1
  398. package/lib/test/EditUtilities.tests.d.ts +6 -0
  399. package/lib/test/EditUtilities.tests.d.ts.map +1 -0
  400. package/lib/test/EditUtilities.tests.js +503 -0
  401. package/lib/test/EditUtilities.tests.js.map +1 -0
  402. package/lib/test/Forest.perf.tests.d.ts +6 -0
  403. package/lib/test/Forest.perf.tests.d.ts.map +1 -0
  404. package/lib/test/Forest.perf.tests.js +133 -0
  405. package/lib/test/Forest.perf.tests.js.map +1 -0
  406. package/lib/test/Forest.tests.js +54 -27
  407. package/lib/test/Forest.tests.js.map +1 -1
  408. package/lib/test/GenericTransaction.tests.js +12 -3
  409. package/lib/test/GenericTransaction.tests.js.map +1 -1
  410. package/lib/test/HistoryEditFactory.tests.d.ts +6 -0
  411. package/lib/test/HistoryEditFactory.tests.d.ts.map +1 -0
  412. package/lib/test/HistoryEditFactory.tests.js +90 -0
  413. package/lib/test/HistoryEditFactory.tests.js.map +1 -0
  414. package/lib/test/IdCompressor.perf.tests.d.ts +6 -0
  415. package/lib/test/IdCompressor.perf.tests.d.ts.map +1 -0
  416. package/lib/test/IdCompressor.perf.tests.js +304 -0
  417. package/lib/test/IdCompressor.perf.tests.js.map +1 -0
  418. package/lib/test/IdCompressor.tests.d.ts +6 -0
  419. package/lib/test/IdCompressor.tests.d.ts.map +1 -0
  420. package/lib/test/IdCompressor.tests.js +1075 -0
  421. package/lib/test/IdCompressor.tests.js.map +1 -0
  422. package/lib/test/IdConversion.tests.d.ts +6 -0
  423. package/lib/test/IdConversion.tests.d.ts.map +1 -0
  424. package/lib/test/IdConversion.tests.js +36 -0
  425. package/lib/test/IdConversion.tests.js.map +1 -0
  426. package/lib/test/LazyCheckout.tests.d.ts +6 -0
  427. package/lib/test/LazyCheckout.tests.d.ts.map +1 -0
  428. package/lib/test/LazyCheckout.tests.js +22 -0
  429. package/lib/test/LazyCheckout.tests.js.map +1 -0
  430. package/lib/test/LogViewer.tests.js +269 -187
  431. package/lib/test/LogViewer.tests.js.map +1 -1
  432. package/lib/test/{SharedTreeWithAnchors.tests.d.ts → MergeHealthTelemetryHeartbeat.tests.d.ts} +1 -1
  433. package/lib/test/MergeHealthTelemetryHeartbeat.tests.d.ts.map +1 -0
  434. package/lib/test/MergeHealthTelemetryHeartbeat.tests.js +342 -0
  435. package/lib/test/MergeHealthTelemetryHeartbeat.tests.js.map +1 -0
  436. package/lib/test/NumericUuid.perf.tests.d.ts +6 -0
  437. package/lib/test/NumericUuid.perf.tests.d.ts.map +1 -0
  438. package/lib/test/NumericUuid.perf.tests.js +68 -0
  439. package/lib/test/NumericUuid.perf.tests.js.map +1 -0
  440. package/lib/test/NumericUuid.tests.d.ts +6 -0
  441. package/lib/test/NumericUuid.tests.d.ts.map +1 -0
  442. package/lib/test/NumericUuid.tests.js +191 -0
  443. package/lib/test/NumericUuid.tests.js.map +1 -0
  444. package/lib/test/RevisionView.tests.d.ts +6 -0
  445. package/lib/test/RevisionView.tests.d.ts.map +1 -0
  446. package/lib/test/RevisionView.tests.js +133 -0
  447. package/lib/test/RevisionView.tests.js.map +1 -0
  448. package/lib/test/SharedTree.perf.tests.d.ts +6 -0
  449. package/lib/test/SharedTree.perf.tests.d.ts.map +1 -0
  450. package/lib/test/SharedTree.perf.tests.js +39 -0
  451. package/lib/test/SharedTree.perf.tests.js.map +1 -0
  452. package/lib/test/SharedTree.tests.js +15 -3
  453. package/lib/test/SharedTree.tests.js.map +1 -1
  454. package/lib/test/StringInterner.tests.d.ts +6 -0
  455. package/lib/test/StringInterner.tests.d.ts.map +1 -0
  456. package/lib/test/StringInterner.tests.js +71 -0
  457. package/lib/test/StringInterner.tests.js.map +1 -0
  458. package/lib/test/Summary.tests.d.ts +8 -0
  459. package/lib/test/Summary.tests.d.ts.map +1 -0
  460. package/lib/test/Summary.tests.js +407 -0
  461. package/lib/test/Summary.tests.js.map +1 -0
  462. package/lib/test/Transaction.tests.js +76 -330
  463. package/lib/test/Transaction.tests.js.map +1 -1
  464. package/lib/test/TransactionInternal.tests.d.ts +6 -0
  465. package/lib/test/TransactionInternal.tests.d.ts.map +1 -0
  466. package/lib/test/TransactionInternal.tests.js +568 -0
  467. package/lib/test/TransactionInternal.tests.js.map +1 -0
  468. package/lib/test/TreeCompression.tests.d.ts +6 -0
  469. package/lib/test/TreeCompression.tests.d.ts.map +1 -0
  470. package/lib/test/TreeCompression.tests.js +292 -0
  471. package/lib/test/TreeCompression.tests.js.map +1 -0
  472. package/lib/test/TreeView.tests.d.ts +6 -0
  473. package/lib/test/TreeView.tests.d.ts.map +1 -0
  474. package/lib/test/TreeView.tests.js +176 -0
  475. package/lib/test/TreeView.tests.js.map +1 -0
  476. package/lib/test/UndoRedoHandler.tests.js +2 -2
  477. package/lib/test/UndoRedoHandler.tests.js.map +1 -1
  478. package/lib/test/Virtualization.tests.js +147 -62
  479. package/lib/test/Virtualization.tests.js.map +1 -1
  480. package/lib/test/fuzz/Generators.d.ts +19 -0
  481. package/lib/test/fuzz/Generators.d.ts.map +1 -0
  482. package/lib/test/fuzz/Generators.js +420 -0
  483. package/lib/test/fuzz/Generators.js.map +1 -0
  484. package/lib/test/fuzz/SharedTreeFuzzTests.d.ts +20 -0
  485. package/lib/test/fuzz/SharedTreeFuzzTests.d.ts.map +1 -0
  486. package/lib/test/fuzz/SharedTreeFuzzTests.js +217 -0
  487. package/lib/test/fuzz/SharedTreeFuzzTests.js.map +1 -0
  488. package/lib/test/fuzz/Types.d.ts +133 -0
  489. package/lib/test/fuzz/Types.d.ts.map +1 -0
  490. package/lib/test/{GenericTransactionWithAnchors.tests.d.ts → fuzz/Types.js} +2 -2
  491. package/lib/test/fuzz/Types.js.map +1 -0
  492. package/lib/test/utilities/IdCompressorTestUtilities.d.ts +180 -0
  493. package/lib/test/utilities/IdCompressorTestUtilities.d.ts.map +1 -0
  494. package/lib/test/utilities/IdCompressorTestUtilities.js +528 -0
  495. package/lib/test/utilities/IdCompressorTestUtilities.js.map +1 -0
  496. package/lib/test/utilities/MockTransaction.d.ts +26 -7
  497. package/lib/test/utilities/MockTransaction.d.ts.map +1 -1
  498. package/lib/test/utilities/MockTransaction.js +40 -11
  499. package/lib/test/utilities/MockTransaction.js.map +1 -1
  500. package/lib/test/utilities/PendingLocalStateTests.d.ts +12 -0
  501. package/lib/test/utilities/PendingLocalStateTests.d.ts.map +1 -0
  502. package/lib/test/utilities/PendingLocalStateTests.js +105 -0
  503. package/lib/test/utilities/PendingLocalStateTests.js.map +1 -0
  504. package/lib/test/utilities/SharedTreeTests.d.ts +3 -4
  505. package/lib/test/utilities/SharedTreeTests.d.ts.map +1 -1
  506. package/lib/test/utilities/SharedTreeTests.js +696 -439
  507. package/lib/test/utilities/SharedTreeTests.js.map +1 -1
  508. package/lib/test/utilities/SharedTreeVersioningTests.d.ts +11 -0
  509. package/lib/test/utilities/SharedTreeVersioningTests.d.ts.map +1 -0
  510. package/lib/test/utilities/SharedTreeVersioningTests.js +370 -0
  511. package/lib/test/utilities/SharedTreeVersioningTests.js.map +1 -0
  512. package/lib/test/utilities/SummaryLoadPerfTests.d.ts +10 -0
  513. package/lib/test/utilities/SummaryLoadPerfTests.d.ts.map +1 -0
  514. package/lib/test/utilities/SummaryLoadPerfTests.js +102 -0
  515. package/lib/test/utilities/SummaryLoadPerfTests.js.map +1 -0
  516. package/lib/test/utilities/SummarySizeTests.d.ts +11 -0
  517. package/lib/test/utilities/SummarySizeTests.d.ts.map +1 -0
  518. package/lib/test/utilities/SummarySizeTests.js +158 -0
  519. package/lib/test/utilities/SummarySizeTests.js.map +1 -0
  520. package/lib/test/utilities/TestCommon.d.ts +9 -0
  521. package/lib/test/utilities/TestCommon.d.ts.map +1 -0
  522. package/lib/test/utilities/TestCommon.js +13 -0
  523. package/lib/test/utilities/TestCommon.js.map +1 -0
  524. package/lib/test/utilities/TestNode.d.ts +140 -0
  525. package/lib/test/utilities/TestNode.d.ts.map +1 -0
  526. package/lib/test/utilities/TestNode.js +292 -0
  527. package/lib/test/utilities/TestNode.js.map +1 -0
  528. package/lib/test/utilities/TestUtilities.d.ts +84 -70
  529. package/lib/test/utilities/TestUtilities.d.ts.map +1 -1
  530. package/lib/test/utilities/TestUtilities.js +218 -143
  531. package/lib/test/utilities/TestUtilities.js.map +1 -1
  532. package/lib/test/utilities/UndoRedoTests.d.ts +4 -5
  533. package/lib/test/utilities/UndoRedoTests.d.ts.map +1 -1
  534. package/lib/test/utilities/UndoRedoTests.js +138 -149
  535. package/lib/test/utilities/UndoRedoTests.js.map +1 -1
  536. package/package.json +22 -17
  537. package/src/ChangeCompression.ts +159 -0
  538. package/src/{default-edits/PersistedTypes.ts → ChangeTypes.ts} +62 -120
  539. package/src/Checkout.ts +81 -52
  540. package/src/Common.ts +317 -117
  541. package/src/EagerCheckout.ts +38 -0
  542. package/src/EditLog.ts +153 -100
  543. package/src/EditUtilities.ts +559 -0
  544. package/src/EventTypes.ts +74 -0
  545. package/src/Forest.ts +81 -73
  546. package/src/{default-edits/HistoryEditFactory.ts → HistoryEditFactory.ts} +103 -53
  547. package/src/IdConversion.ts +125 -0
  548. package/src/Identifiers.ts +101 -1
  549. package/src/InitialTree.ts +5 -4
  550. package/src/LazyCheckout.ts +51 -0
  551. package/src/LogViewer.ts +242 -166
  552. package/src/MergeHealth.ts +447 -0
  553. package/src/NodeIdUtilities.ts +141 -0
  554. package/src/PayloadUtilities.ts +124 -0
  555. package/src/ReconciliationPath.ts +18 -13
  556. package/src/RevisionValueCache.ts +14 -5
  557. package/src/RevisionView.ts +252 -0
  558. package/src/SerializationUtilities.ts +130 -0
  559. package/src/SharedTree.ts +1458 -0
  560. package/src/SharedTreeEncoder.ts +493 -0
  561. package/src/StringInterner.ts +72 -0
  562. package/src/Summary.ts +48 -0
  563. package/src/SummaryBackCompatibility.ts +47 -57
  564. package/src/SummaryTestUtilities.ts +54 -0
  565. package/src/Transaction.ts +94 -0
  566. package/src/TransactionInternal.ts +1088 -0
  567. package/src/TreeCompressor.ts +213 -0
  568. package/src/TreeNodeHandle.ts +19 -32
  569. package/src/TreeView.ts +322 -0
  570. package/src/TreeViewUtilities.ts +77 -0
  571. package/src/{default-edits/UndoRedoHandler.ts → UndoRedoHandler.ts} +8 -13
  572. package/src/id-compressor/AppendOnlySortedMap.ts +325 -0
  573. package/src/id-compressor/IdCompressor.md +3 -0
  574. package/src/id-compressor/IdCompressor.ts +1848 -0
  575. package/src/id-compressor/IdRange.ts +33 -0
  576. package/src/id-compressor/NumericUuid.ts +414 -0
  577. package/src/id-compressor/index.ts +13 -0
  578. package/src/id-compressor/persisted-types/0.0.1.ts +179 -0
  579. package/src/id-compressor/persisted-types/README.md +3 -0
  580. package/src/id-compressor/persisted-types/index.ts +6 -0
  581. package/src/index.ts +119 -59
  582. package/src/persisted-types/0.0.2.ts +442 -0
  583. package/src/persisted-types/0.1.1.ts +476 -0
  584. package/src/persisted-types/README.md +22 -0
  585. package/src/persisted-types/index.ts +9 -0
  586. package/.mocharc.js +0 -41
  587. package/api/tree.api.md +0 -729
  588. package/dist/BasicCheckout.d.ts +0 -23
  589. package/dist/BasicCheckout.d.ts.map +0 -1
  590. package/dist/BasicCheckout.js.map +0 -1
  591. package/dist/Snapshot.d.ts +0 -198
  592. package/dist/Snapshot.d.ts.map +0 -1
  593. package/dist/Snapshot.js +0 -267
  594. package/dist/Snapshot.js.map +0 -1
  595. package/dist/SnapshotUtilities.d.ts +0 -29
  596. package/dist/SnapshotUtilities.d.ts.map +0 -1
  597. package/dist/SnapshotUtilities.js +0 -73
  598. package/dist/SnapshotUtilities.js.map +0 -1
  599. package/dist/anchored-edits/AnchorResolution.d.ts +0 -144
  600. package/dist/anchored-edits/AnchorResolution.d.ts.map +0 -1
  601. package/dist/anchored-edits/AnchorResolution.js +0 -162
  602. package/dist/anchored-edits/AnchorResolution.js.map +0 -1
  603. package/dist/anchored-edits/Factory.d.ts +0 -56
  604. package/dist/anchored-edits/Factory.d.ts.map +0 -1
  605. package/dist/anchored-edits/Factory.js +0 -79
  606. package/dist/anchored-edits/Factory.js.map +0 -1
  607. package/dist/anchored-edits/PersistedTypes.d.ts +0 -245
  608. package/dist/anchored-edits/PersistedTypes.d.ts.map +0 -1
  609. package/dist/anchored-edits/PersistedTypes.js +0 -131
  610. package/dist/anchored-edits/PersistedTypes.js.map +0 -1
  611. package/dist/anchored-edits/SharedTreeWithAnchors.d.ts +0 -120
  612. package/dist/anchored-edits/SharedTreeWithAnchors.d.ts.map +0 -1
  613. package/dist/anchored-edits/SharedTreeWithAnchors.js +0 -115
  614. package/dist/anchored-edits/SharedTreeWithAnchors.js.map +0 -1
  615. package/dist/anchored-edits/TransactionWithAnchors.d.ts +0 -28
  616. package/dist/anchored-edits/TransactionWithAnchors.d.ts.map +0 -1
  617. package/dist/anchored-edits/TransactionWithAnchors.js +0 -36
  618. package/dist/anchored-edits/TransactionWithAnchors.js.map +0 -1
  619. package/dist/anchored-edits/index.d.ts +0 -10
  620. package/dist/anchored-edits/index.d.ts.map +0 -1
  621. package/dist/anchored-edits/index.js +0 -34
  622. package/dist/anchored-edits/index.js.map +0 -1
  623. package/dist/default-edits/EditUtilities.d.ts +0 -57
  624. package/dist/default-edits/EditUtilities.d.ts.map +0 -1
  625. package/dist/default-edits/EditUtilities.js +0 -192
  626. package/dist/default-edits/EditUtilities.js.map +0 -1
  627. package/dist/default-edits/Factory.d.ts +0 -56
  628. package/dist/default-edits/Factory.d.ts.map +0 -1
  629. package/dist/default-edits/Factory.js +0 -79
  630. package/dist/default-edits/Factory.js.map +0 -1
  631. package/dist/default-edits/HistoryEditFactory.d.ts +0 -19
  632. package/dist/default-edits/HistoryEditFactory.d.ts.map +0 -1
  633. package/dist/default-edits/HistoryEditFactory.js +0 -187
  634. package/dist/default-edits/HistoryEditFactory.js.map +0 -1
  635. package/dist/default-edits/PersistedTypes.d.ts.map +0 -1
  636. package/dist/default-edits/PersistedTypes.js.map +0 -1
  637. package/dist/default-edits/SharedTree.d.ts +0 -111
  638. package/dist/default-edits/SharedTree.d.ts.map +0 -1
  639. package/dist/default-edits/SharedTree.js +0 -124
  640. package/dist/default-edits/SharedTree.js.map +0 -1
  641. package/dist/default-edits/Summary.d.ts +0 -15
  642. package/dist/default-edits/Summary.d.ts.map +0 -1
  643. package/dist/default-edits/Summary.js +0 -35
  644. package/dist/default-edits/Summary.js.map +0 -1
  645. package/dist/default-edits/Transaction.d.ts +0 -41
  646. package/dist/default-edits/Transaction.d.ts.map +0 -1
  647. package/dist/default-edits/Transaction.js +0 -225
  648. package/dist/default-edits/Transaction.js.map +0 -1
  649. package/dist/default-edits/UndoRedoHandler.d.ts.map +0 -1
  650. package/dist/default-edits/UndoRedoHandler.js.map +0 -1
  651. package/dist/default-edits/index.d.ts +0 -13
  652. package/dist/default-edits/index.d.ts.map +0 -1
  653. package/dist/default-edits/index.js +0 -41
  654. package/dist/default-edits/index.js.map +0 -1
  655. package/dist/generic/GenericEditUtilities.d.ts +0 -26
  656. package/dist/generic/GenericEditUtilities.d.ts.map +0 -1
  657. package/dist/generic/GenericEditUtilities.js +0 -45
  658. package/dist/generic/GenericEditUtilities.js.map +0 -1
  659. package/dist/generic/GenericSharedTree.d.ts +0 -221
  660. package/dist/generic/GenericSharedTree.d.ts.map +0 -1
  661. package/dist/generic/GenericSharedTree.js +0 -447
  662. package/dist/generic/GenericSharedTree.js.map +0 -1
  663. package/dist/generic/GenericTransaction.d.ts +0 -87
  664. package/dist/generic/GenericTransaction.d.ts.map +0 -1
  665. package/dist/generic/GenericTransaction.js +0 -144
  666. package/dist/generic/GenericTransaction.js.map +0 -1
  667. package/dist/generic/PersistedTypes.d.ts +0 -194
  668. package/dist/generic/PersistedTypes.d.ts.map +0 -1
  669. package/dist/generic/PersistedTypes.js +0 -42
  670. package/dist/generic/PersistedTypes.js.map +0 -1
  671. package/dist/generic/Summary.d.ts +0 -63
  672. package/dist/generic/Summary.d.ts.map +0 -1
  673. package/dist/generic/Summary.js +0 -64
  674. package/dist/generic/Summary.js.map +0 -1
  675. package/dist/generic/index.d.ts +0 -10
  676. package/dist/generic/index.d.ts.map +0 -1
  677. package/dist/generic/index.js +0 -26
  678. package/dist/generic/index.js.map +0 -1
  679. package/lib/BasicCheckout.d.ts +0 -23
  680. package/lib/BasicCheckout.d.ts.map +0 -1
  681. package/lib/BasicCheckout.js.map +0 -1
  682. package/lib/Snapshot.d.ts +0 -198
  683. package/lib/Snapshot.d.ts.map +0 -1
  684. package/lib/Snapshot.js +0 -263
  685. package/lib/Snapshot.js.map +0 -1
  686. package/lib/SnapshotUtilities.d.ts +0 -29
  687. package/lib/SnapshotUtilities.d.ts.map +0 -1
  688. package/lib/SnapshotUtilities.js +0 -67
  689. package/lib/SnapshotUtilities.js.map +0 -1
  690. package/lib/anchored-edits/AnchorResolution.d.ts +0 -144
  691. package/lib/anchored-edits/AnchorResolution.d.ts.map +0 -1
  692. package/lib/anchored-edits/AnchorResolution.js +0 -152
  693. package/lib/anchored-edits/AnchorResolution.js.map +0 -1
  694. package/lib/anchored-edits/Factory.d.ts +0 -56
  695. package/lib/anchored-edits/Factory.d.ts.map +0 -1
  696. package/lib/anchored-edits/Factory.js +0 -74
  697. package/lib/anchored-edits/Factory.js.map +0 -1
  698. package/lib/anchored-edits/PersistedTypes.d.ts +0 -245
  699. package/lib/anchored-edits/PersistedTypes.d.ts.map +0 -1
  700. package/lib/anchored-edits/PersistedTypes.js +0 -128
  701. package/lib/anchored-edits/PersistedTypes.js.map +0 -1
  702. package/lib/anchored-edits/SharedTreeWithAnchors.d.ts +0 -120
  703. package/lib/anchored-edits/SharedTreeWithAnchors.d.ts.map +0 -1
  704. package/lib/anchored-edits/SharedTreeWithAnchors.js +0 -110
  705. package/lib/anchored-edits/SharedTreeWithAnchors.js.map +0 -1
  706. package/lib/anchored-edits/TransactionWithAnchors.d.ts +0 -28
  707. package/lib/anchored-edits/TransactionWithAnchors.d.ts.map +0 -1
  708. package/lib/anchored-edits/TransactionWithAnchors.js +0 -32
  709. package/lib/anchored-edits/TransactionWithAnchors.js.map +0 -1
  710. package/lib/anchored-edits/index.d.ts +0 -10
  711. package/lib/anchored-edits/index.d.ts.map +0 -1
  712. package/lib/anchored-edits/index.js +0 -11
  713. package/lib/anchored-edits/index.js.map +0 -1
  714. package/lib/default-edits/EditUtilities.d.ts +0 -57
  715. package/lib/default-edits/EditUtilities.d.ts.map +0 -1
  716. package/lib/default-edits/EditUtilities.js +0 -181
  717. package/lib/default-edits/EditUtilities.js.map +0 -1
  718. package/lib/default-edits/Factory.d.ts +0 -56
  719. package/lib/default-edits/Factory.d.ts.map +0 -1
  720. package/lib/default-edits/Factory.js +0 -74
  721. package/lib/default-edits/Factory.js.map +0 -1
  722. package/lib/default-edits/HistoryEditFactory.d.ts +0 -19
  723. package/lib/default-edits/HistoryEditFactory.d.ts.map +0 -1
  724. package/lib/default-edits/HistoryEditFactory.js.map +0 -1
  725. package/lib/default-edits/PersistedTypes.d.ts.map +0 -1
  726. package/lib/default-edits/PersistedTypes.js.map +0 -1
  727. package/lib/default-edits/SharedTree.d.ts +0 -111
  728. package/lib/default-edits/SharedTree.d.ts.map +0 -1
  729. package/lib/default-edits/SharedTree.js +0 -100
  730. package/lib/default-edits/SharedTree.js.map +0 -1
  731. package/lib/default-edits/Summary.d.ts +0 -15
  732. package/lib/default-edits/Summary.d.ts.map +0 -1
  733. package/lib/default-edits/Summary.js +0 -31
  734. package/lib/default-edits/Summary.js.map +0 -1
  735. package/lib/default-edits/Transaction.d.ts +0 -41
  736. package/lib/default-edits/Transaction.d.ts.map +0 -1
  737. package/lib/default-edits/Transaction.js +0 -221
  738. package/lib/default-edits/Transaction.js.map +0 -1
  739. package/lib/default-edits/UndoRedoHandler.d.ts.map +0 -1
  740. package/lib/default-edits/UndoRedoHandler.js.map +0 -1
  741. package/lib/default-edits/index.d.ts +0 -13
  742. package/lib/default-edits/index.d.ts.map +0 -1
  743. package/lib/default-edits/index.js +0 -14
  744. package/lib/default-edits/index.js.map +0 -1
  745. package/lib/generic/GenericEditUtilities.d.ts +0 -26
  746. package/lib/generic/GenericEditUtilities.d.ts.map +0 -1
  747. package/lib/generic/GenericEditUtilities.js +0 -38
  748. package/lib/generic/GenericEditUtilities.js.map +0 -1
  749. package/lib/generic/GenericSharedTree.d.ts +0 -221
  750. package/lib/generic/GenericSharedTree.d.ts.map +0 -1
  751. package/lib/generic/GenericSharedTree.js +0 -443
  752. package/lib/generic/GenericSharedTree.js.map +0 -1
  753. package/lib/generic/GenericTransaction.d.ts +0 -87
  754. package/lib/generic/GenericTransaction.d.ts.map +0 -1
  755. package/lib/generic/GenericTransaction.js +0 -140
  756. package/lib/generic/GenericTransaction.js.map +0 -1
  757. package/lib/generic/PersistedTypes.d.ts +0 -194
  758. package/lib/generic/PersistedTypes.d.ts.map +0 -1
  759. package/lib/generic/PersistedTypes.js +0 -39
  760. package/lib/generic/PersistedTypes.js.map +0 -1
  761. package/lib/generic/Summary.d.ts +0 -63
  762. package/lib/generic/Summary.d.ts.map +0 -1
  763. package/lib/generic/Summary.js +0 -58
  764. package/lib/generic/Summary.js.map +0 -1
  765. package/lib/generic/index.d.ts +0 -10
  766. package/lib/generic/index.d.ts.map +0 -1
  767. package/lib/generic/index.js +0 -11
  768. package/lib/generic/index.js.map +0 -1
  769. package/lib/test/Anchors.glassBox.tests.d.ts.map +0 -1
  770. package/lib/test/Anchors.glassBox.tests.js +0 -410
  771. package/lib/test/Anchors.glassBox.tests.js.map +0 -1
  772. package/lib/test/BasicCheckout.tests.d.ts.map +0 -1
  773. package/lib/test/BasicCheckout.tests.js +0 -8
  774. package/lib/test/BasicCheckout.tests.js.map +0 -1
  775. package/lib/test/GenericTransactionWithAnchors.tests.d.ts.map +0 -1
  776. package/lib/test/GenericTransactionWithAnchors.tests.js +0 -25
  777. package/lib/test/GenericTransactionWithAnchors.tests.js.map +0 -1
  778. package/lib/test/SharedTreeWithAnchors.tests.d.ts.map +0 -1
  779. package/lib/test/SharedTreeWithAnchors.tests.js +0 -420
  780. package/lib/test/SharedTreeWithAnchors.tests.js.map +0 -1
  781. package/lib/test/Snapshot.tests.d.ts.map +0 -1
  782. package/lib/test/Snapshot.tests.js +0 -96
  783. package/lib/test/Snapshot.tests.js.map +0 -1
  784. package/lib/test/SnapshotUtilities.tests.d.ts.map +0 -1
  785. package/lib/test/SnapshotUtilities.tests.js +0 -168
  786. package/lib/test/SnapshotUtilities.tests.js.map +0 -1
  787. package/lib/test/undoRedoStackManager.d.ts +0 -26
  788. package/lib/test/undoRedoStackManager.d.ts.map +0 -1
  789. package/lib/test/undoRedoStackManager.js +0 -176
  790. package/lib/test/undoRedoStackManager.js.map +0 -1
  791. package/lib/test/utilities/SummaryFormatCompatibilityTests.d.ts +0 -13
  792. package/lib/test/utilities/SummaryFormatCompatibilityTests.d.ts.map +0 -1
  793. package/lib/test/utilities/SummaryFormatCompatibilityTests.js +0 -154
  794. package/lib/test/utilities/SummaryFormatCompatibilityTests.js.map +0 -1
  795. package/src/BasicCheckout.ts +0 -34
  796. package/src/Snapshot.ts +0 -363
  797. package/src/SnapshotUtilities.ts +0 -88
  798. package/src/anchored-edits/AnchorResolution.ts +0 -442
  799. package/src/anchored-edits/Factory.ts +0 -94
  800. package/src/anchored-edits/PersistedTypes.ts +0 -310
  801. package/src/anchored-edits/SharedTreeWithAnchors.ts +0 -200
  802. package/src/anchored-edits/TransactionWithAnchors.ts +0 -39
  803. package/src/anchored-edits/index.ts +0 -21
  804. package/src/default-edits/EditUtilities.ts +0 -220
  805. package/src/default-edits/Factory.ts +0 -94
  806. package/src/default-edits/SharedTree.ts +0 -174
  807. package/src/default-edits/Summary.ts +0 -44
  808. package/src/default-edits/Transaction.ts +0 -262
  809. package/src/default-edits/index.ts +0 -29
  810. package/src/generic/GenericEditUtilities.ts +0 -46
  811. package/src/generic/GenericSharedTree.ts +0 -593
  812. package/src/generic/GenericTransaction.ts +0 -194
  813. package/src/generic/PersistedTypes.ts +0 -221
  814. package/src/generic/Summary.ts +0 -113
  815. package/src/generic/index.ts +0 -41
package/dist/LogViewer.js CHANGED
@@ -10,32 +10,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.CachingLogViewer = void 0;
11
11
  const denque_1 = __importDefault(require("denque"));
12
12
  const Common_1 = require("./Common");
13
- const Snapshot_1 = require("./Snapshot");
14
- const generic_1 = require("./generic");
15
13
  const RevisionValueCache_1 = require("./RevisionValueCache");
16
- const InitialTree_1 = require("./InitialTree");
14
+ const persisted_types_1 = require("./persisted-types");
17
15
  /**
18
- * Creates Snapshots for revisions associated with an EditLog and caches the results.
16
+ * Creates views for revisions associated with an EditLog and caches the results.
17
+ *
18
+ * Does so by listening for edits added to the log. If the underlying EditLog or its listeners need to be reused beyond the lifetime of
19
+ * a CachingLogViewer instance, that instance should be disposed with `detachFromEditLog` to ensure it is garbage-collectable.
19
20
  * @internal
20
21
  */
21
22
  class CachingLogViewer {
22
23
  /**
23
24
  * Create a new LogViewer
24
- * @param log - the edit log which snapshots will be based on.
25
- * @param baseTree - the tree used in the snapshot corresponding to the 0th revision. Defaults to `initialTree`.
26
- * @param knownRevisions - a set of [sequencedRevision, snapshot] pairs that are known (have been precomputed) at construction time.
25
+ * @param log - the edit log which revisions will be based on.
26
+ * @param baseTree - the tree used in the view corresponding to the 0th revision.
27
+ * @param knownRevisions - a set of [sequencedRevision, view] pairs that are known (have been precomputed) at construction time.
27
28
  * These revisions are guaranteed to never be evicted from the cache.
28
29
  * @param expensiveValidation - Iff true, additional correctness assertions will be run during LogViewer operations.
29
30
  * @param processEditStatus - called after applying an edit.
30
- * @param logger - used to log telemetry
31
+ * @param processSequencedEditResult - called after applying a sequenced edit.
31
32
  */
32
- constructor(log, baseSnapshot = Snapshot_1.Snapshot.fromTree(InitialTree_1.initialTree), knownRevisions = [], expensiveValidation = false, processEditStatus = Common_1.noop, logger, transactionFactory, minimumSequenceNumber = 0) {
33
+ constructor(log, baseView, knownRevisions = [], expensiveValidation = false, processEditStatus = Common_1.noop, processSequencedEditResult = Common_1.noop, transactionFactory, minimumSequenceNumber = 0) {
34
+ this.transactionFactory = transactionFactory;
33
35
  /**
34
- * A cache for local snapshots.
36
+ * A cache for local revisions.
35
37
  * It is invalidated whenever a new sequenced edit (that was not already a local edit) is added to the log.
36
38
  * When a previously local edit is sequenced, this cache is adjusted to account for it, not invalidated.
37
39
  */
38
- this.localSnapshotCache = new denque_1.default();
40
+ this.localRevisionCache = new denque_1.default();
39
41
  /**
40
42
  * The ordered queue of edits that originated from this client that have never been applied (by this log viewer) in a sequenced state.
41
43
  * This means these edits may be local or sequenced, and may have been applied (possibly multiple times) while still local.
@@ -49,19 +51,27 @@ class CachingLogViewer {
49
51
  Common_1.assert(this.log.isSequencedRevision(revision), 'revision must correspond to the result of a SequencedEdit');
50
52
  });
51
53
  }
52
- this.sequencedSnapshotCache = new RevisionValueCache_1.RevisionValueCache(CachingLogViewer.sequencedCacheSizeMax, minimumSequenceNumber, [...knownRevisions, [0, { snapshot: baseSnapshot }]]);
54
+ this.sequencedRevisionCache = new RevisionValueCache_1.RevisionValueCache(CachingLogViewer.sequencedCacheSizeMax, minimumSequenceNumber, [...knownRevisions, [0, { view: baseView }]]);
53
55
  this.processEditStatus = processEditStatus !== null && processEditStatus !== void 0 ? processEditStatus : Common_1.noop;
56
+ this.processSequencedEditResult = processSequencedEditResult !== null && processSequencedEditResult !== void 0 ? processSequencedEditResult : Common_1.noop;
54
57
  this.expensiveValidation = expensiveValidation;
55
- this.logger = logger;
56
58
  this.transactionFactory = transactionFactory;
57
- this.log.registerEditAddedHandler(this.handleEditAdded.bind(this));
59
+ this.detachFromEditLog = this.log.registerEditAddedHandler(this.handleEditAdded.bind(this));
58
60
  }
59
61
  /**
60
- * Performs the tracking needed to log telemetry about failed (invalid/malformed) local edits when they are sequenced.
61
- * As a performance optimization, this method also caches snapshots generated by local edits if they are sequenced without
62
+ * @returns true if the highest revision is cached.
63
+ */
64
+ highestRevisionCached() {
65
+ return this.highestRevisionCacheEntry !== undefined;
66
+ }
67
+ /**
68
+ * As a performance optimization, this method caches views generated by local edits if they are sequenced without
62
69
  * being interleaved with remote edits.
63
70
  */
64
71
  handleEditAdded(edit, isLocal, wasLocal) {
72
+ // Clear highestRevisionCacheEntry, since what revision is highest might change.
73
+ // Note that as an optimization we could skip clearing this when a local edit is sequenced.
74
+ this.highestRevisionCacheEntry = undefined;
65
75
  if (isLocal) {
66
76
  this.unappliedSelfEdits.push(edit.id);
67
77
  }
@@ -69,26 +79,27 @@ class CachingLogViewer {
69
79
  // If the new sequenced edit was generated by this client, the corresponding cache entry (if there is one)
70
80
  // will be at the front of the queue. If the queue is empty, then a concurrent sequenced edit from remote client
71
81
  // must have invalidated the queue cache.
72
- const entry = this.localSnapshotCache.shift();
82
+ const entry = this.localRevisionCache.shift();
73
83
  if (entry !== undefined) {
74
84
  const revision = this.log.numberOfSequencedEdits;
75
- const snapshot = entry.snapshot;
76
- this.sequencedSnapshotCache.cacheValue(revision, entry.status === generic_1.EditStatus.Applied
85
+ const { view } = entry;
86
+ this.sequencedRevisionCache.cacheValue(revision, entry.status === persisted_types_1.EditStatus.Applied
77
87
  ? {
78
- snapshot,
88
+ view,
79
89
  status: entry.status,
80
90
  steps: entry.steps,
81
91
  }
82
92
  : {
83
- snapshot,
93
+ view,
84
94
  status: entry.status,
95
+ failure: entry.failure,
85
96
  });
86
- this.handleSequencedEditResult(edit, entry);
97
+ this.handleSequencedEditResult(edit, entry, []);
87
98
  }
88
99
  }
89
100
  else {
90
101
  // Invalidate any cached results of applying edits which are ordered after `edit` (which are all remaining local edits)
91
- this.localSnapshotCache.clear();
102
+ this.localRevisionCache.clear();
92
103
  }
93
104
  }
94
105
  async getEditResult(revision) {
@@ -97,12 +108,12 @@ class CachingLogViewer {
97
108
  let current = startingPoint;
98
109
  for (let i = startRevision; i < revision && i < this.log.length; i++) {
99
110
  const edit = await this.log.getEditAtIndex(i);
100
- current = this.applyEdit(current.snapshot, edit, i);
111
+ current = this.applyEdit(current.view, edit, i);
101
112
  }
102
113
  return current;
103
114
  }
104
- async getSnapshot(revision) {
105
- return (await this.getEditResult(revision)).snapshot;
115
+ async getRevisionView(revision) {
116
+ return (await this.getEditResult(revision)).view;
106
117
  }
107
118
  getEditResultInSession(revision) {
108
119
  const startingPoint = this.getStartingPoint(revision);
@@ -110,12 +121,12 @@ class CachingLogViewer {
110
121
  let current = startingPoint;
111
122
  for (let i = startRevision; i < revision && i < this.log.length; i++) {
112
123
  const edit = this.log.getEditInSessionAtIndex(i);
113
- current = this.applyEdit(current.snapshot, edit, i);
124
+ current = this.applyEdit(current.view, edit, i);
114
125
  }
115
126
  return current;
116
127
  }
117
- getSnapshotInSession(revision) {
118
- return this.getEditResultInSession(revision).snapshot;
128
+ getRevisionViewInSession(revision) {
129
+ return this.getEditResultInSession(revision).view;
119
130
  }
120
131
  /**
121
132
  * Informs the CachingLogViewer of the latest known minimumSequenceNumber for all connected clients.
@@ -127,111 +138,114 @@ class CachingLogViewer {
127
138
  // Sequence numbers in Fluid are 1-indexed, meaning they correspond to revisions, and can be used as revisions.
128
139
  // This ensures that all revisions >= minimumSequenceNumber are kept in the cache, meaning that even if all clients are caught up
129
140
  // the most recent sequenced revision will be cached.
130
- this.sequencedSnapshotCache.updateRetentionWindow(minimumSequenceNumber);
141
+ this.sequencedRevisionCache.updateRetentionWindow(minimumSequenceNumber);
131
142
  }
132
143
  /**
133
- * Inform the CachingLogViewer that a particular edit is know to have a specific result when applied to a particular Snapshot.
134
- * LogViewer may use this information to as a optimization to avoid re-running the edit if re-applied to the same Snapshot.
144
+ * Inform the CachingLogViewer that a particular edit is known to have a specific result when applied to a particular TreeView.
145
+ * CachingLogViewer may use this information as an optimization to avoid re-running the edit if re-applied to the same TreeView.
135
146
  */
136
147
  setKnownEditingResult(edit, result) {
137
148
  this.cachedEditResult = { editId: edit.id, result };
138
149
  }
139
150
  /**
140
- * @returns the cached snapshot closest to the requested `revision`.
151
+ * @returns the cached revision view closest to the requested `revision`.
141
152
  */
142
153
  getStartingPoint(revision) {
143
154
  var _a, _b, _c;
144
- // Per the documentation for revision, the returned snapshot should be the output of the edit at the largest index <= `revision`.
155
+ // Per the documentation for revision, the returned view should be the output of the edit at the largest index <= `revision`.
145
156
  const revisionClamped = Math.min(revision, this.log.length);
157
+ // If the highest revision is requested, and it's cached, use highestRevisionCacheEntry.
158
+ if (revisionClamped === this.log.length && this.highestRevisionCacheEntry !== undefined) {
159
+ return Object.assign(Object.assign({}, this.highestRevisionCacheEntry), { startRevision: revisionClamped });
160
+ }
146
161
  let current;
147
162
  let startRevision;
148
163
  const { numberOfSequencedEdits } = this.log;
149
164
  const isLocalRevision = revisionClamped > numberOfSequencedEdits;
150
- if (isLocalRevision && !this.localSnapshotCache.isEmpty()) {
151
- const { length } = this.localSnapshotCache;
152
- // Local snapshot cache is indexed such that the snapshot for revision 0 (a local edit) is stored at index 0 in the cache.
165
+ if (isLocalRevision && !this.localRevisionCache.isEmpty()) {
166
+ const { length } = this.localRevisionCache;
167
+ // Local revision view cache is indexed such that the view for revision 0 (a local edit) is stored at index 0 in the cache.
153
168
  // This is because the local cache does not contain an entry for the implicit initial tree edit.
154
169
  const localCacheIndex = revisionClamped - 1 - numberOfSequencedEdits;
155
170
  if (localCacheIndex < length) {
156
- const cached = (_a = this.localSnapshotCache.peekAt(localCacheIndex)) !== null && _a !== void 0 ? _a : Common_1.fail('missing tail of localSnapshotCache');
171
+ const cached = (_a = this.localRevisionCache.peekAt(localCacheIndex)) !== null && _a !== void 0 ? _a : Common_1.fail('missing tail of localRevisionViewCache');
157
172
  return Object.assign(Object.assign({}, cached), { startRevision: revisionClamped });
158
173
  }
159
174
  else {
160
- current = (_b = this.localSnapshotCache.peekAt(length - 1)) !== null && _b !== void 0 ? _b : Common_1.fail('missing tail of localSnapshotCache');
175
+ current = (_b = this.localRevisionCache.peekAt(length - 1)) !== null && _b !== void 0 ? _b : Common_1.fail('missing tail of localRevisionViewCache');
161
176
  startRevision = numberOfSequencedEdits + length;
162
177
  }
163
178
  }
164
179
  else {
165
- const [cachedRevision, cachedSnapshot] = (_c = this.sequencedSnapshotCache.getClosestEntry(revisionClamped)) !== null && _c !== void 0 ? _c : Common_1.fail('No preceding snapshot cached.');
180
+ const [cachedRevision, cachedView] = (_c = this.sequencedRevisionCache.getClosestEntry(revisionClamped)) !== null && _c !== void 0 ? _c : Common_1.fail('No preceding revision view cached.');
166
181
  startRevision = cachedRevision;
167
- current = cachedSnapshot;
182
+ current = cachedView;
168
183
  }
169
184
  return Object.assign({ startRevision }, current);
170
185
  }
171
186
  /**
172
- * Helper for applying an edit at the supplied snapshot.
187
+ * Helper for applying an edit at the supplied revision view.
173
188
  * Must only be called in the order that edits appear in the log.
174
189
  * Must only be called once for a given local edit as long as the local cache has not been invalidated.
175
190
  * Must only be called once for a given sequenced edit.
176
- * @returns the resulting snapshot and the outcome of edit that produced it.
191
+ * @returns the resulting revision view and the outcome of edit that produced it.
177
192
  */
178
- applyEdit(prevSnapshot, edit, editIndex) {
193
+ applyEdit(prevView, edit, editIndex) {
179
194
  let editingResult;
180
195
  let cached;
196
+ let reconciliationPath = [];
181
197
  if (this.cachedEditResult !== undefined &&
182
198
  this.cachedEditResult.editId === edit.id &&
183
- this.cachedEditResult.result.before === prevSnapshot) {
199
+ this.cachedEditResult.result.before === prevView) {
184
200
  editingResult = this.cachedEditResult.result;
185
201
  cached = true;
186
202
  }
187
203
  else {
188
- editingResult = this.transactionFactory(prevSnapshot)
189
- .applyChanges(edit.changes, this.reconciliationPathFromEdit(edit.id))
190
- .close();
204
+ reconciliationPath = this.reconciliationPathFromEdit(edit.id);
205
+ editingResult = this.transactionFactory(prevView).applyChanges(edit.changes, reconciliationPath).close();
191
206
  cached = false;
192
207
  }
193
208
  const revision = editIndex + 1;
194
- let nextSnapshot;
195
- if (editingResult.status === generic_1.EditStatus.Applied) {
196
- nextSnapshot = editingResult.after;
209
+ let nextView;
210
+ if (editingResult.status === persisted_types_1.EditStatus.Applied) {
211
+ nextView = editingResult.after;
197
212
  }
198
213
  else {
199
- nextSnapshot = prevSnapshot;
214
+ nextView = prevView;
200
215
  }
201
- const computedCacheEntry = editingResult.status === generic_1.EditStatus.Applied
202
- ? { snapshot: nextSnapshot, status: editingResult.status, steps: editingResult.steps }
203
- : { snapshot: nextSnapshot, status: editingResult.status };
216
+ const computedCacheEntry = editingResult.status === persisted_types_1.EditStatus.Applied
217
+ ? { view: nextView, status: editingResult.status, steps: editingResult.steps }
218
+ : { view: nextView, status: editingResult.status, failure: editingResult.failure };
204
219
  if (this.log.isSequencedRevision(revision)) {
205
- this.sequencedSnapshotCache.cacheValue(revision, computedCacheEntry);
206
- this.handleSequencedEditResult(edit, computedCacheEntry);
220
+ this.sequencedRevisionCache.cacheValue(revision, computedCacheEntry);
221
+ this.handleSequencedEditResult(edit, computedCacheEntry, reconciliationPath);
207
222
  }
208
223
  else {
209
- // This relies on local edits being append only, and that generating the snapshot for a local revision requires generating
210
- // the snapshot for all local revisions before it in the log. Thus, generating such a snapshot will necessarily require
224
+ // This relies on local edits being append only, and that generating the view for a local revision requires generating
225
+ // the views for all local revisions before it in the log. Thus, generating such a view will necessarily require
211
226
  // calls to this method for all local revisions prior, guaranteeing the correct push order.
212
- Common_1.assert(revision === this.log.numberOfSequencedEdits + this.localSnapshotCache.length + 1, 'Local snapshot cached out of order.');
213
- this.localSnapshotCache.push(computedCacheEntry);
227
+ Common_1.assert(revision === this.log.numberOfSequencedEdits + this.localRevisionCache.length + 1, 'Local revision view cached out of order.');
228
+ this.localRevisionCache.push(computedCacheEntry);
229
+ }
230
+ // Only update highestRevisionCacheEntry if this snapshot is the highest revision.
231
+ if (revision >= this.log.length) {
232
+ this.highestRevisionCacheEntry = computedCacheEntry;
214
233
  }
215
234
  this.processEditStatus(editingResult.status, this.log.getIdAtIndex(editIndex), cached);
216
235
  return computedCacheEntry;
217
236
  }
218
237
  /**
219
- * Helper for performing caching and telemetry logging when a sequenced local edit is first applied.
238
+ * Helper for performing caching when a sequenced local edit is first applied.
239
+ * Invokes the `processSequencedEditResult` handler that was passed to the constructor (if any).
220
240
  * Must only be called for non-cached sequenced edits.
221
241
  */
222
- handleSequencedEditResult(edit, result) {
242
+ handleSequencedEditResult(edit, result, reconciliationPath) {
243
+ let wasLocal = false;
223
244
  // This is the first time this sequenced edit has been processed by this LogViewer. If it was a local edit, log telemetry
224
245
  // in the event that it was invalid or malformed.
225
246
  if (this.unappliedSelfEdits.length > 0) {
226
247
  if (edit.id === this.unappliedSelfEdits.peekFront()) {
227
- if (result.status !== generic_1.EditStatus.Applied) {
228
- this.logger.send({
229
- category: 'generic',
230
- eventName: result.status === generic_1.EditStatus.Malformed
231
- ? 'MalformedSharedTreeEdit'
232
- : 'InvalidSharedTreeEdit',
233
- });
234
- }
248
+ wasLocal = true;
235
249
  this.unappliedSelfEdits.shift();
236
250
  }
237
251
  else if (this.expensiveValidation) {
@@ -240,6 +254,7 @@ class CachingLogViewer {
240
254
  }
241
255
  }
242
256
  }
257
+ this.processSequencedEditResult({ edit, wasLocal, result, reconciliationPath });
243
258
  }
244
259
  /**
245
260
  * We currently compute only the "main branch" part of the reconciliation path (meaning we don't include inverts of the edits
@@ -263,15 +278,20 @@ class CachingLogViewer {
263
278
  if (targetSequenceNumber < orderedId.sequenceInfo.sequenceNumber) {
264
279
  const firstEdit = this.getEditResultFromSequenceNumber(targetSequenceNumber);
265
280
  if (firstEdit !== undefined) {
266
- if (firstEdit.status === generic_1.EditStatus.Applied) {
267
- reconciliationPath.push(Object.assign(Object.assign({}, firstEdit.steps), { before: firstEdit.before, after: firstEdit.after, length: firstEdit.steps.length }));
281
+ if (firstEdit.status === persisted_types_1.EditStatus.Applied) {
282
+ const firstEditInfo = this.log.getOrderedEditId(firstEdit.id);
283
+ if (firstEditInfo.sequenceInfo !== undefined &&
284
+ firstEditInfo.sequenceInfo.sequenceNumber >
285
+ orderedId.sequenceInfo.referenceSequenceNumber) {
286
+ reconciliationPath.push(Object.assign(Object.assign({}, firstEdit.steps), { before: firstEdit.before, after: firstEdit.view, length: firstEdit.steps.length }));
287
+ }
268
288
  }
269
289
  const lowestIndex = this.log.getIndexOfId(firstEdit.id) + 1;
270
290
  const highestIndex = this.log.getIndexOfId(editId) - 1;
271
291
  for (let index = lowestIndex; index <= highestIndex; ++index) {
272
292
  const edit = this.getEditResultFromIndex(index);
273
- if (edit.status === generic_1.EditStatus.Applied) {
274
- reconciliationPath.push(Object.assign(Object.assign({}, edit.steps), { before: edit.before, after: edit.after, length: edit.steps.length }));
293
+ if (edit.status === persisted_types_1.EditStatus.Applied) {
294
+ reconciliationPath.push(Object.assign(Object.assign({}, edit.steps), { before: edit.before, after: edit.view, length: edit.steps.length }));
275
295
  }
276
296
  }
277
297
  }
@@ -303,30 +323,33 @@ class CachingLogViewer {
303
323
  */
304
324
  getEditResultFromIndex(index) {
305
325
  const edit = this.log.getEditInSessionAtIndex(index);
306
- const before = this.getSnapshotInSession(index);
326
+ const before = this.getRevisionViewInSession(index);
307
327
  const resultAfter = this.getEditResultInSession(index + 1);
308
328
  if (resultAfter.status === undefined) {
309
329
  Common_1.fail('The status of every edit in session should be known');
310
330
  }
311
- return resultAfter.status === generic_1.EditStatus.Applied
331
+ return resultAfter.status === persisted_types_1.EditStatus.Applied
312
332
  ? {
313
333
  id: edit.id,
314
- status: generic_1.EditStatus.Applied,
334
+ status: persisted_types_1.EditStatus.Applied,
315
335
  before,
316
336
  changes: edit.changes,
317
- after: resultAfter.snapshot,
337
+ view: resultAfter.view,
318
338
  steps: resultAfter.steps,
319
339
  }
320
340
  : {
321
341
  id: edit.id,
322
342
  status: resultAfter.status,
343
+ failure: resultAfter.failure,
323
344
  before,
345
+ view: resultAfter.view,
324
346
  changes: edit.changes,
325
347
  };
326
348
  }
327
349
  /**
328
350
  * @param sequenceNumber - The server-assigned sequenced number assigned to the edit of interest.
329
- * @returns Edit result information for the edit with the given sequence number. Undefined if no such edit is known.
351
+ * @returns Edit result information for the edit with the given sequence number or the nearest sequenced edit before that.
352
+ * Undefined if no sequenced edit occurred at or prior to the given sequenceNumber.
330
353
  */
331
354
  getEditResultFromSequenceNumber(sequenceNumber) {
332
355
  const earliestSequenced = this.earliestSequencedEditInSession();
@@ -343,24 +366,26 @@ class CachingLogViewer {
343
366
  // has been processed by a different DDS (several DDSes can share the same stream of operations and will only see those
344
367
  // relevant to them). In such cases, we return the edit info for the last known edit before that.
345
368
  if (orderedId.sequenceInfo && orderedId.sequenceInfo.sequenceNumber <= sequenceNumber) {
346
- const before = this.getSnapshotInSession(index);
369
+ const before = this.getRevisionViewInSession(index);
347
370
  const resultAfter = this.getEditResultInSession(index + 1);
348
371
  if (resultAfter.status === undefined) {
349
372
  Common_1.fail('The status of every edit in session should be known');
350
373
  }
351
- return resultAfter.status === generic_1.EditStatus.Applied
374
+ return resultAfter.status === persisted_types_1.EditStatus.Applied
352
375
  ? {
353
376
  id: edit.id,
354
- status: generic_1.EditStatus.Applied,
377
+ status: persisted_types_1.EditStatus.Applied,
355
378
  before,
356
379
  changes: edit.changes,
357
- after: resultAfter.snapshot,
380
+ view: resultAfter.view,
358
381
  steps: resultAfter.steps,
359
382
  }
360
383
  : {
361
384
  id: edit.id,
362
385
  status: resultAfter.status,
386
+ failure: resultAfter.failure,
363
387
  before,
388
+ view: resultAfter.view,
364
389
  changes: edit.changes,
365
390
  };
366
391
  }
@@ -371,7 +396,7 @@ class CachingLogViewer {
371
396
  }
372
397
  exports.CachingLogViewer = CachingLogViewer;
373
398
  /**
374
- * Maximum size of the sequenced snapshot cache.
399
+ * Maximum size of the sequenced revision cache.
375
400
  */
376
401
  CachingLogViewer.sequencedCacheSizeMax = 50;
377
402
  //# sourceMappingURL=LogViewer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LogViewer.js","sourceRoot":"","sources":["../src/LogViewer.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;AAGH,oDAA4B;AAC5B,qCAA8C;AAE9C,yCAAsC;AACtC,uCAAgF;AAEhF,6DAA0D;AAC1D,+CAA4C;AAiI5C;;;GAGG;AACH,MAAa,gBAAgB;IAsD5B;;;;;;;;;OASG;IACH,YACC,GAAqB,EACrB,eAAyB,mBAAQ,CAAC,QAAQ,CAAC,yBAAW,CAAC,EACvD,iBAAwD,EAAE,EAC1D,mBAAmB,GAAG,KAAK,EAC3B,oBAAwC,aAAI,EAC5C,MAA4B,EAC5B,kBAAuE,EACvE,qBAAqB,GAAG,CAAC;QAhE1B;;;;WAIG;QACc,uBAAkB,GAAG,IAAI,gBAAM,EAA0C,CAAC;QAwB3F;;;;WAIG;QACc,uBAAkB,GAAG,IAAI,gBAAM,EAAU,CAAC;QAgC1D,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,mBAAmB,EAAE;YACxB,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE;gBACrC,eAAM,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,6BAA6B,CAAC,CAAC;gBAClE,eAAM,CACL,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EACtC,2DAA2D,CAC3D,CAAC;YACH,CAAC,CAAC,CAAC;SACH;QAED,IAAI,CAAC,sBAAsB,GAAG,IAAI,uCAAkB,CACnD,gBAAgB,CAAC,qBAAqB,EACtC,qBAAqB,EACrB,CAAC,GAAG,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CACpD,CAAC;QACF,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,aAAjB,iBAAiB,cAAjB,iBAAiB,GAAI,aAAI,CAAC;QACnD,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;QAC/C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;QAC7C,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,CAAC;IAED;;;;OAIG;IACK,eAAe,CAAC,IAAmB,EAAE,OAAgB,EAAE,QAAiB;QAC/E,IAAI,OAAO,EAAE;YACZ,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACtC;aAAM,IAAI,QAAQ,EAAE;YACpB,0GAA0G;YAC1G,gHAAgH;YAChH,yCAAyC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;YAC9C,IAAI,KAAK,KAAK,SAAS,EAAE;gBACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC;gBACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;gBAChC,IAAI,CAAC,sBAAsB,CAAC,UAAU,CACrC,QAAQ,EACR,KAAK,CAAC,MAAM,KAAK,oBAAU,CAAC,OAAO;oBAClC,CAAC,CAAC;wBACA,QAAQ;wBACR,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;qBACjB;oBACH,CAAC,CAAC;wBACA,QAAQ;wBACR,MAAM,EAAE,KAAK,CAAC,MAAM;qBACnB,CACJ,CAAC;gBACF,IAAI,CAAC,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;aAC5C;SACD;aAAM;YACN,uHAAuH;YACvH,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;SAChC;IACF,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,QAAkB;QAC5C,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;QACxC,IAAI,OAAO,GAA4B,aAAa,CAAC;QACrD,KAAK,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,QAAQ,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;YAC9C,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;SACpD;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,QAAkB;QAC1C,OAAO,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IACtD,CAAC;IAEM,sBAAsB,CAAC,QAAkB;QAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;QACxC,IAAI,OAAO,GAA4B,aAAa,CAAC;QACrD,KAAK,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,QAAQ,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;YACjD,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;SACpD;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAEM,oBAAoB,CAAC,QAAkB;QAC7C,OAAO,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC;IACvD,CAAC;IAED;;;;;OAKG;IACI,wBAAwB,CAAC,qBAA6B;QAC5D,+GAA+G;QAC/G,iIAAiI;QACjI,qDAAqD;QACrD,IAAI,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;IAC1E,CAAC;IAED;;;OAGG;IACI,qBAAqB,CAAC,IAAmB,EAAE,MAA8B;QAC/E,IAAI,CAAC,gBAAgB,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC;IACrD,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,QAAkB;;QAC1C,iIAAiI;QACjI,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5D,IAAI,OAAgC,CAAC;QACrC,IAAI,aAAuB,CAAC;QAC5B,MAAM,EAAE,sBAAsB,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;QAC5C,MAAM,eAAe,GAAG,eAAe,GAAG,sBAAsB,CAAC;QACjE,IAAI,eAAe,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAE;YAC1D,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,kBAAkB,CAAC;YAC3C,0HAA0H;YAC1H,gGAAgG;YAChG,MAAM,eAAe,GAAG,eAAe,GAAG,CAAC,GAAG,sBAAsB,CAAC;YACrE,IAAI,eAAe,GAAG,MAAM,EAAE;gBAC7B,MAAM,MAAM,SACX,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,eAAe,CAAC,mCAAI,aAAI,CAAC,oCAAoC,CAAC,CAAC;gBAC/F,uCACI,MAAM,KACT,aAAa,EAAE,eAAe,IAC7B;aACF;iBAAM;gBACN,OAAO,SAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,mCAAI,aAAI,CAAC,oCAAoC,CAAC,CAAC;gBACnG,aAAa,GAAG,sBAAsB,GAAG,MAAM,CAAC;aAChD;SACD;aAAM;YACN,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,SACrC,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,eAAe,CAAC,mCAAI,aAAI,CAAC,+BAA+B,CAAC,CAAC;YACvG,aAAa,GAAG,cAAc,CAAC;YAC/B,OAAO,GAAG,cAAc,CAAC;SACzB;QACD,uBAAS,aAAa,IAAK,OAAO,EAAG;IACtC,CAAC;IAED;;;;;;OAMG;IACK,SAAS,CAChB,YAAsB,EACtB,IAAmB,EACnB,SAAiB;QAEjB,IAAI,aAAqC,CAAC;QAC1C,IAAI,MAAM,CAAC;QACX,IACC,IAAI,CAAC,gBAAgB,KAAK,SAAS;YACnC,IAAI,CAAC,gBAAgB,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE;YACxC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,KAAK,YAAY,EACnD;YACD,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;YAC7C,MAAM,GAAG,IAAI,CAAC;SACd;aAAM;YACN,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC;iBACnD,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;iBACpE,KAAK,EAAE,CAAC;YACV,MAAM,GAAG,KAAK,CAAC;SACf;QAED,MAAM,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC;QAC/B,IAAI,YAAsB,CAAC;QAC3B,IAAI,aAAa,CAAC,MAAM,KAAK,oBAAU,CAAC,OAAO,EAAE;YAChD,YAAY,GAAG,aAAa,CAAC,KAAK,CAAC;SACnC;aAAM;YACN,YAAY,GAAG,YAAY,CAAC;SAC5B;QAED,MAAM,kBAAkB,GACvB,aAAa,CAAC,MAAM,KAAK,oBAAU,CAAC,OAAO;YAC1C,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC,KAAK,EAAE;YACtF,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC;QAE7D,IAAI,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE;YAC3C,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;YACrE,IAAI,CAAC,yBAAyB,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;SACzD;aAAM;YACN,0HAA0H;YAC1H,uHAAuH;YACvH,2FAA2F;YAC3F,eAAM,CACL,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,sBAAsB,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,EACjF,qCAAqC,CACrC,CAAC;YACF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;SACjD;QAED,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;QACvF,OAAO,kBAAkB,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACK,yBAAyB,CAAC,IAAmB,EAAE,MAA8C;QACpG,yHAAyH;QACzH,iDAAiD;QACjD,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE;YACvC,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE;gBACpD,IAAI,MAAM,CAAC,MAAM,KAAK,oBAAU,CAAC,OAAO,EAAE;oBACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;wBAChB,QAAQ,EAAE,SAAS;wBACnB,SAAS,EACR,MAAM,CAAC,MAAM,KAAK,oBAAU,CAAC,SAAS;4BACrC,CAAC,CAAC,yBAAyB;4BAC3B,CAAC,CAAC,uBAAuB;qBAC3B,CAAC,CAAC;iBACH;gBACD,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;aAChC;iBAAM,IAAI,IAAI,CAAC,mBAAmB,EAAE;gBACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBACxD,eAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,EAAE,EAAE,qCAAqC,CAAC,CAAC;iBAC7F;aACD;SACD;IACF,CAAC;IAED;;;;;OAKG;IACI,0BAA0B,CAAC,MAAc;QAC/C,MAAM,kBAAkB,GAAkC,EAAE,CAAC;QAC7D,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,OAAO,IAAI,KAAK,CAAC,kBAAkB,EAAE;YACpC,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,EAAW,EAAE;gBAC9B,IAAI,CAAC,MAAM,EAAE;oBACZ,MAAM,GAAG,IAAI,CAAC;oBACd,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;oBACpD,IAAI,SAAS,CAAC,OAAO,KAAK,KAAK,IAAI,SAAS,CAAC,YAAY,KAAK,SAAS,EAAE;wBACxE,MAAM,iBAAiB,GAAG,IAAI,CAAC,8BAA8B,EAAE,CAAC;wBAChE,IAAI,iBAAiB,KAAK,SAAS,EAAE;4BACpC,MAAM,0BAA0B,GAAG,iBAAiB,CAAC,cAAc,CAAC;4BACpE,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,CACpC,0BAA0B,EAC1B,SAAS,CAAC,YAAY,CAAC,uBAAuB,CAC9C,CAAC;4BACF,IAAI,oBAAoB,GAAG,SAAS,CAAC,YAAY,CAAC,cAAc,EAAE;gCACjE,MAAM,SAAS,GAAG,IAAI,CAAC,+BAA+B,CAAC,oBAAoB,CAAC,CAAC;gCAC7E,IAAI,SAAS,KAAK,SAAS,EAAE;oCAC5B,IAAI,SAAS,CAAC,MAAM,KAAK,oBAAU,CAAC,OAAO,EAAE;wCAC5C,kBAAkB,CAAC,IAAI,iCACnB,SAAS,CAAC,KAAK,KAClB,MAAM,EAAE,SAAS,CAAC,MAAM,EACxB,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,IAC7B,CAAC;qCACH;oCACD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;oCAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oCACvD,KAAK,IAAI,KAAK,GAAG,WAAW,EAAE,KAAK,IAAI,YAAY,EAAE,EAAE,KAAK,EAAE;wCAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;wCAChD,IAAI,IAAI,CAAC,MAAM,KAAK,oBAAU,CAAC,OAAO,EAAE;4CACvC,kBAAkB,CAAC,IAAI,iCACnB,IAAI,CAAC,KAAK,KACb,MAAM,EAAE,IAAI,CAAC,MAAM,EACnB,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,IACxB,CAAC;yCACH;qCACD;iCACD;6BACD;yBACD;qBACD;iBACD;gBACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;SACD,CAAC,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,8BAA8B;QACpC,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,0BAA0B,CAAC;QAC9D,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAsB,GAAG,iBAAiB,GAAG,CAAC,CAAC;QAClF,KAAK,IAAI,KAAK,GAAG,iBAAiB,EAAE,KAAK,IAAI,iBAAiB,EAAE,EAAE,KAAK,EAAE;YACxE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC;YACrD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAA2B,CAAC;YACnF,IAAI,aAAa,CAAC,YAAY,KAAK,SAAS,EAAE;gBAC7C,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,aAAa,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;aAC3E;SACD;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,KAAa;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAChD,MAAM,WAAW,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC3D,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS,EAAE;YACrC,aAAI,CAAC,qDAAqD,CAAC,CAAC;SAC5D;QACD,OAAO,WAAW,CAAC,MAAM,KAAK,oBAAU,CAAC,OAAO;YAC/C,CAAC,CAAC;gBACA,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,MAAM,EAAE,oBAAU,CAAC,OAAO;gBAC1B,MAAM;gBACN,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,KAAK,EAAE,WAAW,CAAC,QAAQ;gBAC3B,KAAK,EAAE,WAAW,CAAC,KAAK;aACvB;YACH,CAAC,CAAC;gBACA,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,MAAM;gBACN,OAAO,EAAE,IAAI,CAAC,OAAO;aACpB,CAAC;IACN,CAAC;IAED;;;OAGG;IACI,+BAA+B,CAAC,cAAsB;QAC5D,MAAM,iBAAiB,GAAG,IAAI,CAAC,8BAA8B,EAAE,CAAC;QAChE,IAAI,iBAAiB,KAAK,SAAS,IAAI,cAAc,IAAI,iBAAiB,CAAC,cAAc,EAAE;YAC1F,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACrE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAsB,GAAG,CAAC,CAAC;YACzD,KAAK,IAAI,KAAK,GAAG,YAAY,EAAE,KAAK,IAAI,WAAW,EAAE,EAAE,KAAK,EAAE;gBAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC;gBACrD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAA2B,CAAC;gBAC/E,uHAAuH;gBACvH,yDAAyD;gBACzD,0HAA0H;gBAC1H,yHAAyH;gBACzH,uHAAuH;gBACvH,iGAAiG;gBACjG,IAAI,SAAS,CAAC,YAAY,IAAI,SAAS,CAAC,YAAY,CAAC,cAAc,IAAI,cAAc,EAAE;oBACtF,MAAM,MAAM,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;oBAChD,MAAM,WAAW,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;oBAC3D,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS,EAAE;wBACrC,aAAI,CAAC,qDAAqD,CAAC,CAAC;qBAC5D;oBACD,OAAO,WAAW,CAAC,MAAM,KAAK,oBAAU,CAAC,OAAO;wBAC/C,CAAC,CAAC;4BACA,EAAE,EAAE,IAAI,CAAC,EAAE;4BACX,MAAM,EAAE,oBAAU,CAAC,OAAO;4BAC1B,MAAM;4BACN,OAAO,EAAE,IAAI,CAAC,OAAO;4BACrB,KAAK,EAAE,WAAW,CAAC,QAAQ;4BAC3B,KAAK,EAAE,WAAW,CAAC,KAAK;yBACvB;wBACH,CAAC,CAAC;4BACA,EAAE,EAAE,IAAI,CAAC,EAAE;4BACX,MAAM,EAAE,WAAW,CAAC,MAAM;4BAC1B,MAAM;4BACN,OAAO,EAAE,IAAI,CAAC,OAAO;yBACpB,CAAC;iBACL;aACD;SACD;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;;AAhcF,4CAicC;AA9bA;;GAEG;AACoB,sCAAqB,GAAG,EAAE,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryBaseLogger } from '@fluidframework/common-definitions';\nimport Denque from 'denque';\nimport { assert, fail, noop } from './Common';\nimport { EditLog, SequencedOrderedEditId } from './EditLog';\nimport { Snapshot } from './Snapshot';\nimport { Edit, EditStatus, EditingResult, GenericTransaction } from './generic';\nimport { EditId } from './Identifiers';\nimport { RevisionValueCache } from './RevisionValueCache';\nimport { initialTree } from './InitialTree';\nimport { ReconciliationEdit, ReconciliationPath } from './ReconciliationPath';\n\n/**\n * Callback for when an edit is applied (meaning the result of applying it to a particular snapshot is computed).\n *\n * Edits may be applied any time a Snapshot is computed that includes them.\n * Depending on the caching policy of the LogViewer, a given edit may or may not be applied in order to compute a Snapshot containing it.\n *\n * If the same edit occurs in different contexts (ex: a local edit is adjusted for a new remote edit),\n * that it will be reapplied, and this may result in different results.\n *\n * Edits may additionally be reapplied at other times since their previous output might not be cached.\n *\n * If an application requests the current view, this will force all edits to be applied.\n * Such an application can use this callback can be log each edit as it comes it to see its status,\n * however this may include duplicates, as well as entries for reapplications in modified contexts.\n *\n * In the context of this callback,\n * skipping the first evaluation of an edit in a particular context due to setKnownEditingResult is still considered applying.\n * To use this call back to track when the actual computational work of applying edits is done, only count cases when `wasCached` is false.\n */\nexport type EditStatusCallback = (editResult: EditStatus, editId: EditId, wasCached: boolean) => void;\n\n/**\n * Result of applying an identified transaction.\n * @public\n */\nexport type EditingResultWithId<TChange> = EditingResult<TChange> & {\n\t/**\n\t * Unique identifier for this edit. Must never be reused.\n\t * Used for referencing and de-duplicating edits.\n\t */\n\treadonly id: EditId;\n};\n\n/**\n * The data cached by `CachingLogViewer` for an edit.\n */\nexport type EditCacheEntry<TChange> =\n\t| SuccessfulEditCacheEntry<TChange>\n\t| UnsuccessfulEditCacheEntry\n\t| SummarizedEditResultCacheEntry;\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has attempted to apply locally.\n */\nexport type AttemptedEditResultCacheEntry<TChange> = SuccessfulEditCacheEntry<TChange> | UnsuccessfulEditCacheEntry;\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has successfully applied locally.\n */\nexport interface SuccessfulEditCacheEntry<TChange> {\n\t/**\n\t * The snapshot resulting from the edit.\n\t */\n\tsnapshot: Snapshot;\n\t/**\n\t * The status code for the edit that produced the snapshot.\n\t */\n\tstatus: EditStatus.Applied;\n\t/**\n\t * The resolved changes that were applied during the edit and their associated outcome.\n\t */\n\tsteps: readonly { resolvedChange: TChange; after: Snapshot }[];\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has unsuccessfully attempted to apply locally.\n */\nexport interface UnsuccessfulEditCacheEntry {\n\t/**\n\t * The snapshot resulting from the edit.\n\t */\n\treadonly snapshot: Snapshot;\n\t/**\n\t * The status code for the edit that produced the snapshot.\n\t */\n\tstatus: EditStatus.Invalid | EditStatus.Malformed;\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has retrieved from a summary.\n * TODO:#57176: once summarized edits carry enough information remove this interface and use `AttemptedEditResultCacheEntry` instead.\n */\nexport interface SummarizedEditResultCacheEntry {\n\t/**\n\t * The snapshot resulting from the edit.\n\t */\n\tsnapshot: Snapshot;\n\tstatus?: undefined;\n}\n\n/**\n * A revision corresponds to an index in an `EditLog`.\n *\n * It is associated with the output `Snapshot` of applying the edit at the index to the previous revision.\n * For example:\n * - revision 0 corresponds to the initialSnapshot.\n * - revision 1 corresponds to the output of editLog[0] applied to the initialSnapshot.\n */\nexport type Revision = number;\n\n/**\n * Creates `Snapshot`s for the revisions in an `EditLog`\n */\nexport interface LogViewer {\n\t/**\n\t * Returns the `Snapshot` output associated with the largest revision in `editLog` less than (but not equal to) the supplied revision.\n\t *\n\t * For example:\n\t * - revision 0 returns the initialSnapshot.\n\t * - revision 1 returns the output of editLog[0] (or initialSnapshot if there is no edit 0).\n\t * - revision Number.POSITIVE_INFINITY returns the newest revision.\n\t */\n\tgetSnapshot(revision: Revision): Promise<Snapshot>;\n\n\t/**\n\t * Returns the `Snapshot` output associated with the largest revision in `editLog` less than (but not equal to) the supplied revision.\n\t * Can only be used to retrieve revisions added during the current sessions.\n\t *\n\t * For example:\n\t * - revision 0 returns the initialSnapshot.\n\t * - revision 1 returns the output of editLog[0] (or initialSnapshot if there is no edit 0).\n\t * - revision Number.POSITIVE_INFINITY returns the newest revision.\n\t */\n\tgetSnapshotInSession(revision: Revision): Snapshot;\n}\n\n/**\n * Creates Snapshots for revisions associated with an EditLog and caches the results.\n * @internal\n */\nexport class CachingLogViewer<TChange> implements LogViewer {\n\tpublic readonly log: EditLog<TChange>;\n\n\t/**\n\t * Maximum size of the sequenced snapshot cache.\n\t */\n\tpublic static readonly sequencedCacheSizeMax = 50;\n\n\t/**\n\t * A cache for local snapshots.\n\t * It is invalidated whenever a new sequenced edit (that was not already a local edit) is added to the log.\n\t * When a previously local edit is sequenced, this cache is adjusted to account for it, not invalidated.\n\t */\n\tprivate readonly localSnapshotCache = new Denque<AttemptedEditResultCacheEntry<TChange>>();\n\n\t/**\n\t * Cache of sequenced snapshots.\n\t */\n\tprivate readonly sequencedSnapshotCache: RevisionValueCache<EditCacheEntry<TChange>>;\n\n\t/**\n\t * Called whenever an edit is processed.\n\t * This will have been called at least once for any edit if a revision after than edit has been requested.\n\t * It may be called multiple times: the number of calls and when they occur depends on caching and is an implementation detail.\n\t */\n\tprivate readonly processEditStatus: EditStatusCallback;\n\n\t/**\n\t * Iff true, additional correctness assertions will be run during LogViewer operations.\n\t */\n\tprivate readonly expensiveValidation: boolean;\n\n\t/**\n\t * Telemetry logger, used to log events such as edit application rejection.\n\t */\n\tprivate readonly logger: ITelemetryBaseLogger;\n\n\t/**\n\t * The ordered queue of edits that originated from this client that have never been applied (by this log viewer) in a sequenced state.\n\t * This means these edits may be local or sequenced, and may have been applied (possibly multiple times) while still local.\n\t * Used to log telemetry about the result of edit application. Edits are removed when first applied after being sequenced.\n\t */\n\tprivate readonly unappliedSelfEdits = new Denque<EditId>();\n\n\t/**\n\t * Cache of applying a edit.\n\t * Due to use of Transactions in checkouts, a common pattern involves applying an edit\n\t * as part of the transaction, then submitting it.\n\t * This cache helps optimize that case by avoiding recomputing the edit if no other edits were added during the transaction.\n\t */\n\tprivate cachedEditResult?: { editId: EditId; result: EditingResult<TChange> };\n\n\tprivate readonly transactionFactory: (snapshot: Snapshot) => GenericTransaction<TChange>;\n\n\t/**\n\t * Create a new LogViewer\n\t * @param log - the edit log which snapshots will be based on.\n\t * @param baseTree - the tree used in the snapshot corresponding to the 0th revision. Defaults to `initialTree`.\n\t * @param knownRevisions - a set of [sequencedRevision, snapshot] pairs that are known (have been precomputed) at construction time.\n\t * These revisions are guaranteed to never be evicted from the cache.\n\t * @param expensiveValidation - Iff true, additional correctness assertions will be run during LogViewer operations.\n\t * @param processEditStatus - called after applying an edit.\n\t * @param logger - used to log telemetry\n\t */\n\tpublic constructor(\n\t\tlog: EditLog<TChange>,\n\t\tbaseSnapshot: Snapshot = Snapshot.fromTree(initialTree),\n\t\tknownRevisions: [Revision, EditCacheEntry<TChange>][] = [],\n\t\texpensiveValidation = false,\n\t\tprocessEditStatus: EditStatusCallback = noop,\n\t\tlogger: ITelemetryBaseLogger,\n\t\ttransactionFactory: (snapshot: Snapshot) => GenericTransaction<TChange>,\n\t\tminimumSequenceNumber = 0\n\t) {\n\t\tthis.log = log;\n\t\tif (expensiveValidation) {\n\t\t\tknownRevisions.forEach(([revision]) => {\n\t\t\t\tassert(Number.isInteger(revision), 'revision must be an integer');\n\t\t\t\tassert(\n\t\t\t\t\tthis.log.isSequencedRevision(revision),\n\t\t\t\t\t'revision must correspond to the result of a SequencedEdit'\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\tthis.sequencedSnapshotCache = new RevisionValueCache(\n\t\t\tCachingLogViewer.sequencedCacheSizeMax,\n\t\t\tminimumSequenceNumber,\n\t\t\t[...knownRevisions, [0, { snapshot: baseSnapshot }]]\n\t\t);\n\t\tthis.processEditStatus = processEditStatus ?? noop;\n\t\tthis.expensiveValidation = expensiveValidation;\n\t\tthis.logger = logger;\n\t\tthis.transactionFactory = transactionFactory;\n\t\tthis.log.registerEditAddedHandler(this.handleEditAdded.bind(this));\n\t}\n\n\t/**\n\t * Performs the tracking needed to log telemetry about failed (invalid/malformed) local edits when they are sequenced.\n\t * As a performance optimization, this method also caches snapshots generated by local edits if they are sequenced without\n\t * being interleaved with remote edits.\n\t */\n\tprivate handleEditAdded(edit: Edit<TChange>, isLocal: boolean, wasLocal: boolean): void {\n\t\tif (isLocal) {\n\t\t\tthis.unappliedSelfEdits.push(edit.id);\n\t\t} else if (wasLocal) {\n\t\t\t// If the new sequenced edit was generated by this client, the corresponding cache entry (if there is one)\n\t\t\t// will be at the front of the queue. If the queue is empty, then a concurrent sequenced edit from remote client\n\t\t\t// must have invalidated the queue cache.\n\t\t\tconst entry = this.localSnapshotCache.shift();\n\t\t\tif (entry !== undefined) {\n\t\t\t\tconst revision = this.log.numberOfSequencedEdits;\n\t\t\t\tconst snapshot = entry.snapshot;\n\t\t\t\tthis.sequencedSnapshotCache.cacheValue(\n\t\t\t\t\trevision,\n\t\t\t\t\tentry.status === EditStatus.Applied\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tsnapshot,\n\t\t\t\t\t\t\t\tstatus: entry.status,\n\t\t\t\t\t\t\t\tsteps: entry.steps,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tsnapshot,\n\t\t\t\t\t\t\t\tstatus: entry.status,\n\t\t\t\t\t\t }\n\t\t\t\t);\n\t\t\t\tthis.handleSequencedEditResult(edit, entry);\n\t\t\t}\n\t\t} else {\n\t\t\t// Invalidate any cached results of applying edits which are ordered after `edit` (which are all remaining local edits)\n\t\t\tthis.localSnapshotCache.clear();\n\t\t}\n\t}\n\n\tpublic async getEditResult(revision: Revision): Promise<EditCacheEntry<TChange>> {\n\t\tconst startingPoint = this.getStartingPoint(revision);\n\t\tconst { startRevision } = startingPoint;\n\t\tlet current: EditCacheEntry<TChange> = startingPoint;\n\t\tfor (let i = startRevision; i < revision && i < this.log.length; i++) {\n\t\t\tconst edit = await this.log.getEditAtIndex(i);\n\t\t\tcurrent = this.applyEdit(current.snapshot, edit, i);\n\t\t}\n\t\treturn current;\n\t}\n\n\tpublic async getSnapshot(revision: Revision): Promise<Snapshot> {\n\t\treturn (await this.getEditResult(revision)).snapshot;\n\t}\n\n\tpublic getEditResultInSession(revision: Revision): EditCacheEntry<TChange> {\n\t\tconst startingPoint = this.getStartingPoint(revision);\n\t\tconst { startRevision } = startingPoint;\n\t\tlet current: EditCacheEntry<TChange> = startingPoint;\n\t\tfor (let i = startRevision; i < revision && i < this.log.length; i++) {\n\t\t\tconst edit = this.log.getEditInSessionAtIndex(i);\n\t\t\tcurrent = this.applyEdit(current.snapshot, edit, i);\n\t\t}\n\t\treturn current;\n\t}\n\n\tpublic getSnapshotInSession(revision: Revision): Snapshot {\n\t\treturn this.getEditResultInSession(revision).snapshot;\n\t}\n\n\t/**\n\t * Informs the CachingLogViewer of the latest known minimumSequenceNumber for all connected clients.\n\t * This can be used to provide more aggressive caching of revisions within the collaboration window, as those revisions\n\t * are more likely to be demanded to resolve conflicts.\n\t * @param minSequenceNumber - the minimum known sequence number of all connected clients.\n\t */\n\tpublic setMinimumSequenceNumber(minimumSequenceNumber: number): void {\n\t\t// Sequence numbers in Fluid are 1-indexed, meaning they correspond to revisions, and can be used as revisions.\n\t\t// This ensures that all revisions >= minimumSequenceNumber are kept in the cache, meaning that even if all clients are caught up\n\t\t// the most recent sequenced revision will be cached.\n\t\tthis.sequencedSnapshotCache.updateRetentionWindow(minimumSequenceNumber);\n\t}\n\n\t/**\n\t * Inform the CachingLogViewer that a particular edit is know to have a specific result when applied to a particular Snapshot.\n\t * LogViewer may use this information to as a optimization to avoid re-running the edit if re-applied to the same Snapshot.\n\t */\n\tpublic setKnownEditingResult(edit: Edit<TChange>, result: EditingResult<TChange>): void {\n\t\tthis.cachedEditResult = { editId: edit.id, result };\n\t}\n\n\t/**\n\t * @returns the cached snapshot closest to the requested `revision`.\n\t */\n\tprivate getStartingPoint(revision: Revision): { startRevision: Revision } & EditCacheEntry<TChange> {\n\t\t// Per the documentation for revision, the returned snapshot should be the output of the edit at the largest index <= `revision`.\n\t\tconst revisionClamped = Math.min(revision, this.log.length);\n\t\tlet current: EditCacheEntry<TChange>;\n\t\tlet startRevision: Revision;\n\t\tconst { numberOfSequencedEdits } = this.log;\n\t\tconst isLocalRevision = revisionClamped > numberOfSequencedEdits;\n\t\tif (isLocalRevision && !this.localSnapshotCache.isEmpty()) {\n\t\t\tconst { length } = this.localSnapshotCache;\n\t\t\t// Local snapshot cache is indexed such that the snapshot for revision 0 (a local edit) is stored at index 0 in the cache.\n\t\t\t// This is because the local cache does not contain an entry for the implicit initial tree edit.\n\t\t\tconst localCacheIndex = revisionClamped - 1 - numberOfSequencedEdits;\n\t\t\tif (localCacheIndex < length) {\n\t\t\t\tconst cached =\n\t\t\t\t\tthis.localSnapshotCache.peekAt(localCacheIndex) ?? fail('missing tail of localSnapshotCache');\n\t\t\t\treturn {\n\t\t\t\t\t...cached,\n\t\t\t\t\tstartRevision: revisionClamped,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tcurrent = this.localSnapshotCache.peekAt(length - 1) ?? fail('missing tail of localSnapshotCache');\n\t\t\t\tstartRevision = numberOfSequencedEdits + length;\n\t\t\t}\n\t\t} else {\n\t\t\tconst [cachedRevision, cachedSnapshot] =\n\t\t\t\tthis.sequencedSnapshotCache.getClosestEntry(revisionClamped) ?? fail('No preceding snapshot cached.');\n\t\t\tstartRevision = cachedRevision;\n\t\t\tcurrent = cachedSnapshot;\n\t\t}\n\t\treturn { startRevision, ...current };\n\t}\n\n\t/**\n\t * Helper for applying an edit at the supplied snapshot.\n\t * Must only be called in the order that edits appear in the log.\n\t * Must only be called once for a given local edit as long as the local cache has not been invalidated.\n\t * Must only be called once for a given sequenced edit.\n\t * @returns the resulting snapshot and the outcome of edit that produced it.\n\t */\n\tprivate applyEdit(\n\t\tprevSnapshot: Snapshot,\n\t\tedit: Edit<TChange>,\n\t\teditIndex: number\n\t): AttemptedEditResultCacheEntry<TChange> {\n\t\tlet editingResult: EditingResult<TChange>;\n\t\tlet cached;\n\t\tif (\n\t\t\tthis.cachedEditResult !== undefined &&\n\t\t\tthis.cachedEditResult.editId === edit.id &&\n\t\t\tthis.cachedEditResult.result.before === prevSnapshot\n\t\t) {\n\t\t\teditingResult = this.cachedEditResult.result;\n\t\t\tcached = true;\n\t\t} else {\n\t\t\teditingResult = this.transactionFactory(prevSnapshot)\n\t\t\t\t.applyChanges(edit.changes, this.reconciliationPathFromEdit(edit.id))\n\t\t\t\t.close();\n\t\t\tcached = false;\n\t\t}\n\n\t\tconst revision = editIndex + 1;\n\t\tlet nextSnapshot: Snapshot;\n\t\tif (editingResult.status === EditStatus.Applied) {\n\t\t\tnextSnapshot = editingResult.after;\n\t\t} else {\n\t\t\tnextSnapshot = prevSnapshot;\n\t\t}\n\n\t\tconst computedCacheEntry =\n\t\t\teditingResult.status === EditStatus.Applied\n\t\t\t\t? { snapshot: nextSnapshot, status: editingResult.status, steps: editingResult.steps }\n\t\t\t\t: { snapshot: nextSnapshot, status: editingResult.status };\n\n\t\tif (this.log.isSequencedRevision(revision)) {\n\t\t\tthis.sequencedSnapshotCache.cacheValue(revision, computedCacheEntry);\n\t\t\tthis.handleSequencedEditResult(edit, computedCacheEntry);\n\t\t} else {\n\t\t\t// This relies on local edits being append only, and that generating the snapshot for a local revision requires generating\n\t\t\t// the snapshot for all local revisions before it in the log. Thus, generating such a snapshot will necessarily require\n\t\t\t// calls to this method for all local revisions prior, guaranteeing the correct push order.\n\t\t\tassert(\n\t\t\t\trevision === this.log.numberOfSequencedEdits + this.localSnapshotCache.length + 1,\n\t\t\t\t'Local snapshot cached out of order.'\n\t\t\t);\n\t\t\tthis.localSnapshotCache.push(computedCacheEntry);\n\t\t}\n\n\t\tthis.processEditStatus(editingResult.status, this.log.getIdAtIndex(editIndex), cached);\n\t\treturn computedCacheEntry;\n\t}\n\n\t/**\n\t * Helper for performing caching and telemetry logging when a sequenced local edit is first applied.\n\t * Must only be called for non-cached sequenced edits.\n\t */\n\tprivate handleSequencedEditResult(edit: Edit<TChange>, result: AttemptedEditResultCacheEntry<TChange>): void {\n\t\t// This is the first time this sequenced edit has been processed by this LogViewer. If it was a local edit, log telemetry\n\t\t// in the event that it was invalid or malformed.\n\t\tif (this.unappliedSelfEdits.length > 0) {\n\t\t\tif (edit.id === this.unappliedSelfEdits.peekFront()) {\n\t\t\t\tif (result.status !== EditStatus.Applied) {\n\t\t\t\t\tthis.logger.send({\n\t\t\t\t\t\tcategory: 'generic',\n\t\t\t\t\t\teventName:\n\t\t\t\t\t\t\tresult.status === EditStatus.Malformed\n\t\t\t\t\t\t\t\t? 'MalformedSharedTreeEdit'\n\t\t\t\t\t\t\t\t: 'InvalidSharedTreeEdit',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis.unappliedSelfEdits.shift();\n\t\t\t} else if (this.expensiveValidation) {\n\t\t\t\tfor (let i = 0; i < this.unappliedSelfEdits.length; i++) {\n\t\t\t\t\tassert(this.unappliedSelfEdits.peekAt(i) !== edit.id, 'Local edits processed out of order.');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * We currently compute only the \"main branch\" part of the reconciliation path (meaning we don't include inverts of the edits\n\t * that occurred on the rebased branch). Doing so is only needed for the sequential anchor resolution approach which is not\n\t * yet supported.\n\t * @param editId - The ID for the edit to get the reconciliation path for.\n\t */\n\tpublic reconciliationPathFromEdit(editId: EditId): ReconciliationPath<TChange> {\n\t\tconst reconciliationPath: ReconciliationEdit<TChange>[] = [];\n\t\tlet cached = false;\n\t\treturn new Proxy(reconciliationPath, {\n\t\t\tget: (target, prop): unknown => {\n\t\t\t\tif (!cached) {\n\t\t\t\t\tcached = true;\n\t\t\t\t\tconst orderedId = this.log.getOrderedEditId(editId);\n\t\t\t\t\tif (orderedId.isLocal === false && orderedId.sequenceInfo !== undefined) {\n\t\t\t\t\t\tconst earliestSequenced = this.earliestSequencedEditInSession();\n\t\t\t\t\t\tif (earliestSequenced !== undefined) {\n\t\t\t\t\t\t\tconst earliestEditSequenceNumber = earliestSequenced.sequenceNumber;\n\t\t\t\t\t\t\tconst targetSequenceNumber = Math.max(\n\t\t\t\t\t\t\t\tearliestEditSequenceNumber,\n\t\t\t\t\t\t\t\torderedId.sequenceInfo.referenceSequenceNumber\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (targetSequenceNumber < orderedId.sequenceInfo.sequenceNumber) {\n\t\t\t\t\t\t\t\tconst firstEdit = this.getEditResultFromSequenceNumber(targetSequenceNumber);\n\t\t\t\t\t\t\t\tif (firstEdit !== undefined) {\n\t\t\t\t\t\t\t\t\tif (firstEdit.status === EditStatus.Applied) {\n\t\t\t\t\t\t\t\t\t\treconciliationPath.push({\n\t\t\t\t\t\t\t\t\t\t\t...firstEdit.steps,\n\t\t\t\t\t\t\t\t\t\t\tbefore: firstEdit.before,\n\t\t\t\t\t\t\t\t\t\t\tafter: firstEdit.after,\n\t\t\t\t\t\t\t\t\t\t\tlength: firstEdit.steps.length,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst lowestIndex = this.log.getIndexOfId(firstEdit.id) + 1;\n\t\t\t\t\t\t\t\t\tconst highestIndex = this.log.getIndexOfId(editId) - 1;\n\t\t\t\t\t\t\t\t\tfor (let index = lowestIndex; index <= highestIndex; ++index) {\n\t\t\t\t\t\t\t\t\t\tconst edit = this.getEditResultFromIndex(index);\n\t\t\t\t\t\t\t\t\t\tif (edit.status === EditStatus.Applied) {\n\t\t\t\t\t\t\t\t\t\t\treconciliationPath.push({\n\t\t\t\t\t\t\t\t\t\t\t\t...edit.steps,\n\t\t\t\t\t\t\t\t\t\t\t\tbefore: edit.before,\n\t\t\t\t\t\t\t\t\t\t\t\tafter: edit.after,\n\t\t\t\t\t\t\t\t\t\t\t\tlength: edit.steps.length,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn target[prop];\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * @returns Edit information for the earliest known sequenced edit.\n\t */\n\tpublic earliestSequencedEditInSession(): { edit: Edit<TChange>; sequenceNumber: number } | undefined {\n\t\tconst earliestEditIndex = this.log.earliestAvailableEditIndex;\n\t\tconst lastSequencedEdit = this.log.numberOfSequencedEdits + earliestEditIndex - 1;\n\t\tfor (let index = earliestEditIndex; index <= lastSequencedEdit; ++index) {\n\t\t\tconst edit = this.log.getEditInSessionAtIndex(index);\n\t\t\tconst editOrderedId = this.log.getOrderedEditId(edit.id) as SequencedOrderedEditId;\n\t\t\tif (editOrderedId.sequenceInfo !== undefined) {\n\t\t\t\treturn { edit, sequenceNumber: editOrderedId.sequenceInfo.sequenceNumber };\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * @returns Edit result information for the edit at the given `index`.\n\t */\n\tprivate getEditResultFromIndex(index: number): EditingResultWithId<TChange> {\n\t\tconst edit = this.log.getEditInSessionAtIndex(index);\n\t\tconst before = this.getSnapshotInSession(index);\n\t\tconst resultAfter = this.getEditResultInSession(index + 1);\n\t\tif (resultAfter.status === undefined) {\n\t\t\tfail('The status of every edit in session should be known');\n\t\t}\n\t\treturn resultAfter.status === EditStatus.Applied\n\t\t\t? {\n\t\t\t\t\tid: edit.id,\n\t\t\t\t\tstatus: EditStatus.Applied,\n\t\t\t\t\tbefore,\n\t\t\t\t\tchanges: edit.changes,\n\t\t\t\t\tafter: resultAfter.snapshot,\n\t\t\t\t\tsteps: resultAfter.steps,\n\t\t\t }\n\t\t\t: {\n\t\t\t\t\tid: edit.id,\n\t\t\t\t\tstatus: resultAfter.status,\n\t\t\t\t\tbefore,\n\t\t\t\t\tchanges: edit.changes,\n\t\t\t };\n\t}\n\n\t/**\n\t * @param sequenceNumber - The server-assigned sequenced number assigned to the edit of interest.\n\t * @returns Edit result information for the edit with the given sequence number. Undefined if no such edit is known.\n\t */\n\tpublic getEditResultFromSequenceNumber(sequenceNumber: number): EditingResultWithId<TChange> | undefined {\n\t\tconst earliestSequenced = this.earliestSequencedEditInSession();\n\t\tif (earliestSequenced !== undefined && sequenceNumber >= earliestSequenced.sequenceNumber) {\n\t\t\tconst lowestIndex = this.log.getIndexOfId(earliestSequenced.edit.id);\n\t\t\tconst highestIndex = this.log.numberOfSequencedEdits - 1;\n\t\t\tfor (let index = highestIndex; index >= lowestIndex; --index) {\n\t\t\t\tconst edit = this.log.getEditInSessionAtIndex(index);\n\t\t\t\tconst orderedId = this.log.getOrderedEditId(edit.id) as SequencedOrderedEditId;\n\t\t\t\t// If `orderedId.sequenceInfo.sequenceNumber` is equal to the requested `sequenceNumber` then we have found the edit of\n\t\t\t\t// interest and simply return its associated information.\n\t\t\t\t// Note that the check bellow also is also satisfied if `orderedId.sequenceInfo.sequenceNumber`is lower than the requested\n\t\t\t\t// `sequenceNumber`. This can happen when the edit for the requested `sequenceNumber` has either not yet been received or\n\t\t\t\t// has been processed by a different DDS (several DDSes can share the same stream of operations and will only see those\n\t\t\t\t// relevant to them). In such cases, we return the edit info for the last known edit before that.\n\t\t\t\tif (orderedId.sequenceInfo && orderedId.sequenceInfo.sequenceNumber <= sequenceNumber) {\n\t\t\t\t\tconst before = this.getSnapshotInSession(index);\n\t\t\t\t\tconst resultAfter = this.getEditResultInSession(index + 1);\n\t\t\t\t\tif (resultAfter.status === undefined) {\n\t\t\t\t\t\tfail('The status of every edit in session should be known');\n\t\t\t\t\t}\n\t\t\t\t\treturn resultAfter.status === EditStatus.Applied\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tid: edit.id,\n\t\t\t\t\t\t\t\tstatus: EditStatus.Applied,\n\t\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\t\tchanges: edit.changes,\n\t\t\t\t\t\t\t\tafter: resultAfter.snapshot,\n\t\t\t\t\t\t\t\tsteps: resultAfter.steps,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tid: edit.id,\n\t\t\t\t\t\t\t\tstatus: resultAfter.status,\n\t\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\t\tchanges: edit.changes,\n\t\t\t\t\t\t };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"LogViewer.js","sourceRoot":"","sources":["../src/LogViewer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport Denque from 'denque';\nimport { assert, fail, noop } from './Common';\nimport { EditLog, SequencedOrderedEditId } from './EditLog';\nimport { EditId } from './Identifiers';\nimport { Revision, RevisionValueCache } from './RevisionValueCache';\nimport { ReconciliationChange, ReconciliationEdit, ReconciliationPath } from './ReconciliationPath';\nimport { ChangeInternal, Edit, EditStatus } from './persisted-types';\nimport { RevisionView } from './RevisionView';\nimport { EditingResult, TransactionInternal, TransactionFactory } from './TransactionInternal';\n\n/**\n * Callback for when an edit is applied (meaning the result of applying it to a particular revision is computed).\n *\n * Edits may be applied any time a TreeView is computed that includes them.\n * Depending on the caching policy of the LogViewer, a given edit may or may not be applied in order to compute a TreeView containing it.\n *\n * If the same edit occurs in different contexts (ex: a local edit is adjusted for a new remote edit),\n * that it will be reapplied, and this may result in different results.\n *\n * Edits may additionally be reapplied at other times since their previous output might not be cached.\n *\n * If an application requests the current view, this will force all edits to be applied.\n * Such an application can use this callback can be log each edit as it comes it to see its status,\n * however this may include duplicates, as well as entries for reapplications in modified contexts.\n *\n * In the context of this callback,\n * skipping the first evaluation of an edit in a particular context due to setKnownEditingResult is still considered applying.\n * To use this call back to track when the actual computational work of applying edits is done, only count cases when `wasCached` is false.\n */\nexport type EditStatusCallback = (editResult: EditStatus, editId: EditId, wasCached: boolean) => void;\n\n/**\n * Callback for when a sequenced edit is applied.\n * This includes local edits though the callback is only invoked once the sequenced version is received.\n *\n * For edits that were local (see {@link SequencedEditResult.wasLocal}, this callback will only be called once.\n * For non-local edits, it may be called multiple times: the number of calls and when they occur depends on caching and is an implementation\n * detail.\n */\nexport type SequencedEditResultCallback = (args: SequencedEditResult) => void;\n\n/**\n * The relevant information pertaining to the application of a sequenced edit.\n */\nexport interface SequencedEditResult {\n\t/**\n\t * The edit that was applied.\n\t */\n\tedit: Edit<ChangeInternal>;\n\t/**\n\t * true iff the edit was local.\n\t */\n\twasLocal: boolean;\n\t/**\n\t * The result of applying the edit.\n\t */\n\tresult: AttemptedEditResultCacheEntry;\n\t/**\n\t * The reconciliation path for the edit.\n\t */\n\treconciliationPath: ReconciliationPath;\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit.\n */\nexport type EditCacheEntry = SuccessfulEditCacheEntry | UnsuccessfulEditCacheEntry | SummarizedEditResultCacheEntry;\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has attempted to apply locally.\n */\nexport type AttemptedEditResultCacheEntry = SuccessfulEditCacheEntry | UnsuccessfulEditCacheEntry;\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has successfully applied locally.\n */\nexport interface SuccessfulEditCacheEntry {\n\t/**\n\t * The revision view resulting from the edit.\n\t */\n\treadonly view: RevisionView;\n\t/**\n\t * The status code for the edit that produced the revision.\n\t */\n\treadonly status: EditStatus.Applied;\n\t/**\n\t * The resolved changes that were applied during the edit and their associated outcome.\n\t */\n\treadonly steps: readonly ReconciliationChange[];\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has unsuccessfully attempted to apply locally.\n */\nexport interface UnsuccessfulEditCacheEntry {\n\t/**\n\t * The revision view resulting from the edit.\n\t */\n\treadonly view: RevisionView;\n\t/**\n\t * The status code for the edit that produced the revision.\n\t */\n\treadonly status: EditStatus.Invalid | EditStatus.Malformed;\n\t/**\n\t * Information about the failure encountered by the edit\n\t */\n\treadonly failure: TransactionInternal.Failure;\n}\n\n/**\n * The data cached by `CachingLogViewer` for an edit that it has retrieved from a summary.\n * TODO:#57176: once summarized edits carry enough information remove this interface and use `AttemptedEditResultCacheEntry` instead.\n */\nexport interface SummarizedEditResultCacheEntry {\n\t/**\n\t * The revision view resulting from the edit.\n\t */\n\treadonly view: RevisionView;\n\t/**\n\t * Not specified on `SummarizedEditResultCacheEntry`.\n\t * Declared to allow checking `entry.status` against undefined.\n\t */\n\treadonly status?: never;\n}\n\nexport type CachedEditingResult = AttemptedEditResultCacheEntry & {\n\t/**\n\t * Unique identifier for this edit. Must never be reused.\n\t * Used for referencing and de-duplicating edits.\n\t */\n\treadonly id: EditId;\n\treadonly before: RevisionView;\n\treadonly changes: readonly ChangeInternal[];\n};\n\n/**\n * Creates `RevisionView`s for the revisions in an `EditLog`\n */\nexport interface LogViewer {\n\t/**\n\t * Returns the `TreeView` output associated with the largest revision in `editLog` less than (but not equal to) the supplied revision.\n\t *\n\t * For example:\n\t * - revision 0 returns the initialRevision.\n\t * - revision 1 returns the output of editLog[0] (or initialRevision if there is no edit 0).\n\t * - revision Number.POSITIVE_INFINITY returns the newest revision.\n\t */\n\tgetRevisionView(revision: Revision): Promise<RevisionView>;\n\n\t/**\n\t * Returns the `TreeView` output associated with the largest revision in `editLog` less than (but not equal to) the supplied revision.\n\t * Can only be used to retrieve revisions added during the current sessions.\n\t *\n\t * For example:\n\t * - revision 0 returns the initialRevision.\n\t * - revision 1 returns the output of editLog[0] (or initialRevision if there is no edit 0).\n\t * - revision Number.POSITIVE_INFINITY returns the newest revision.\n\t */\n\tgetRevisionViewInSession(revision: Revision): RevisionView;\n}\n\n/**\n * Creates views for revisions associated with an EditLog and caches the results.\n *\n * Does so by listening for edits added to the log. If the underlying EditLog or its listeners need to be reused beyond the lifetime of\n * a CachingLogViewer instance, that instance should be disposed with `detachFromEditLog` to ensure it is garbage-collectable.\n * @internal\n */\nexport class CachingLogViewer implements LogViewer {\n\tpublic readonly log: EditLog<ChangeInternal>;\n\n\t/**\n\t * Maximum size of the sequenced revision cache.\n\t */\n\tpublic static readonly sequencedCacheSizeMax = 50;\n\n\t/**\n\t * A cache for local revisions.\n\t * It is invalidated whenever a new sequenced edit (that was not already a local edit) is added to the log.\n\t * When a previously local edit is sequenced, this cache is adjusted to account for it, not invalidated.\n\t */\n\tprivate readonly localRevisionCache = new Denque<AttemptedEditResultCacheEntry>();\n\n\t/**\n\t * Cache of sequenced revisions.\n\t */\n\tprivate readonly sequencedRevisionCache: RevisionValueCache<EditCacheEntry>;\n\n\t/**\n\t * Called whenever a sequenced edit is applied.\n\t * This will have been called at least once for any edit if a revision after than edit has been requested.\n\t * It may be called multiple times: the number of calls and when they occur depends on caching and is an implementation detail.\n\t */\n\tprivate readonly processSequencedEditResult: SequencedEditResultCallback;\n\n\t/**\n\t * Called whenever an edit is processed.\n\t * This will have been called at least once for any edit if a revision after than edit has been requested.\n\t * It may be called multiple times: the number of calls and when they occur depends on caching and is an implementation detail.\n\t */\n\tprivate readonly processEditStatus: EditStatusCallback;\n\n\t/**\n\t * Iff true, additional correctness assertions will be run during LogViewer operations.\n\t */\n\tprivate readonly expensiveValidation: boolean;\n\n\t/**\n\t * The ordered queue of edits that originated from this client that have never been applied (by this log viewer) in a sequenced state.\n\t * This means these edits may be local or sequenced, and may have been applied (possibly multiple times) while still local.\n\t * Used to log telemetry about the result of edit application. Edits are removed when first applied after being sequenced.\n\t */\n\tprivate readonly unappliedSelfEdits = new Denque<EditId>();\n\n\t/**\n\t * Cache of applying a edit.\n\t * Due to use of Transactions in checkouts, a common pattern involves applying an edit\n\t * as part of the transaction, then submitting it.\n\t * This cache helps optimize that case by avoiding recomputing the edit if no other edits were added during the transaction.\n\t */\n\tprivate cachedEditResult?: { editId: EditId; result: EditingResult };\n\n\t/**\n\t * Cache entry for the highest revision.\n\t * `undefined` when not cached.\n\t */\n\tprivate highestRevisionCacheEntry?: EditCacheEntry;\n\n\t/**\n\t * Removes this log viewer from the set of handleEditAdded listeners on its underlying log.\n\t * This should be called if the underlying log or its listeners are re-used past the lifetime of this log viewer.\n\t */\n\tpublic readonly detachFromEditLog: () => void;\n\n\t/**\n\t * @returns true if the highest revision is cached.\n\t */\n\tpublic highestRevisionCached(): boolean {\n\t\treturn this.highestRevisionCacheEntry !== undefined;\n\t}\n\n\t/**\n\t * Create a new LogViewer\n\t * @param log - the edit log which revisions will be based on.\n\t * @param baseTree - the tree used in the view corresponding to the 0th revision.\n\t * @param knownRevisions - a set of [sequencedRevision, view] pairs that are known (have been precomputed) at construction time.\n\t * These revisions are guaranteed to never be evicted from the cache.\n\t * @param expensiveValidation - Iff true, additional correctness assertions will be run during LogViewer operations.\n\t * @param processEditStatus - called after applying an edit.\n\t * @param processSequencedEditResult - called after applying a sequenced edit.\n\t */\n\tpublic constructor(\n\t\tlog: EditLog<ChangeInternal>,\n\t\tbaseView: RevisionView,\n\t\tknownRevisions: [Revision, EditCacheEntry][] = [],\n\t\texpensiveValidation = false,\n\t\tprocessEditStatus: EditStatusCallback = noop,\n\t\tprocessSequencedEditResult: SequencedEditResultCallback = noop,\n\t\tprivate readonly transactionFactory: TransactionFactory,\n\t\tminimumSequenceNumber = 0\n\t) {\n\t\tthis.log = log;\n\t\tif (expensiveValidation) {\n\t\t\tknownRevisions.forEach(([revision]) => {\n\t\t\t\tassert(Number.isInteger(revision), 'revision must be an integer');\n\t\t\t\tassert(\n\t\t\t\t\tthis.log.isSequencedRevision(revision),\n\t\t\t\t\t'revision must correspond to the result of a SequencedEdit'\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\tthis.sequencedRevisionCache = new RevisionValueCache(\n\t\t\tCachingLogViewer.sequencedCacheSizeMax,\n\t\t\tminimumSequenceNumber,\n\t\t\t[...knownRevisions, [0, { view: baseView }]]\n\t\t);\n\t\tthis.processEditStatus = processEditStatus ?? noop;\n\t\tthis.processSequencedEditResult = processSequencedEditResult ?? noop;\n\t\tthis.expensiveValidation = expensiveValidation;\n\t\tthis.transactionFactory = transactionFactory;\n\t\tthis.detachFromEditLog = this.log.registerEditAddedHandler(this.handleEditAdded.bind(this));\n\t}\n\n\t/**\n\t * As a performance optimization, this method caches views generated by local edits if they are sequenced without\n\t * being interleaved with remote edits.\n\t */\n\tprivate handleEditAdded(edit: Edit<ChangeInternal>, isLocal: boolean, wasLocal: boolean): void {\n\t\t// Clear highestRevisionCacheEntry, since what revision is highest might change.\n\t\t// Note that as an optimization we could skip clearing this when a local edit is sequenced.\n\t\tthis.highestRevisionCacheEntry = undefined;\n\n\t\tif (isLocal) {\n\t\t\tthis.unappliedSelfEdits.push(edit.id);\n\t\t} else if (wasLocal) {\n\t\t\t// If the new sequenced edit was generated by this client, the corresponding cache entry (if there is one)\n\t\t\t// will be at the front of the queue. If the queue is empty, then a concurrent sequenced edit from remote client\n\t\t\t// must have invalidated the queue cache.\n\t\t\tconst entry = this.localRevisionCache.shift();\n\t\t\tif (entry !== undefined) {\n\t\t\t\tconst revision = this.log.numberOfSequencedEdits;\n\t\t\t\tconst { view } = entry;\n\t\t\t\tthis.sequencedRevisionCache.cacheValue(\n\t\t\t\t\trevision,\n\t\t\t\t\tentry.status === EditStatus.Applied\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tview,\n\t\t\t\t\t\t\t\tstatus: entry.status,\n\t\t\t\t\t\t\t\tsteps: entry.steps,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tview,\n\t\t\t\t\t\t\t\tstatus: entry.status,\n\t\t\t\t\t\t\t\tfailure: entry.failure,\n\t\t\t\t\t\t }\n\t\t\t\t);\n\t\t\t\tthis.handleSequencedEditResult(edit, entry, []);\n\t\t\t}\n\t\t} else {\n\t\t\t// Invalidate any cached results of applying edits which are ordered after `edit` (which are all remaining local edits)\n\t\t\tthis.localRevisionCache.clear();\n\t\t}\n\t}\n\n\tpublic async getEditResult(revision: Revision): Promise<EditCacheEntry> {\n\t\tconst startingPoint = this.getStartingPoint(revision);\n\t\tconst { startRevision } = startingPoint;\n\t\tlet current: EditCacheEntry = startingPoint;\n\t\tfor (let i = startRevision; i < revision && i < this.log.length; i++) {\n\t\t\tconst edit = await this.log.getEditAtIndex(i);\n\t\t\tcurrent = this.applyEdit(current.view, edit, i);\n\t\t}\n\t\treturn current;\n\t}\n\n\tpublic async getRevisionView(revision: Revision): Promise<RevisionView> {\n\t\treturn (await this.getEditResult(revision)).view;\n\t}\n\n\tpublic getEditResultInSession(revision: Revision): EditCacheEntry {\n\t\tconst startingPoint = this.getStartingPoint(revision);\n\t\tconst { startRevision } = startingPoint;\n\t\tlet current: EditCacheEntry = startingPoint;\n\t\tfor (let i = startRevision; i < revision && i < this.log.length; i++) {\n\t\t\tconst edit = this.log.getEditInSessionAtIndex(i);\n\t\t\tcurrent = this.applyEdit(current.view, edit, i);\n\t\t}\n\t\treturn current;\n\t}\n\n\tpublic getRevisionViewInSession(revision: Revision): RevisionView {\n\t\treturn this.getEditResultInSession(revision).view;\n\t}\n\n\t/**\n\t * Informs the CachingLogViewer of the latest known minimumSequenceNumber for all connected clients.\n\t * This can be used to provide more aggressive caching of revisions within the collaboration window, as those revisions\n\t * are more likely to be demanded to resolve conflicts.\n\t * @param minSequenceNumber - the minimum known sequence number of all connected clients.\n\t */\n\tpublic setMinimumSequenceNumber(minimumSequenceNumber: number): void {\n\t\t// Sequence numbers in Fluid are 1-indexed, meaning they correspond to revisions, and can be used as revisions.\n\t\t// This ensures that all revisions >= minimumSequenceNumber are kept in the cache, meaning that even if all clients are caught up\n\t\t// the most recent sequenced revision will be cached.\n\t\tthis.sequencedRevisionCache.updateRetentionWindow(minimumSequenceNumber);\n\t}\n\n\t/**\n\t * Inform the CachingLogViewer that a particular edit is known to have a specific result when applied to a particular TreeView.\n\t * CachingLogViewer may use this information as an optimization to avoid re-running the edit if re-applied to the same TreeView.\n\t */\n\tpublic setKnownEditingResult(edit: Edit<ChangeInternal>, result: EditingResult): void {\n\t\tthis.cachedEditResult = { editId: edit.id, result };\n\t}\n\n\t/**\n\t * @returns the cached revision view closest to the requested `revision`.\n\t */\n\tprivate getStartingPoint(revision: Revision): { startRevision: Revision } & EditCacheEntry {\n\t\t// Per the documentation for revision, the returned view should be the output of the edit at the largest index <= `revision`.\n\t\tconst revisionClamped = Math.min(revision, this.log.length);\n\n\t\t// If the highest revision is requested, and it's cached, use highestRevisionCacheEntry.\n\t\tif (revisionClamped === this.log.length && this.highestRevisionCacheEntry !== undefined) {\n\t\t\treturn { ...this.highestRevisionCacheEntry, startRevision: revisionClamped };\n\t\t}\n\n\t\tlet current: EditCacheEntry;\n\t\tlet startRevision: Revision;\n\t\tconst { numberOfSequencedEdits } = this.log;\n\t\tconst isLocalRevision = revisionClamped > numberOfSequencedEdits;\n\t\tif (isLocalRevision && !this.localRevisionCache.isEmpty()) {\n\t\t\tconst { length } = this.localRevisionCache;\n\t\t\t// Local revision view cache is indexed such that the view for revision 0 (a local edit) is stored at index 0 in the cache.\n\t\t\t// This is because the local cache does not contain an entry for the implicit initial tree edit.\n\t\t\tconst localCacheIndex = revisionClamped - 1 - numberOfSequencedEdits;\n\t\t\tif (localCacheIndex < length) {\n\t\t\t\tconst cached =\n\t\t\t\t\tthis.localRevisionCache.peekAt(localCacheIndex) ?? fail('missing tail of localRevisionViewCache');\n\t\t\t\treturn {\n\t\t\t\t\t...cached,\n\t\t\t\t\tstartRevision: revisionClamped,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tcurrent = this.localRevisionCache.peekAt(length - 1) ?? fail('missing tail of localRevisionViewCache');\n\t\t\t\tstartRevision = numberOfSequencedEdits + length;\n\t\t\t}\n\t\t} else {\n\t\t\tconst [cachedRevision, cachedView] =\n\t\t\t\tthis.sequencedRevisionCache.getClosestEntry(revisionClamped) ??\n\t\t\t\tfail('No preceding revision view cached.');\n\n\t\t\tstartRevision = cachedRevision;\n\t\t\tcurrent = cachedView;\n\t\t}\n\t\treturn { startRevision, ...current };\n\t}\n\n\t/**\n\t * Helper for applying an edit at the supplied revision view.\n\t * Must only be called in the order that edits appear in the log.\n\t * Must only be called once for a given local edit as long as the local cache has not been invalidated.\n\t * Must only be called once for a given sequenced edit.\n\t * @returns the resulting revision view and the outcome of edit that produced it.\n\t */\n\tprivate applyEdit(\n\t\tprevView: RevisionView,\n\t\tedit: Edit<ChangeInternal>,\n\t\teditIndex: number\n\t): AttemptedEditResultCacheEntry {\n\t\tlet editingResult: EditingResult;\n\t\tlet cached;\n\t\tlet reconciliationPath: ReconciliationPath = [];\n\t\tif (\n\t\t\tthis.cachedEditResult !== undefined &&\n\t\t\tthis.cachedEditResult.editId === edit.id &&\n\t\t\tthis.cachedEditResult.result.before === prevView\n\t\t) {\n\t\t\teditingResult = this.cachedEditResult.result;\n\t\t\tcached = true;\n\t\t} else {\n\t\t\treconciliationPath = this.reconciliationPathFromEdit(edit.id);\n\t\t\teditingResult = this.transactionFactory(prevView).applyChanges(edit.changes, reconciliationPath).close();\n\t\t\tcached = false;\n\t\t}\n\n\t\tconst revision = editIndex + 1;\n\t\tlet nextView: RevisionView;\n\t\tif (editingResult.status === EditStatus.Applied) {\n\t\t\tnextView = editingResult.after;\n\t\t} else {\n\t\t\tnextView = prevView;\n\t\t}\n\n\t\tconst computedCacheEntry =\n\t\t\teditingResult.status === EditStatus.Applied\n\t\t\t\t? { view: nextView, status: editingResult.status, steps: editingResult.steps }\n\t\t\t\t: { view: nextView, status: editingResult.status, failure: editingResult.failure };\n\n\t\tif (this.log.isSequencedRevision(revision)) {\n\t\t\tthis.sequencedRevisionCache.cacheValue(revision, computedCacheEntry);\n\t\t\tthis.handleSequencedEditResult(edit, computedCacheEntry, reconciliationPath);\n\t\t} else {\n\t\t\t// This relies on local edits being append only, and that generating the view for a local revision requires generating\n\t\t\t// the views for all local revisions before it in the log. Thus, generating such a view will necessarily require\n\t\t\t// calls to this method for all local revisions prior, guaranteeing the correct push order.\n\t\t\tassert(\n\t\t\t\trevision === this.log.numberOfSequencedEdits + this.localRevisionCache.length + 1,\n\t\t\t\t'Local revision view cached out of order.'\n\t\t\t);\n\t\t\tthis.localRevisionCache.push(computedCacheEntry);\n\t\t}\n\n\t\t// Only update highestRevisionCacheEntry if this snapshot is the highest revision.\n\t\tif (revision >= this.log.length) {\n\t\t\tthis.highestRevisionCacheEntry = computedCacheEntry;\n\t\t}\n\n\t\tthis.processEditStatus(editingResult.status, this.log.getIdAtIndex(editIndex), cached);\n\t\treturn computedCacheEntry;\n\t}\n\n\t/**\n\t * Helper for performing caching when a sequenced local edit is first applied.\n\t * Invokes the `processSequencedEditResult` handler that was passed to the constructor (if any).\n\t * Must only be called for non-cached sequenced edits.\n\t */\n\tprivate handleSequencedEditResult(\n\t\tedit: Edit<ChangeInternal>,\n\t\tresult: AttemptedEditResultCacheEntry,\n\t\treconciliationPath: ReconciliationPath\n\t): void {\n\t\tlet wasLocal = false;\n\t\t// This is the first time this sequenced edit has been processed by this LogViewer. If it was a local edit, log telemetry\n\t\t// in the event that it was invalid or malformed.\n\t\tif (this.unappliedSelfEdits.length > 0) {\n\t\t\tif (edit.id === this.unappliedSelfEdits.peekFront()) {\n\t\t\t\twasLocal = true;\n\t\t\t\tthis.unappliedSelfEdits.shift();\n\t\t\t} else if (this.expensiveValidation) {\n\t\t\t\tfor (let i = 0; i < this.unappliedSelfEdits.length; i++) {\n\t\t\t\t\tassert(this.unappliedSelfEdits.peekAt(i) !== edit.id, 'Local edits processed out of order.');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.processSequencedEditResult({ edit, wasLocal, result, reconciliationPath });\n\t}\n\n\t/**\n\t * We currently compute only the \"main branch\" part of the reconciliation path (meaning we don't include inverts of the edits\n\t * that occurred on the rebased branch). Doing so is only needed for the sequential anchor resolution approach which is not\n\t * yet supported.\n\t * @param editId - The ID for the edit to get the reconciliation path for.\n\t */\n\tpublic reconciliationPathFromEdit(editId: EditId): ReconciliationPath {\n\t\tconst reconciliationPath: ReconciliationEdit[] = [];\n\t\tlet cached = false;\n\t\treturn new Proxy(reconciliationPath, {\n\t\t\tget: (target, prop): unknown => {\n\t\t\t\tif (!cached) {\n\t\t\t\t\tcached = true;\n\t\t\t\t\tconst orderedId = this.log.getOrderedEditId(editId);\n\t\t\t\t\tif (orderedId.isLocal === false && orderedId.sequenceInfo !== undefined) {\n\t\t\t\t\t\tconst earliestSequenced = this.earliestSequencedEditInSession();\n\t\t\t\t\t\tif (earliestSequenced !== undefined) {\n\t\t\t\t\t\t\tconst earliestEditSequenceNumber = earliestSequenced.sequenceNumber;\n\t\t\t\t\t\t\tconst targetSequenceNumber = Math.max(\n\t\t\t\t\t\t\t\tearliestEditSequenceNumber,\n\t\t\t\t\t\t\t\torderedId.sequenceInfo.referenceSequenceNumber\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (targetSequenceNumber < orderedId.sequenceInfo.sequenceNumber) {\n\t\t\t\t\t\t\t\tconst firstEdit = this.getEditResultFromSequenceNumber(targetSequenceNumber);\n\t\t\t\t\t\t\t\tif (firstEdit !== undefined) {\n\t\t\t\t\t\t\t\t\tif (firstEdit.status === EditStatus.Applied) {\n\t\t\t\t\t\t\t\t\t\tconst firstEditInfo = this.log.getOrderedEditId(\n\t\t\t\t\t\t\t\t\t\t\tfirstEdit.id\n\t\t\t\t\t\t\t\t\t\t) as SequencedOrderedEditId;\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tfirstEditInfo.sequenceInfo !== undefined &&\n\t\t\t\t\t\t\t\t\t\t\tfirstEditInfo.sequenceInfo.sequenceNumber >\n\t\t\t\t\t\t\t\t\t\t\t\torderedId.sequenceInfo.referenceSequenceNumber\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\treconciliationPath.push({\n\t\t\t\t\t\t\t\t\t\t\t\t...firstEdit.steps,\n\t\t\t\t\t\t\t\t\t\t\t\tbefore: firstEdit.before,\n\t\t\t\t\t\t\t\t\t\t\t\tafter: firstEdit.view,\n\t\t\t\t\t\t\t\t\t\t\t\tlength: firstEdit.steps.length,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tconst lowestIndex = this.log.getIndexOfId(firstEdit.id) + 1;\n\t\t\t\t\t\t\t\t\tconst highestIndex = this.log.getIndexOfId(editId) - 1;\n\t\t\t\t\t\t\t\t\tfor (let index = lowestIndex; index <= highestIndex; ++index) {\n\t\t\t\t\t\t\t\t\t\tconst edit = this.getEditResultFromIndex(index);\n\t\t\t\t\t\t\t\t\t\tif (edit.status === EditStatus.Applied) {\n\t\t\t\t\t\t\t\t\t\t\treconciliationPath.push({\n\t\t\t\t\t\t\t\t\t\t\t\t...edit.steps,\n\t\t\t\t\t\t\t\t\t\t\t\tbefore: edit.before,\n\t\t\t\t\t\t\t\t\t\t\t\tafter: edit.view,\n\t\t\t\t\t\t\t\t\t\t\t\tlength: edit.steps.length,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn target[prop];\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * @returns Edit information for the earliest known sequenced edit.\n\t */\n\tpublic earliestSequencedEditInSession(): { edit: Edit<ChangeInternal>; sequenceNumber: number } | undefined {\n\t\tconst earliestEditIndex = this.log.earliestAvailableEditIndex;\n\t\tconst lastSequencedEdit = this.log.numberOfSequencedEdits + earliestEditIndex - 1;\n\t\tfor (let index = earliestEditIndex; index <= lastSequencedEdit; ++index) {\n\t\t\tconst edit = this.log.getEditInSessionAtIndex(index);\n\t\t\tconst editOrderedId = this.log.getOrderedEditId(edit.id) as SequencedOrderedEditId;\n\t\t\tif (editOrderedId.sequenceInfo !== undefined) {\n\t\t\t\treturn { edit, sequenceNumber: editOrderedId.sequenceInfo.sequenceNumber };\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * @returns Edit result information for the edit at the given `index`.\n\t */\n\tprivate getEditResultFromIndex(index: number): CachedEditingResult {\n\t\tconst edit = this.log.getEditInSessionAtIndex(index);\n\t\tconst before = this.getRevisionViewInSession(index);\n\t\tconst resultAfter = this.getEditResultInSession(index + 1);\n\t\tif (resultAfter.status === undefined) {\n\t\t\tfail('The status of every edit in session should be known');\n\t\t}\n\t\treturn resultAfter.status === EditStatus.Applied\n\t\t\t? {\n\t\t\t\t\tid: edit.id,\n\t\t\t\t\tstatus: EditStatus.Applied,\n\t\t\t\t\tbefore,\n\t\t\t\t\tchanges: edit.changes,\n\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\tsteps: resultAfter.steps,\n\t\t\t }\n\t\t\t: {\n\t\t\t\t\tid: edit.id,\n\t\t\t\t\tstatus: resultAfter.status,\n\t\t\t\t\tfailure: resultAfter.failure,\n\t\t\t\t\tbefore,\n\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\tchanges: edit.changes,\n\t\t\t };\n\t}\n\n\t/**\n\t * @param sequenceNumber - The server-assigned sequenced number assigned to the edit of interest.\n\t * @returns Edit result information for the edit with the given sequence number or the nearest sequenced edit before that.\n\t * Undefined if no sequenced edit occurred at or prior to the given sequenceNumber.\n\t */\n\tpublic getEditResultFromSequenceNumber(sequenceNumber: number): CachedEditingResult | undefined {\n\t\tconst earliestSequenced = this.earliestSequencedEditInSession();\n\t\tif (earliestSequenced !== undefined && sequenceNumber >= earliestSequenced.sequenceNumber) {\n\t\t\tconst lowestIndex = this.log.getIndexOfId(earliestSequenced.edit.id);\n\t\t\tconst highestIndex = this.log.numberOfSequencedEdits - 1;\n\t\t\tfor (let index = highestIndex; index >= lowestIndex; --index) {\n\t\t\t\tconst edit = this.log.getEditInSessionAtIndex(index);\n\t\t\t\tconst orderedId = this.log.getOrderedEditId(edit.id) as SequencedOrderedEditId;\n\t\t\t\t// If `orderedId.sequenceInfo.sequenceNumber` is equal to the requested `sequenceNumber` then we have found the edit of\n\t\t\t\t// interest and simply return its associated information.\n\t\t\t\t// Note that the check bellow also is also satisfied if `orderedId.sequenceInfo.sequenceNumber`is lower than the requested\n\t\t\t\t// `sequenceNumber`. This can happen when the edit for the requested `sequenceNumber` has either not yet been received or\n\t\t\t\t// has been processed by a different DDS (several DDSes can share the same stream of operations and will only see those\n\t\t\t\t// relevant to them). In such cases, we return the edit info for the last known edit before that.\n\t\t\t\tif (orderedId.sequenceInfo && orderedId.sequenceInfo.sequenceNumber <= sequenceNumber) {\n\t\t\t\t\tconst before = this.getRevisionViewInSession(index);\n\t\t\t\t\tconst resultAfter = this.getEditResultInSession(index + 1);\n\t\t\t\t\tif (resultAfter.status === undefined) {\n\t\t\t\t\t\tfail('The status of every edit in session should be known');\n\t\t\t\t\t}\n\t\t\t\t\treturn resultAfter.status === EditStatus.Applied\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tid: edit.id,\n\t\t\t\t\t\t\t\tstatus: EditStatus.Applied,\n\t\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\t\tchanges: edit.changes,\n\t\t\t\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\t\t\t\tsteps: resultAfter.steps,\n\t\t\t\t\t\t }\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tid: edit.id,\n\t\t\t\t\t\t\t\tstatus: resultAfter.status,\n\t\t\t\t\t\t\t\tfailure: resultAfter.failure,\n\t\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\t\tview: resultAfter.view,\n\t\t\t\t\t\t\t\tchanges: edit.changes,\n\t\t\t\t\t\t };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"]}