@fluidframework/sequence 2.0.0-rc.2.0.2 → 2.0.0-rc.3.0.1

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 (313) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +1 -1
  3. package/api-report/sequence.api.md +32 -32
  4. package/beta.d.ts +11 -0
  5. package/dist/{localValues.d.ts → IntervalCollectionValues.d.ts} +13 -12
  6. package/dist/IntervalCollectionValues.d.ts.map +1 -0
  7. package/dist/{localValues.js → IntervalCollectionValues.js} +6 -6
  8. package/dist/IntervalCollectionValues.js.map +1 -0
  9. package/dist/beta.d.ts +12 -0
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +10 -10
  13. package/dist/index.js.map +1 -1
  14. package/dist/intervalCollection.d.ts +10 -10
  15. package/dist/intervalCollection.d.ts.map +1 -1
  16. package/dist/intervalCollection.js +103 -99
  17. package/dist/intervalCollection.js.map +1 -1
  18. package/dist/{defaultMap.d.ts → intervalCollectionMap.d.ts} +11 -44
  19. package/dist/intervalCollectionMap.d.ts.map +1 -0
  20. package/dist/{defaultMap.js → intervalCollectionMap.js} +15 -70
  21. package/dist/intervalCollectionMap.js.map +1 -0
  22. package/dist/{defaultMapInterfaces.d.ts → intervalCollectionMapInterfaces.d.ts} +17 -16
  23. package/dist/intervalCollectionMapInterfaces.d.ts.map +1 -0
  24. package/dist/{defaultMapInterfaces.js → intervalCollectionMapInterfaces.js} +1 -1
  25. package/dist/intervalCollectionMapInterfaces.js.map +1 -0
  26. package/dist/intervalIndex/endpointInRangeIndex.d.ts +1 -1
  27. package/dist/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
  28. package/dist/intervalIndex/endpointInRangeIndex.js +3 -3
  29. package/dist/intervalIndex/endpointInRangeIndex.js.map +1 -1
  30. package/dist/intervalIndex/endpointIndex.d.ts +1 -1
  31. package/dist/intervalIndex/endpointIndex.d.ts.map +1 -1
  32. package/dist/intervalIndex/endpointIndex.js +3 -3
  33. package/dist/intervalIndex/endpointIndex.js.map +1 -1
  34. package/dist/intervalIndex/idIntervalIndex.d.ts.map +1 -1
  35. package/dist/intervalIndex/idIntervalIndex.js +3 -3
  36. package/dist/intervalIndex/idIntervalIndex.js.map +1 -1
  37. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +3 -3
  38. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
  39. package/dist/intervalIndex/overlappingIntervalsIndex.js +2 -3
  40. package/dist/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
  41. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -1
  42. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js +6 -6
  43. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -1
  44. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts +1 -1
  45. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -1
  46. package/dist/intervalIndex/sequenceIntervalIndexes.js.map +1 -1
  47. package/dist/intervalIndex/startpointInRangeIndex.d.ts +1 -1
  48. package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
  49. package/dist/intervalIndex/startpointInRangeIndex.js +3 -3
  50. package/dist/intervalIndex/startpointInRangeIndex.js.map +1 -1
  51. package/dist/intervalTree.d.ts +1 -1
  52. package/dist/intervalTree.d.ts.map +1 -1
  53. package/dist/intervalTree.js +2 -2
  54. package/dist/intervalTree.js.map +1 -1
  55. package/dist/intervals/interval.d.ts +1 -1
  56. package/dist/intervals/interval.d.ts.map +1 -1
  57. package/dist/intervals/interval.js +10 -10
  58. package/dist/intervals/interval.js.map +1 -1
  59. package/dist/intervals/intervalUtils.d.ts +1 -1
  60. package/dist/intervals/intervalUtils.d.ts.map +1 -1
  61. package/dist/intervals/intervalUtils.js +5 -5
  62. package/dist/intervals/intervalUtils.js.map +1 -1
  63. package/dist/intervals/sequenceInterval.d.ts +1 -1
  64. package/dist/intervals/sequenceInterval.d.ts.map +1 -1
  65. package/dist/intervals/sequenceInterval.js +34 -34
  66. package/dist/intervals/sequenceInterval.js.map +1 -1
  67. package/dist/legacy.d.ts +61 -0
  68. package/dist/packageVersion.d.ts +1 -1
  69. package/dist/packageVersion.js +1 -1
  70. package/dist/packageVersion.js.map +1 -1
  71. package/dist/public.d.ts +12 -0
  72. package/dist/revertibles.d.ts +2 -2
  73. package/dist/revertibles.d.ts.map +1 -1
  74. package/dist/revertibles.js +34 -34
  75. package/dist/revertibles.js.map +1 -1
  76. package/dist/sequence.d.ts +7 -6
  77. package/dist/sequence.d.ts.map +1 -1
  78. package/dist/sequence.js +34 -34
  79. package/dist/sequence.js.map +1 -1
  80. package/dist/sequenceDeltaEvent.d.ts +1 -1
  81. package/dist/sequenceDeltaEvent.d.ts.map +1 -1
  82. package/dist/sequenceDeltaEvent.js +4 -4
  83. package/dist/sequenceDeltaEvent.js.map +1 -1
  84. package/dist/sequenceFactory.d.ts +1 -1
  85. package/dist/sequenceFactory.d.ts.map +1 -1
  86. package/dist/sequenceFactory.js +3 -3
  87. package/dist/sequenceFactory.js.map +1 -1
  88. package/dist/sharedIntervalCollection.d.ts +4 -3
  89. package/dist/sharedIntervalCollection.d.ts.map +1 -1
  90. package/dist/sharedIntervalCollection.js +5 -5
  91. package/dist/sharedIntervalCollection.js.map +1 -1
  92. package/dist/sharedSequence.d.ts +3 -2
  93. package/dist/sharedSequence.d.ts.map +1 -1
  94. package/dist/sharedSequence.js +4 -4
  95. package/dist/sharedSequence.js.map +1 -1
  96. package/dist/sharedString.d.ts +2 -2
  97. package/dist/sharedString.d.ts.map +1 -1
  98. package/dist/sharedString.js +9 -9
  99. package/dist/sharedString.js.map +1 -1
  100. package/internal.d.ts +11 -0
  101. package/legacy.d.ts +11 -0
  102. package/lib/{localValues.d.ts → IntervalCollectionValues.d.ts} +13 -12
  103. package/lib/IntervalCollectionValues.d.ts.map +1 -0
  104. package/lib/{localValues.js → IntervalCollectionValues.js} +3 -3
  105. package/lib/IntervalCollectionValues.js.map +1 -0
  106. package/lib/beta.d.ts +12 -0
  107. package/lib/index.d.ts +2 -2
  108. package/lib/index.d.ts.map +1 -1
  109. package/lib/index.js +1 -1
  110. package/lib/index.js.map +1 -1
  111. package/lib/intervalCollection.d.ts +10 -10
  112. package/lib/intervalCollection.d.ts.map +1 -1
  113. package/lib/intervalCollection.js +8 -4
  114. package/lib/intervalCollection.js.map +1 -1
  115. package/lib/{defaultMap.d.ts → intervalCollectionMap.d.ts} +11 -44
  116. package/lib/intervalCollectionMap.d.ts.map +1 -0
  117. package/lib/{defaultMap.js → intervalCollectionMap.js} +8 -63
  118. package/lib/intervalCollectionMap.js.map +1 -0
  119. package/lib/{defaultMapInterfaces.d.ts → intervalCollectionMapInterfaces.d.ts} +17 -16
  120. package/lib/intervalCollectionMapInterfaces.d.ts.map +1 -0
  121. package/lib/{defaultMapInterfaces.js → intervalCollectionMapInterfaces.js} +1 -1
  122. package/lib/intervalCollectionMapInterfaces.js.map +1 -0
  123. package/lib/intervalIndex/endpointInRangeIndex.d.ts +1 -1
  124. package/lib/intervalIndex/endpointInRangeIndex.d.ts.map +1 -1
  125. package/lib/intervalIndex/endpointInRangeIndex.js +1 -1
  126. package/lib/intervalIndex/endpointInRangeIndex.js.map +1 -1
  127. package/lib/intervalIndex/endpointIndex.d.ts +1 -1
  128. package/lib/intervalIndex/endpointIndex.d.ts.map +1 -1
  129. package/lib/intervalIndex/endpointIndex.js +1 -1
  130. package/lib/intervalIndex/endpointIndex.js.map +1 -1
  131. package/lib/intervalIndex/idIntervalIndex.d.ts.map +1 -1
  132. package/lib/intervalIndex/idIntervalIndex.js +1 -1
  133. package/lib/intervalIndex/idIntervalIndex.js.map +1 -1
  134. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts +3 -3
  135. package/lib/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -1
  136. package/lib/intervalIndex/overlappingIntervalsIndex.js +2 -3
  137. package/lib/intervalIndex/overlappingIntervalsIndex.js.map +1 -1
  138. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -1
  139. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js +2 -2
  140. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.js.map +1 -1
  141. package/lib/intervalIndex/sequenceIntervalIndexes.d.ts +1 -1
  142. package/lib/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -1
  143. package/lib/intervalIndex/sequenceIntervalIndexes.js.map +1 -1
  144. package/lib/intervalIndex/startpointInRangeIndex.d.ts +1 -1
  145. package/lib/intervalIndex/startpointInRangeIndex.d.ts.map +1 -1
  146. package/lib/intervalIndex/startpointInRangeIndex.js +1 -1
  147. package/lib/intervalIndex/startpointInRangeIndex.js.map +1 -1
  148. package/lib/intervalTree.d.ts +1 -1
  149. package/lib/intervalTree.d.ts.map +1 -1
  150. package/lib/intervalTree.js +1 -1
  151. package/lib/intervalTree.js.map +1 -1
  152. package/lib/intervals/interval.d.ts +1 -1
  153. package/lib/intervals/interval.d.ts.map +1 -1
  154. package/lib/intervals/interval.js +3 -3
  155. package/lib/intervals/interval.js.map +1 -1
  156. package/lib/intervals/intervalUtils.d.ts +1 -1
  157. package/lib/intervals/intervalUtils.d.ts.map +1 -1
  158. package/lib/intervals/intervalUtils.js +1 -1
  159. package/lib/intervals/intervalUtils.js.map +1 -1
  160. package/lib/intervals/sequenceInterval.d.ts +1 -1
  161. package/lib/intervals/sequenceInterval.d.ts.map +1 -1
  162. package/lib/intervals/sequenceInterval.js +3 -3
  163. package/lib/intervals/sequenceInterval.js.map +1 -1
  164. package/lib/legacy.d.ts +61 -0
  165. package/lib/packageVersion.d.ts +1 -1
  166. package/lib/packageVersion.js +1 -1
  167. package/lib/packageVersion.js.map +1 -1
  168. package/lib/public.d.ts +12 -0
  169. package/lib/revertibles.d.ts +2 -2
  170. package/lib/revertibles.d.ts.map +1 -1
  171. package/lib/revertibles.js +3 -4
  172. package/lib/revertibles.js.map +1 -1
  173. package/lib/sequence.d.ts +7 -6
  174. package/lib/sequence.d.ts.map +1 -1
  175. package/lib/sequence.js +11 -12
  176. package/lib/sequence.js.map +1 -1
  177. package/lib/sequenceDeltaEvent.d.ts +1 -1
  178. package/lib/sequenceDeltaEvent.d.ts.map +1 -1
  179. package/lib/sequenceDeltaEvent.js +3 -4
  180. package/lib/sequenceDeltaEvent.js.map +1 -1
  181. package/lib/sequenceFactory.d.ts +1 -1
  182. package/lib/sequenceFactory.d.ts.map +1 -1
  183. package/lib/sequenceFactory.js +1 -1
  184. package/lib/sequenceFactory.js.map +1 -1
  185. package/lib/sharedIntervalCollection.d.ts +4 -3
  186. package/lib/sharedIntervalCollection.d.ts.map +1 -1
  187. package/lib/sharedIntervalCollection.js +4 -4
  188. package/lib/sharedIntervalCollection.js.map +1 -1
  189. package/lib/sharedSequence.d.ts +3 -2
  190. package/lib/sharedSequence.d.ts.map +1 -1
  191. package/lib/sharedSequence.js +2 -2
  192. package/lib/sharedSequence.js.map +1 -1
  193. package/lib/sharedString.d.ts +2 -2
  194. package/lib/sharedString.d.ts.map +1 -1
  195. package/lib/sharedString.js +1 -1
  196. package/lib/sharedString.js.map +1 -1
  197. package/package.json +41 -58
  198. package/src/{localValues.ts → IntervalCollectionValues.ts} +26 -18
  199. package/src/index.ts +2 -2
  200. package/src/intervalCollection.ts +46 -47
  201. package/src/{defaultMap.ts → intervalCollectionMap.ts} +42 -105
  202. package/src/{defaultMapInterfaces.ts → intervalCollectionMapInterfaces.ts} +26 -16
  203. package/src/intervalIndex/endpointInRangeIndex.ts +4 -1
  204. package/src/intervalIndex/endpointIndex.ts +4 -1
  205. package/src/intervalIndex/idIntervalIndex.ts +4 -2
  206. package/src/intervalIndex/overlappingIntervalsIndex.ts +8 -5
  207. package/src/intervalIndex/overlappingSequenceIntervalsIndex.ts +6 -3
  208. package/src/intervalIndex/sequenceIntervalIndexes.ts +3 -1
  209. package/src/intervalIndex/startpointInRangeIndex.ts +4 -1
  210. package/src/intervalTree.ts +4 -3
  211. package/src/intervals/interval.ts +6 -3
  212. package/src/intervals/intervalUtils.ts +4 -2
  213. package/src/intervals/sequenceInterval.ts +5 -3
  214. package/src/packageVersion.ts +1 -1
  215. package/src/revertibles.ts +10 -10
  216. package/src/sequence.ts +24 -31
  217. package/src/sequenceDeltaEvent.ts +3 -4
  218. package/src/sequenceFactory.ts +4 -3
  219. package/src/sharedIntervalCollection.ts +12 -18
  220. package/src/sharedSequence.ts +9 -6
  221. package/src/sharedString.ts +4 -3
  222. package/api-extractor-cjs.json +0 -8
  223. package/dist/defaultMap.d.ts.map +0 -1
  224. package/dist/defaultMap.js.map +0 -1
  225. package/dist/defaultMapInterfaces.d.ts.map +0 -1
  226. package/dist/defaultMapInterfaces.js.map +0 -1
  227. package/dist/localValues.d.ts.map +0 -1
  228. package/dist/localValues.js.map +0 -1
  229. package/dist/sequence-alpha.d.ts +0 -1432
  230. package/dist/sequence-beta.d.ts +0 -246
  231. package/dist/sequence-public.d.ts +0 -246
  232. package/dist/sequence-untrimmed.d.ts +0 -1820
  233. package/lib/defaultMap.d.ts.map +0 -1
  234. package/lib/defaultMap.js.map +0 -1
  235. package/lib/defaultMapInterfaces.d.ts.map +0 -1
  236. package/lib/defaultMapInterfaces.js.map +0 -1
  237. package/lib/localValues.d.ts.map +0 -1
  238. package/lib/localValues.js.map +0 -1
  239. package/lib/sequence-alpha.d.ts +0 -1432
  240. package/lib/sequence-beta.d.ts +0 -246
  241. package/lib/sequence-public.d.ts +0 -246
  242. package/lib/sequence-untrimmed.d.ts +0 -1820
  243. package/lib/test/collections.intervalTree.js +0 -73
  244. package/lib/test/collections.intervalTree.js.map +0 -1
  245. package/lib/test/createSnapshotFiles.js +0 -15
  246. package/lib/test/createSnapshotFiles.js.map +0 -1
  247. package/lib/test/dirname.cjs +0 -16
  248. package/lib/test/dirname.cjs.map +0 -1
  249. package/lib/test/endpointInRangeIndex.spec.js +0 -182
  250. package/lib/test/endpointInRangeIndex.spec.js.map +0 -1
  251. package/lib/test/fuzz/fuzzUtils.js +0 -250
  252. package/lib/test/fuzz/fuzzUtils.js.map +0 -1
  253. package/lib/test/fuzz/intervalCollection.fuzz.spec.js +0 -200
  254. package/lib/test/fuzz/intervalCollection.fuzz.spec.js.map +0 -1
  255. package/lib/test/fuzz/intervalRevertibles.fuzz.spec.js +0 -129
  256. package/lib/test/fuzz/intervalRevertibles.fuzz.spec.js.map +0 -1
  257. package/lib/test/fuzz/sharedString.fuzz.spec.js +0 -91
  258. package/lib/test/fuzz/sharedString.fuzz.spec.js.map +0 -1
  259. package/lib/test/generateSharedStrings.js +0 -138
  260. package/lib/test/generateSharedStrings.js.map +0 -1
  261. package/lib/test/intervalCollection.detached.spec.js +0 -126
  262. package/lib/test/intervalCollection.detached.spec.js.map +0 -1
  263. package/lib/test/intervalCollection.events.spec.js +0 -491
  264. package/lib/test/intervalCollection.events.spec.js.map +0 -1
  265. package/lib/test/intervalCollection.perf.spec.js +0 -88
  266. package/lib/test/intervalCollection.perf.spec.js.map +0 -1
  267. package/lib/test/intervalCollection.snapshot.spec.js +0 -171
  268. package/lib/test/intervalCollection.snapshot.spec.js.map +0 -1
  269. package/lib/test/intervalCollection.spec.js +0 -1660
  270. package/lib/test/intervalCollection.spec.js.map +0 -1
  271. package/lib/test/intervalIndexTestUtils.js +0 -49
  272. package/lib/test/intervalIndexTestUtils.js.map +0 -1
  273. package/lib/test/intervalRebasing.spec.js +0 -589
  274. package/lib/test/intervalRebasing.spec.js.map +0 -1
  275. package/lib/test/intervalStashedOps.spec.js +0 -142
  276. package/lib/test/intervalStashedOps.spec.js.map +0 -1
  277. package/lib/test/intervalTestUtils.js +0 -81
  278. package/lib/test/intervalTestUtils.js.map +0 -1
  279. package/lib/test/marshalling.spec.js +0 -55
  280. package/lib/test/marshalling.spec.js.map +0 -1
  281. package/lib/test/memory/sharedSequence.spec.js +0 -82
  282. package/lib/test/memory/sharedSequence.spec.js.map +0 -1
  283. package/lib/test/memory/sharedString.spec.js +0 -134
  284. package/lib/test/memory/sharedString.spec.js.map +0 -1
  285. package/lib/test/overlappingSequenceIntervalsIndex.spec.js +0 -348
  286. package/lib/test/overlappingSequenceIntervalsIndex.spec.js.map +0 -1
  287. package/lib/test/partialLoad.spec.js +0 -211
  288. package/lib/test/partialLoad.spec.js.map +0 -1
  289. package/lib/test/rebasing.spec.js +0 -81
  290. package/lib/test/rebasing.spec.js.map +0 -1
  291. package/lib/test/reentrancy.spec.js +0 -174
  292. package/lib/test/reentrancy.spec.js.map +0 -1
  293. package/lib/test/revertibles.spec.js +0 -971
  294. package/lib/test/revertibles.spec.js.map +0 -1
  295. package/lib/test/sequenceDeltaEvent.spec.js +0 -2144
  296. package/lib/test/sequenceDeltaEvent.spec.js.map +0 -1
  297. package/lib/test/sharedIntervalCollection.spec.js +0 -159
  298. package/lib/test/sharedIntervalCollection.spec.js.map +0 -1
  299. package/lib/test/sharedString.spec.js +0 -532
  300. package/lib/test/sharedString.spec.js.map +0 -1
  301. package/lib/test/snapshotEmptyProps.spec.js +0 -45
  302. package/lib/test/snapshotEmptyProps.spec.js.map +0 -1
  303. package/lib/test/snapshotVersion.spec.js +0 -149
  304. package/lib/test/snapshotVersion.spec.js.map +0 -1
  305. package/lib/test/startpointInRangeIndex.spec.js +0 -182
  306. package/lib/test/startpointInRangeIndex.spec.js.map +0 -1
  307. package/lib/test/subSequence.spec.js +0 -92
  308. package/lib/test/subSequence.spec.js.map +0 -1
  309. package/lib/test/types/validateSequencePrevious.generated.js +0 -162
  310. package/lib/test/types/validateSequencePrevious.generated.js.map +0 -1
  311. package/lib/test/v1IntervalCollectionHelpers.js +0 -93
  312. package/lib/test/v1IntervalCollectionHelpers.js.map +0 -1
  313. /package/{dist → lib}/tsdoc-metadata.json +0 -0
@@ -1,211 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { strict as assert } from "assert";
6
- import { MockFluidDataStoreRuntime, MockContainerRuntimeFactory, MockStorage, } from "@fluidframework/test-runtime-utils";
7
- import { ReferenceType } from "@fluidframework/merge-tree";
8
- import { SharedStringFactory, SharedString } from "../index.js";
9
- function applyOperations(sharedString, content = sharedString.getLength().toString()) {
10
- const lenMod = sharedString.getLength() % 4;
11
- switch (lenMod) {
12
- case 0:
13
- sharedString.insertText(0, content);
14
- break;
15
- case 1: {
16
- const pos = Math.floor(sharedString.getLength() / lenMod);
17
- sharedString.insertMarker(pos, ReferenceType.Simple);
18
- break;
19
- }
20
- case 2: {
21
- sharedString.insertText(sharedString.getLength(), content);
22
- const pos = Math.floor(sharedString.getLength() / lenMod);
23
- sharedString.removeText(pos, pos + 1);
24
- // fall through to insert after remove
25
- }
26
- default:
27
- sharedString.insertText(sharedString.getLength(), content);
28
- }
29
- }
30
- const mergeTreeSnapshotChunkSize = 5;
31
- function generateSummaryTree(containerRuntimeFactory, options = {}) {
32
- const dataStoreRuntime1 = new MockFluidDataStoreRuntime();
33
- dataStoreRuntime1.options = options;
34
- // Connect the first SharedString.
35
- const containerRuntime1 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime1);
36
- const services1 = {
37
- deltaConnection: dataStoreRuntime1.createDeltaConnection(),
38
- objectStorage: new MockStorage(),
39
- };
40
- const sharedString = new SharedString(dataStoreRuntime1, "shared-string", SharedStringFactory.Attributes);
41
- sharedString.initializeLocal();
42
- sharedString.connect(services1);
43
- // Create and connect a second SharedString.
44
- const dataStoreRuntime2 = new MockFluidDataStoreRuntime();
45
- dataStoreRuntime2.options = options;
46
- const containerRuntime2 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime2);
47
- const sharedString2 = new SharedString(dataStoreRuntime2, "shared-string", SharedStringFactory.Attributes);
48
- const services2 = {
49
- deltaConnection: dataStoreRuntime2.createDeltaConnection(),
50
- objectStorage: new MockStorage(),
51
- };
52
- sharedString2.initializeLocal();
53
- sharedString2.connect(services2);
54
- while (sharedString.getLength() < mergeTreeSnapshotChunkSize * 3) {
55
- applyOperations(sharedString);
56
- containerRuntimeFactory.processAllMessages();
57
- }
58
- assert.equal(sharedString2.getText(), sharedString.getText());
59
- const summaryTree = sharedString2.getAttachSummary().summary;
60
- assert(summaryTree);
61
- return [sharedString2, summaryTree];
62
- }
63
- describe("SharedString Partial Load", () => {
64
- it("Validate Full Load", async () => {
65
- const containerRuntimeFactory = new MockContainerRuntimeFactory();
66
- const options = { mergeTreeSnapshotChunkSize };
67
- const [remoteSharedString, summaryTree] = generateSummaryTree(containerRuntimeFactory, options);
68
- const localDataStoreRuntime = new MockFluidDataStoreRuntime();
69
- localDataStoreRuntime.options = options;
70
- containerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);
71
- const localServices = {
72
- deltaConnection: localDataStoreRuntime.createDeltaConnection(),
73
- objectStorage: MockStorage.createFromSummary(summaryTree),
74
- };
75
- const localSharedString = new SharedString(localDataStoreRuntime, "shared-string", SharedStringFactory.Attributes);
76
- await localSharedString.load(localServices);
77
- assert.equal(localSharedString.getText(), remoteSharedString.getText());
78
- });
79
- it("Validate New Format Load", async () => {
80
- const containerRuntimeFactory = new MockContainerRuntimeFactory();
81
- const options = { newMergeTreeSnapshotFormat: true, mergeTreeSnapshotChunkSize };
82
- const [remoteSharedString, summaryTree] = generateSummaryTree(containerRuntimeFactory, options);
83
- const localDataStoreRuntime = new MockFluidDataStoreRuntime();
84
- localDataStoreRuntime.options = options;
85
- containerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);
86
- const localServices = {
87
- deltaConnection: localDataStoreRuntime.createDeltaConnection(),
88
- objectStorage: MockStorage.createFromSummary(summaryTree),
89
- };
90
- const localSharedString = new SharedString(localDataStoreRuntime, "shared-string", SharedStringFactory.Attributes);
91
- await localSharedString.load(localServices);
92
- assert.equal(localSharedString.getText(), remoteSharedString.getText());
93
- });
94
- it("Validate Partial load", async () => {
95
- const containerRuntimeFactory = new MockContainerRuntimeFactory();
96
- const options = {
97
- newMergeTreeSnapshotFormat: true,
98
- sequenceInitializeFromHeaderOnly: true,
99
- mergeTreeSnapshotChunkSize,
100
- };
101
- const [remoteSharedString, summaryTree] = generateSummaryTree(containerRuntimeFactory, options);
102
- const localDataStoreRuntime = new MockFluidDataStoreRuntime();
103
- localDataStoreRuntime.options = options;
104
- containerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);
105
- const localServices = {
106
- deltaConnection: localDataStoreRuntime.createDeltaConnection(),
107
- objectStorage: MockStorage.createFromSummary(summaryTree),
108
- };
109
- const localSharedString = new SharedString(localDataStoreRuntime, "shared-string", SharedStringFactory.Attributes);
110
- await localSharedString.load(localServices);
111
- assert.notEqual(localSharedString.getText(), remoteSharedString.getText());
112
- await localSharedString.loaded;
113
- localDataStoreRuntime.deltaManager.lastSequenceNumber = localSharedString.getCurrentSeq();
114
- assert.equal(localSharedString.getText(), remoteSharedString.getText());
115
- });
116
- it("Validate Partial load with local ops", async () => {
117
- const containerRuntimeFactory = new MockContainerRuntimeFactory();
118
- const options = {
119
- sequenceInitializeFromHeaderOnly: true,
120
- mergeTreeSnapshotChunkSize,
121
- };
122
- const [remoteSharedString, summaryTree] = generateSummaryTree(containerRuntimeFactory, options);
123
- const localDataStoreRuntime = new MockFluidDataStoreRuntime();
124
- localDataStoreRuntime.options = options;
125
- containerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);
126
- const localServices = {
127
- deltaConnection: localDataStoreRuntime.createDeltaConnection(),
128
- objectStorage: MockStorage.createFromSummary(summaryTree),
129
- };
130
- const localSharedString = new SharedString(localDataStoreRuntime, "shared-string", SharedStringFactory.Attributes);
131
- await localSharedString.load(localServices);
132
- localDataStoreRuntime.deltaManager.lastSequenceNumber =
133
- containerRuntimeFactory.sequenceNumber;
134
- localDataStoreRuntime.deltaManager.minimumSequenceNumber =
135
- containerRuntimeFactory.getMinSeq();
136
- assert.notEqual(localSharedString.getText(), remoteSharedString.getText());
137
- for (let i = 0; i < 10; i++) {
138
- applyOperations(localSharedString, "L");
139
- }
140
- assert.equal(containerRuntimeFactory.outstandingMessageCount, 0);
141
- await localSharedString.loaded;
142
- assert.notEqual(localSharedString.getText(), remoteSharedString.getText());
143
- assert.notEqual(containerRuntimeFactory.outstandingMessageCount, 0);
144
- containerRuntimeFactory.processAllMessages();
145
- assert.equal(localSharedString.getText(), remoteSharedString.getText());
146
- });
147
- it("Validate Partial load with remote ops", async () => {
148
- const containerRuntimeFactory = new MockContainerRuntimeFactory();
149
- const options = {
150
- sequenceInitializeFromHeaderOnly: true,
151
- mergeTreeSnapshotChunkSize,
152
- };
153
- const [remoteSharedString, summaryTree] = generateSummaryTree(containerRuntimeFactory, options);
154
- const localDataStoreRuntime = new MockFluidDataStoreRuntime();
155
- localDataStoreRuntime.options = options;
156
- containerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);
157
- const localServices = {
158
- deltaConnection: localDataStoreRuntime.createDeltaConnection(),
159
- objectStorage: MockStorage.createFromSummary(summaryTree),
160
- };
161
- const localSharedString = new SharedString(localDataStoreRuntime, "shared-string", SharedStringFactory.Attributes);
162
- await localSharedString.load(localServices);
163
- localDataStoreRuntime.deltaManager.lastSequenceNumber =
164
- containerRuntimeFactory.sequenceNumber;
165
- localDataStoreRuntime.deltaManager.minimumSequenceNumber =
166
- containerRuntimeFactory.getMinSeq();
167
- assert.notEqual(localSharedString.getText(), remoteSharedString.getText());
168
- for (let i = 0; i < 10; i++) {
169
- applyOperations(remoteSharedString, "R");
170
- }
171
- containerRuntimeFactory.processAllMessages();
172
- assert.notEqual(localSharedString.getText(), remoteSharedString.getText());
173
- await localSharedString.loaded;
174
- assert.equal(localSharedString.getText(), remoteSharedString.getText());
175
- });
176
- it("Validate Partial load with local and remote ops", async () => {
177
- const containerRuntimeFactory = new MockContainerRuntimeFactory();
178
- const options = {
179
- sequenceInitializeFromHeaderOnly: true,
180
- mergeTreeSnapshotChunkSize,
181
- };
182
- const [remoteSharedString, summaryTree] = generateSummaryTree(containerRuntimeFactory, options);
183
- const localDataStoreRuntime = new MockFluidDataStoreRuntime();
184
- localDataStoreRuntime.options = options;
185
- containerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);
186
- const localServices = {
187
- deltaConnection: localDataStoreRuntime.createDeltaConnection(),
188
- objectStorage: MockStorage.createFromSummary(summaryTree),
189
- };
190
- const localSharedString = new SharedString(localDataStoreRuntime, "shared-string", SharedStringFactory.Attributes);
191
- await localSharedString.load(localServices);
192
- localDataStoreRuntime.deltaManager.lastSequenceNumber =
193
- containerRuntimeFactory.sequenceNumber;
194
- localDataStoreRuntime.deltaManager.minimumSequenceNumber =
195
- containerRuntimeFactory.getMinSeq();
196
- assert.notEqual(localSharedString.getText(), remoteSharedString.getText());
197
- for (let i = 0; i < 10; i++) {
198
- applyOperations(remoteSharedString, "R");
199
- }
200
- for (let i = 0; i < 10; i++) {
201
- applyOperations(localSharedString, "L");
202
- }
203
- containerRuntimeFactory.processAllMessages();
204
- assert.notEqual(localSharedString.getText(), remoteSharedString.getText());
205
- await localSharedString.loaded;
206
- assert.notEqual(localSharedString.getText(), remoteSharedString.getText());
207
- containerRuntimeFactory.processAllMessages();
208
- assert.equal(localSharedString.getText(), remoteSharedString.getText());
209
- });
210
- });
211
- //# sourceMappingURL=partialLoad.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"partialLoad.spec.js","sourceRoot":"","sources":["../../src/test/partialLoad.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EACN,yBAAyB,EACzB,2BAA2B,EAC3B,WAAW,GACX,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhE,SAAS,eAAe,CACvB,YAA0B,EAC1B,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE;IAE7C,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC5C,QAAQ,MAAM,EAAE;QACf,KAAK,CAAC;YACL,YAAY,CAAC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACpC,MAAM;QAEP,KAAK,CAAC,CAAC,CAAC;YACP,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,GAAG,MAAM,CAAC,CAAC;YAC1D,YAAY,CAAC,YAAY,CAAC,GAAG,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;YACrD,MAAM;SACN;QAED,KAAK,CAAC,CAAC,CAAC;YACP,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;YAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,GAAG,MAAM,CAAC,CAAC;YAC1D,YAAY,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;YACtC,sCAAsC;SACtC;QACD;YACC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;KAC5D;AACF,CAAC;AAED,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAErC,SAAS,mBAAmB,CAC3B,uBAAoD,EACpD,UAAe,EAAE;IAEjB,MAAM,iBAAiB,GAAG,IAAI,yBAAyB,EAAE,CAAC;IAC1D,iBAAiB,CAAC,OAAO,GAAG,OAAO,CAAC;IACpC,kCAAkC;IAClC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;IAC5F,MAAM,SAAS,GAAqB;QACnC,eAAe,EAAE,iBAAiB,CAAC,qBAAqB,EAAE;QAC1D,aAAa,EAAE,IAAI,WAAW,EAAE;KAChC,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,YAAY,CACpC,iBAAiB,EACjB,eAAe,EACf,mBAAmB,CAAC,UAAU,CAC9B,CAAC;IACF,YAAY,CAAC,eAAe,EAAE,CAAC;IAC/B,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,4CAA4C;IAC5C,MAAM,iBAAiB,GAAG,IAAI,yBAAyB,EAAE,CAAC;IAC1D,iBAAiB,CAAC,OAAO,GAAG,OAAO,CAAC;IACpC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;IAC5F,MAAM,aAAa,GAAG,IAAI,YAAY,CACrC,iBAAiB,EACjB,eAAe,EACf,mBAAmB,CAAC,UAAU,CAC9B,CAAC;IACF,MAAM,SAAS,GAAqB;QACnC,eAAe,EAAE,iBAAiB,CAAC,qBAAqB,EAAE;QAC1D,aAAa,EAAE,IAAI,WAAW,EAAE;KAChC,CAAC;IACF,aAAa,CAAC,eAAe,EAAE,CAAC;IAChC,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEjC,OAAO,YAAY,CAAC,SAAS,EAAE,GAAG,0BAA0B,GAAG,CAAC,EAAE;QACjE,eAAe,CAAC,YAAY,CAAC,CAAC;QAC9B,uBAAuB,CAAC,kBAAkB,EAAE,CAAC;KAC7C;IACD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9D,MAAM,WAAW,GAAG,aAAa,CAAC,gBAAgB,EAAE,CAAC,OAAO,CAAC;IAC7D,MAAM,CAAC,WAAW,CAAC,CAAC;IACpB,OAAO,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AACrC,CAAC;AAED,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,uBAAuB,GAAG,IAAI,2BAA2B,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG,EAAE,0BAA0B,EAAE,CAAC;QAC/C,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,mBAAmB,CAC5D,uBAAuB,EACvB,OAAO,CACP,CAAC;QAEF,MAAM,qBAAqB,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9D,qBAAqB,CAAC,OAAO,GAAG,OAAO,CAAC;QACxC,uBAAuB,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG;YACrB,eAAe,EAAE,qBAAqB,CAAC,qBAAqB,EAAE;YAC9D,aAAa,EAAE,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC;SACzD,CAAC;QACF,MAAM,iBAAiB,GAAG,IAAI,YAAY,CACzC,qBAAqB,EACrB,eAAe,EACf,mBAAmB,CAAC,UAAU,CAC9B,CAAC;QAEF,MAAM,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE5C,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,uBAAuB,GAAG,IAAI,2BAA2B,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG,EAAE,0BAA0B,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC;QACjF,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,mBAAmB,CAC5D,uBAAuB,EACvB,OAAO,CACP,CAAC;QAEF,MAAM,qBAAqB,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9D,qBAAqB,CAAC,OAAO,GAAG,OAAO,CAAC;QACxC,uBAAuB,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG;YACrB,eAAe,EAAE,qBAAqB,CAAC,qBAAqB,EAAE;YAC9D,aAAa,EAAE,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC;SACzD,CAAC;QACF,MAAM,iBAAiB,GAAG,IAAI,YAAY,CACzC,qBAAqB,EACrB,eAAe,EACf,mBAAmB,CAAC,UAAU,CAC9B,CAAC;QAEF,MAAM,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE5C,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACtC,MAAM,uBAAuB,GAAG,IAAI,2BAA2B,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG;YACf,0BAA0B,EAAE,IAAI;YAChC,gCAAgC,EAAE,IAAI;YACtC,0BAA0B;SAC1B,CAAC;QACF,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,mBAAmB,CAC5D,uBAAuB,EACvB,OAAO,CACP,CAAC;QAEF,MAAM,qBAAqB,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9D,qBAAqB,CAAC,OAAO,GAAG,OAAO,CAAC;QACxC,uBAAuB,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG;YACrB,eAAe,EAAE,qBAAqB,CAAC,qBAAqB,EAAE;YAC9D,aAAa,EAAE,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC;SACzD,CAAC;QACF,MAAM,iBAAiB,GAAG,IAAI,YAAY,CACzC,qBAAqB,EACrB,eAAe,EACf,mBAAmB,CAAC,UAAU,CAC9B,CAAC;QAEF,MAAM,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE5C,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;QAE3E,MAAM,iBAAiB,CAAC,MAAM,CAAC;QAC/B,qBAAqB,CAAC,YAAY,CAAC,kBAAkB,GAAG,iBAAiB,CAAC,aAAa,EAAE,CAAC;QAE1F,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,uBAAuB,GAAG,IAAI,2BAA2B,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG;YACf,gCAAgC,EAAE,IAAI;YACtC,0BAA0B;SAC1B,CAAC;QACF,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,mBAAmB,CAC5D,uBAAuB,EACvB,OAAO,CACP,CAAC;QAEF,MAAM,qBAAqB,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9D,qBAAqB,CAAC,OAAO,GAAG,OAAO,CAAC;QACxC,uBAAuB,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG;YACrB,eAAe,EAAE,qBAAqB,CAAC,qBAAqB,EAAE;YAC9D,aAAa,EAAE,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC;SACzD,CAAC;QACF,MAAM,iBAAiB,GAAG,IAAI,YAAY,CACzC,qBAAqB,EACrB,eAAe,EACf,mBAAmB,CAAC,UAAU,CAC9B,CAAC;QAEF,MAAM,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE5C,qBAAqB,CAAC,YAAY,CAAC,kBAAkB;YACpD,uBAAuB,CAAC,cAAc,CAAC;QAExC,qBAAqB,CAAC,YAAY,CAAC,qBAAqB;YACvD,uBAAuB,CAAC,SAAS,EAAE,CAAC;QAErC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;QAE3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;YAC5B,eAAe,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;SACxC;QAED,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC;QAEjE,MAAM,iBAAiB,CAAC,MAAM,CAAC;QAE/B,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3E,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC;QACpE,uBAAuB,CAAC,kBAAkB,EAAE,CAAC;QAE7C,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,uBAAuB,GAAG,IAAI,2BAA2B,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG;YACf,gCAAgC,EAAE,IAAI;YACtC,0BAA0B;SAC1B,CAAC;QACF,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,mBAAmB,CAC5D,uBAAuB,EACvB,OAAO,CACP,CAAC;QAEF,MAAM,qBAAqB,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9D,qBAAqB,CAAC,OAAO,GAAG,OAAO,CAAC;QACxC,uBAAuB,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG;YACrB,eAAe,EAAE,qBAAqB,CAAC,qBAAqB,EAAE;YAC9D,aAAa,EAAE,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC;SACzD,CAAC;QACF,MAAM,iBAAiB,GAAG,IAAI,YAAY,CACzC,qBAAqB,EACrB,eAAe,EACf,mBAAmB,CAAC,UAAU,CAC9B,CAAC;QAEF,MAAM,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE5C,qBAAqB,CAAC,YAAY,CAAC,kBAAkB;YACpD,uBAAuB,CAAC,cAAc,CAAC;QAExC,qBAAqB,CAAC,YAAY,CAAC,qBAAqB;YACvD,uBAAuB,CAAC,SAAS,EAAE,CAAC;QAErC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;QAE3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;YAC5B,eAAe,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;SACzC;QACD,uBAAuB,CAAC,kBAAkB,EAAE,CAAC;QAE7C,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;QAE3E,MAAM,iBAAiB,CAAC,MAAM,CAAC;QAE/B,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,uBAAuB,GAAG,IAAI,2BAA2B,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG;YACf,gCAAgC,EAAE,IAAI;YACtC,0BAA0B;SAC1B,CAAC;QACF,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG,mBAAmB,CAC5D,uBAAuB,EACvB,OAAO,CACP,CAAC;QAEF,MAAM,qBAAqB,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9D,qBAAqB,CAAC,OAAO,GAAG,OAAO,CAAC;QACxC,uBAAuB,CAAC,sBAAsB,CAAC,qBAAqB,CAAC,CAAC;QACtE,MAAM,aAAa,GAAG;YACrB,eAAe,EAAE,qBAAqB,CAAC,qBAAqB,EAAE;YAC9D,aAAa,EAAE,WAAW,CAAC,iBAAiB,CAAC,WAAW,CAAC;SACzD,CAAC;QACF,MAAM,iBAAiB,GAAG,IAAI,YAAY,CACzC,qBAAqB,EACrB,eAAe,EACf,mBAAmB,CAAC,UAAU,CAC9B,CAAC;QAEF,MAAM,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE5C,qBAAqB,CAAC,YAAY,CAAC,kBAAkB;YACpD,uBAAuB,CAAC,cAAc,CAAC;QAExC,qBAAqB,CAAC,YAAY,CAAC,qBAAqB;YACvD,uBAAuB,CAAC,SAAS,EAAE,CAAC;QAErC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;QAE3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;YAC5B,eAAe,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;SACzC;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;YAC5B,eAAe,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;SACxC;QACD,uBAAuB,CAAC,kBAAkB,EAAE,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;QAE3E,MAAM,iBAAiB,CAAC,MAAM,CAAC;QAE/B,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;QAE3E,uBAAuB,CAAC,kBAAkB,EAAE,CAAC;QAE7C,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"assert\";\nimport {\n\tMockFluidDataStoreRuntime,\n\tMockContainerRuntimeFactory,\n\tMockStorage,\n} from \"@fluidframework/test-runtime-utils\";\nimport { ReferenceType } from \"@fluidframework/merge-tree\";\nimport { IChannelServices } from \"@fluidframework/datastore-definitions\";\nimport { ISummaryTree } from \"@fluidframework/protocol-definitions\";\nimport { SharedStringFactory, SharedString } from \"../index.js\";\n\nfunction applyOperations(\n\tsharedString: SharedString,\n\tcontent = sharedString.getLength().toString(),\n) {\n\tconst lenMod = sharedString.getLength() % 4;\n\tswitch (lenMod) {\n\t\tcase 0:\n\t\t\tsharedString.insertText(0, content);\n\t\t\tbreak;\n\n\t\tcase 1: {\n\t\t\tconst pos = Math.floor(sharedString.getLength() / lenMod);\n\t\t\tsharedString.insertMarker(pos, ReferenceType.Simple);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 2: {\n\t\t\tsharedString.insertText(sharedString.getLength(), content);\n\t\t\tconst pos = Math.floor(sharedString.getLength() / lenMod);\n\t\t\tsharedString.removeText(pos, pos + 1);\n\t\t\t// fall through to insert after remove\n\t\t}\n\t\tdefault:\n\t\t\tsharedString.insertText(sharedString.getLength(), content);\n\t}\n}\n\nconst mergeTreeSnapshotChunkSize = 5;\n\nfunction generateSummaryTree(\n\tcontainerRuntimeFactory: MockContainerRuntimeFactory,\n\toptions: any = {},\n): [SharedString, ISummaryTree] {\n\tconst dataStoreRuntime1 = new MockFluidDataStoreRuntime();\n\tdataStoreRuntime1.options = options;\n\t// Connect the first SharedString.\n\tconst containerRuntime1 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime1);\n\tconst services1: IChannelServices = {\n\t\tdeltaConnection: dataStoreRuntime1.createDeltaConnection(),\n\t\tobjectStorage: new MockStorage(),\n\t};\n\tconst sharedString = new SharedString(\n\t\tdataStoreRuntime1,\n\t\t\"shared-string\",\n\t\tSharedStringFactory.Attributes,\n\t);\n\tsharedString.initializeLocal();\n\tsharedString.connect(services1);\n\n\t// Create and connect a second SharedString.\n\tconst dataStoreRuntime2 = new MockFluidDataStoreRuntime();\n\tdataStoreRuntime2.options = options;\n\tconst containerRuntime2 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime2);\n\tconst sharedString2 = new SharedString(\n\t\tdataStoreRuntime2,\n\t\t\"shared-string\",\n\t\tSharedStringFactory.Attributes,\n\t);\n\tconst services2: IChannelServices = {\n\t\tdeltaConnection: dataStoreRuntime2.createDeltaConnection(),\n\t\tobjectStorage: new MockStorage(),\n\t};\n\tsharedString2.initializeLocal();\n\tsharedString2.connect(services2);\n\n\twhile (sharedString.getLength() < mergeTreeSnapshotChunkSize * 3) {\n\t\tapplyOperations(sharedString);\n\t\tcontainerRuntimeFactory.processAllMessages();\n\t}\n\tassert.equal(sharedString2.getText(), sharedString.getText());\n\tconst summaryTree = sharedString2.getAttachSummary().summary;\n\tassert(summaryTree);\n\treturn [sharedString2, summaryTree];\n}\n\ndescribe(\"SharedString Partial Load\", () => {\n\tit(\"Validate Full Load\", async () => {\n\t\tconst containerRuntimeFactory = new MockContainerRuntimeFactory();\n\t\tconst options = { mergeTreeSnapshotChunkSize };\n\t\tconst [remoteSharedString, summaryTree] = generateSummaryTree(\n\t\t\tcontainerRuntimeFactory,\n\t\t\toptions,\n\t\t);\n\n\t\tconst localDataStoreRuntime = new MockFluidDataStoreRuntime();\n\t\tlocalDataStoreRuntime.options = options;\n\t\tcontainerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);\n\t\tconst localServices = {\n\t\t\tdeltaConnection: localDataStoreRuntime.createDeltaConnection(),\n\t\t\tobjectStorage: MockStorage.createFromSummary(summaryTree),\n\t\t};\n\t\tconst localSharedString = new SharedString(\n\t\t\tlocalDataStoreRuntime,\n\t\t\t\"shared-string\",\n\t\t\tSharedStringFactory.Attributes,\n\t\t);\n\n\t\tawait localSharedString.load(localServices);\n\n\t\tassert.equal(localSharedString.getText(), remoteSharedString.getText());\n\t});\n\n\tit(\"Validate New Format Load\", async () => {\n\t\tconst containerRuntimeFactory = new MockContainerRuntimeFactory();\n\t\tconst options = { newMergeTreeSnapshotFormat: true, mergeTreeSnapshotChunkSize };\n\t\tconst [remoteSharedString, summaryTree] = generateSummaryTree(\n\t\t\tcontainerRuntimeFactory,\n\t\t\toptions,\n\t\t);\n\n\t\tconst localDataStoreRuntime = new MockFluidDataStoreRuntime();\n\t\tlocalDataStoreRuntime.options = options;\n\t\tcontainerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);\n\t\tconst localServices = {\n\t\t\tdeltaConnection: localDataStoreRuntime.createDeltaConnection(),\n\t\t\tobjectStorage: MockStorage.createFromSummary(summaryTree),\n\t\t};\n\t\tconst localSharedString = new SharedString(\n\t\t\tlocalDataStoreRuntime,\n\t\t\t\"shared-string\",\n\t\t\tSharedStringFactory.Attributes,\n\t\t);\n\n\t\tawait localSharedString.load(localServices);\n\n\t\tassert.equal(localSharedString.getText(), remoteSharedString.getText());\n\t});\n\n\tit(\"Validate Partial load\", async () => {\n\t\tconst containerRuntimeFactory = new MockContainerRuntimeFactory();\n\t\tconst options = {\n\t\t\tnewMergeTreeSnapshotFormat: true,\n\t\t\tsequenceInitializeFromHeaderOnly: true,\n\t\t\tmergeTreeSnapshotChunkSize,\n\t\t};\n\t\tconst [remoteSharedString, summaryTree] = generateSummaryTree(\n\t\t\tcontainerRuntimeFactory,\n\t\t\toptions,\n\t\t);\n\n\t\tconst localDataStoreRuntime = new MockFluidDataStoreRuntime();\n\t\tlocalDataStoreRuntime.options = options;\n\t\tcontainerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);\n\t\tconst localServices = {\n\t\t\tdeltaConnection: localDataStoreRuntime.createDeltaConnection(),\n\t\t\tobjectStorage: MockStorage.createFromSummary(summaryTree),\n\t\t};\n\t\tconst localSharedString = new SharedString(\n\t\t\tlocalDataStoreRuntime,\n\t\t\t\"shared-string\",\n\t\t\tSharedStringFactory.Attributes,\n\t\t);\n\n\t\tawait localSharedString.load(localServices);\n\n\t\tassert.notEqual(localSharedString.getText(), remoteSharedString.getText());\n\n\t\tawait localSharedString.loaded;\n\t\tlocalDataStoreRuntime.deltaManager.lastSequenceNumber = localSharedString.getCurrentSeq();\n\n\t\tassert.equal(localSharedString.getText(), remoteSharedString.getText());\n\t});\n\n\tit(\"Validate Partial load with local ops\", async () => {\n\t\tconst containerRuntimeFactory = new MockContainerRuntimeFactory();\n\t\tconst options = {\n\t\t\tsequenceInitializeFromHeaderOnly: true,\n\t\t\tmergeTreeSnapshotChunkSize,\n\t\t};\n\t\tconst [remoteSharedString, summaryTree] = generateSummaryTree(\n\t\t\tcontainerRuntimeFactory,\n\t\t\toptions,\n\t\t);\n\n\t\tconst localDataStoreRuntime = new MockFluidDataStoreRuntime();\n\t\tlocalDataStoreRuntime.options = options;\n\t\tcontainerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);\n\t\tconst localServices = {\n\t\t\tdeltaConnection: localDataStoreRuntime.createDeltaConnection(),\n\t\t\tobjectStorage: MockStorage.createFromSummary(summaryTree),\n\t\t};\n\t\tconst localSharedString = new SharedString(\n\t\t\tlocalDataStoreRuntime,\n\t\t\t\"shared-string\",\n\t\t\tSharedStringFactory.Attributes,\n\t\t);\n\n\t\tawait localSharedString.load(localServices);\n\n\t\tlocalDataStoreRuntime.deltaManager.lastSequenceNumber =\n\t\t\tcontainerRuntimeFactory.sequenceNumber;\n\n\t\tlocalDataStoreRuntime.deltaManager.minimumSequenceNumber =\n\t\t\tcontainerRuntimeFactory.getMinSeq();\n\n\t\tassert.notEqual(localSharedString.getText(), remoteSharedString.getText());\n\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tapplyOperations(localSharedString, \"L\");\n\t\t}\n\n\t\tassert.equal(containerRuntimeFactory.outstandingMessageCount, 0);\n\n\t\tawait localSharedString.loaded;\n\n\t\tassert.notEqual(localSharedString.getText(), remoteSharedString.getText());\n\t\tassert.notEqual(containerRuntimeFactory.outstandingMessageCount, 0);\n\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\tassert.equal(localSharedString.getText(), remoteSharedString.getText());\n\t});\n\n\tit(\"Validate Partial load with remote ops\", async () => {\n\t\tconst containerRuntimeFactory = new MockContainerRuntimeFactory();\n\t\tconst options = {\n\t\t\tsequenceInitializeFromHeaderOnly: true,\n\t\t\tmergeTreeSnapshotChunkSize,\n\t\t};\n\t\tconst [remoteSharedString, summaryTree] = generateSummaryTree(\n\t\t\tcontainerRuntimeFactory,\n\t\t\toptions,\n\t\t);\n\n\t\tconst localDataStoreRuntime = new MockFluidDataStoreRuntime();\n\t\tlocalDataStoreRuntime.options = options;\n\t\tcontainerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);\n\t\tconst localServices = {\n\t\t\tdeltaConnection: localDataStoreRuntime.createDeltaConnection(),\n\t\t\tobjectStorage: MockStorage.createFromSummary(summaryTree),\n\t\t};\n\t\tconst localSharedString = new SharedString(\n\t\t\tlocalDataStoreRuntime,\n\t\t\t\"shared-string\",\n\t\t\tSharedStringFactory.Attributes,\n\t\t);\n\n\t\tawait localSharedString.load(localServices);\n\n\t\tlocalDataStoreRuntime.deltaManager.lastSequenceNumber =\n\t\t\tcontainerRuntimeFactory.sequenceNumber;\n\n\t\tlocalDataStoreRuntime.deltaManager.minimumSequenceNumber =\n\t\t\tcontainerRuntimeFactory.getMinSeq();\n\n\t\tassert.notEqual(localSharedString.getText(), remoteSharedString.getText());\n\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tapplyOperations(remoteSharedString, \"R\");\n\t\t}\n\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\tassert.notEqual(localSharedString.getText(), remoteSharedString.getText());\n\n\t\tawait localSharedString.loaded;\n\n\t\tassert.equal(localSharedString.getText(), remoteSharedString.getText());\n\t});\n\n\tit(\"Validate Partial load with local and remote ops\", async () => {\n\t\tconst containerRuntimeFactory = new MockContainerRuntimeFactory();\n\t\tconst options = {\n\t\t\tsequenceInitializeFromHeaderOnly: true,\n\t\t\tmergeTreeSnapshotChunkSize,\n\t\t};\n\t\tconst [remoteSharedString, summaryTree] = generateSummaryTree(\n\t\t\tcontainerRuntimeFactory,\n\t\t\toptions,\n\t\t);\n\n\t\tconst localDataStoreRuntime = new MockFluidDataStoreRuntime();\n\t\tlocalDataStoreRuntime.options = options;\n\t\tcontainerRuntimeFactory.createContainerRuntime(localDataStoreRuntime);\n\t\tconst localServices = {\n\t\t\tdeltaConnection: localDataStoreRuntime.createDeltaConnection(),\n\t\t\tobjectStorage: MockStorage.createFromSummary(summaryTree),\n\t\t};\n\t\tconst localSharedString = new SharedString(\n\t\t\tlocalDataStoreRuntime,\n\t\t\t\"shared-string\",\n\t\t\tSharedStringFactory.Attributes,\n\t\t);\n\n\t\tawait localSharedString.load(localServices);\n\n\t\tlocalDataStoreRuntime.deltaManager.lastSequenceNumber =\n\t\t\tcontainerRuntimeFactory.sequenceNumber;\n\n\t\tlocalDataStoreRuntime.deltaManager.minimumSequenceNumber =\n\t\t\tcontainerRuntimeFactory.getMinSeq();\n\n\t\tassert.notEqual(localSharedString.getText(), remoteSharedString.getText());\n\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tapplyOperations(remoteSharedString, \"R\");\n\t\t}\n\t\tfor (let i = 0; i < 10; i++) {\n\t\t\tapplyOperations(localSharedString, \"L\");\n\t\t}\n\t\tcontainerRuntimeFactory.processAllMessages();\n\t\tassert.notEqual(localSharedString.getText(), remoteSharedString.getText());\n\n\t\tawait localSharedString.loaded;\n\n\t\tassert.notEqual(localSharedString.getText(), remoteSharedString.getText());\n\n\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\tassert.equal(localSharedString.getText(), remoteSharedString.getText());\n\t});\n});\n"]}
@@ -1,81 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { strict as assert } from "assert";
6
- import { MockFluidDataStoreRuntime, MockContainerRuntimeFactory, MockStorage, } from "@fluidframework/test-runtime-utils";
7
- import { FlushMode } from "@fluidframework/runtime-definitions";
8
- import { AttachState } from "@fluidframework/container-definitions";
9
- import { SharedString } from "../sharedString.js";
10
- import { SharedStringFactory } from "../sequenceFactory.js";
11
- [
12
- {
13
- options: {
14
- flushMode: FlushMode.Immediate,
15
- },
16
- name: "FlushMode immediate",
17
- },
18
- {
19
- options: {
20
- flushMode: FlushMode.TurnBased,
21
- enableGroupedBatching: true,
22
- },
23
- name: "FlushMode TurnBased with grouped batching",
24
- },
25
- ].forEach((testConfig) => {
26
- describe(`Rebasing - ${testConfig.name}`, () => {
27
- let containerRuntimeFactory;
28
- let containerRuntime1;
29
- let containerRuntime2;
30
- let sharedString1;
31
- let sharedString2;
32
- const createSharedString = async (id, factory) => {
33
- const dataStoreRuntime = new MockFluidDataStoreRuntime();
34
- dataStoreRuntime.setAttachState(AttachState.Attached);
35
- const containerRuntime = factory.createContainerRuntime(dataStoreRuntime);
36
- const services = {
37
- deltaConnection: dataStoreRuntime.createDeltaConnection(),
38
- objectStorage: new MockStorage(),
39
- };
40
- const sharedString = new SharedString(dataStoreRuntime, id, SharedStringFactory.Attributes);
41
- sharedString.initializeLocal();
42
- sharedString.connect(services);
43
- return [sharedString, containerRuntime];
44
- };
45
- beforeEach(async () => {
46
- containerRuntimeFactory = new MockContainerRuntimeFactory(testConfig.options);
47
- [sharedString1, containerRuntime1] = await createSharedString("shared-string-1", containerRuntimeFactory);
48
- [sharedString2, containerRuntime2] = await createSharedString("shared-string-2", containerRuntimeFactory);
49
- });
50
- it("Rebasing ops maintains eventual consistency", async () => {
51
- sharedString1.insertText(0, "ad");
52
- sharedString1.insertText(1, "c");
53
- containerRuntime1.flush();
54
- containerRuntime2.flush();
55
- containerRuntimeFactory.processAllMessages();
56
- sharedString2.on("sequenceDelta", (sequenceDeltaEvent) => {
57
- if (sequenceDeltaEvent.opArgs.op.seg === "b") {
58
- sharedString2.insertText(3, "u");
59
- }
60
- });
61
- sharedString1.insertText(1, "b");
62
- sharedString2.insertText(0, "y");
63
- sharedString2.insertText(1, "w");
64
- containerRuntime1.rebase();
65
- containerRuntime1.flush();
66
- containerRuntimeFactory.processOneMessage();
67
- sharedString2.insertText(2, "v");
68
- containerRuntime2.rebase();
69
- containerRuntime1.flush();
70
- containerRuntime2.flush();
71
- containerRuntimeFactory.processAllMessages();
72
- sharedString2.insertText(0, "z");
73
- containerRuntime1.flush();
74
- containerRuntime2.flush();
75
- containerRuntimeFactory.processAllMessages();
76
- assert.strictEqual(sharedString1.getText(), "zywvaubcd");
77
- assert.strictEqual(sharedString1.getText(), sharedString2.getText(), "SharedString eventual consistency broken");
78
- });
79
- });
80
- });
81
- //# sourceMappingURL=rebasing.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rebasing.spec.js","sourceRoot":"","sources":["../../src/test/rebasing.spec.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 { strict as assert } from \"assert\";\nimport {\n\tMockFluidDataStoreRuntime,\n\tMockContainerRuntimeFactory,\n\tMockContainerRuntime,\n\tMockStorage,\n} from \"@fluidframework/test-runtime-utils\";\nimport { IMergeTreeInsertMsg } from \"@fluidframework/merge-tree\";\nimport { FlushMode } from \"@fluidframework/runtime-definitions\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { SharedString } from \"../sharedString.js\";\nimport { SharedStringFactory } from \"../sequenceFactory.js\";\n\n[\n\t{\n\t\toptions: {\n\t\t\tflushMode: FlushMode.Immediate,\n\t\t},\n\t\tname: \"FlushMode immediate\",\n\t},\n\t{\n\t\toptions: {\n\t\t\tflushMode: FlushMode.TurnBased,\n\t\t\tenableGroupedBatching: true,\n\t\t},\n\t\tname: \"FlushMode TurnBased with grouped batching\",\n\t},\n].forEach((testConfig) => {\n\tdescribe(`Rebasing - ${testConfig.name}`, () => {\n\t\tlet containerRuntimeFactory: MockContainerRuntimeFactory;\n\t\tlet containerRuntime1: MockContainerRuntime;\n\t\tlet containerRuntime2: MockContainerRuntime;\n\t\tlet sharedString1: SharedString;\n\t\tlet sharedString2: SharedString;\n\n\t\tconst createSharedString = async (\n\t\t\tid: string,\n\t\t\tfactory: MockContainerRuntimeFactory,\n\t\t): Promise<[SharedString, MockContainerRuntime]> => {\n\t\t\tconst dataStoreRuntime = new MockFluidDataStoreRuntime();\n\t\t\tdataStoreRuntime.setAttachState(AttachState.Attached);\n\t\t\tconst containerRuntime = factory.createContainerRuntime(dataStoreRuntime);\n\t\t\tconst services = {\n\t\t\t\tdeltaConnection: dataStoreRuntime.createDeltaConnection(),\n\t\t\t\tobjectStorage: new MockStorage(),\n\t\t\t};\n\t\t\tconst sharedString = new SharedString(\n\t\t\t\tdataStoreRuntime,\n\t\t\t\tid,\n\t\t\t\tSharedStringFactory.Attributes,\n\t\t\t);\n\t\t\tsharedString.initializeLocal();\n\t\t\tsharedString.connect(services);\n\t\t\treturn [sharedString, containerRuntime];\n\t\t};\n\n\t\tbeforeEach(async () => {\n\t\t\tcontainerRuntimeFactory = new MockContainerRuntimeFactory(testConfig.options);\n\t\t\t[sharedString1, containerRuntime1] = await createSharedString(\n\t\t\t\t\"shared-string-1\",\n\t\t\t\tcontainerRuntimeFactory,\n\t\t\t);\n\t\t\t[sharedString2, containerRuntime2] = await createSharedString(\n\t\t\t\t\"shared-string-2\",\n\t\t\t\tcontainerRuntimeFactory,\n\t\t\t);\n\t\t});\n\n\t\tit(\"Rebasing ops maintains eventual consistency\", async () => {\n\t\t\tsharedString1.insertText(0, \"ad\");\n\t\t\tsharedString1.insertText(1, \"c\");\n\t\t\tcontainerRuntime1.flush();\n\t\t\tcontainerRuntime2.flush();\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tsharedString2.on(\"sequenceDelta\", (sequenceDeltaEvent) => {\n\t\t\t\tif ((sequenceDeltaEvent.opArgs.op as IMergeTreeInsertMsg).seg === \"b\") {\n\t\t\t\t\tsharedString2.insertText(3, \"u\");\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tsharedString1.insertText(1, \"b\");\n\t\t\tsharedString2.insertText(0, \"y\");\n\t\t\tsharedString2.insertText(1, \"w\");\n\t\t\tcontainerRuntime1.rebase();\n\t\t\tcontainerRuntime1.flush();\n\t\t\tcontainerRuntimeFactory.processOneMessage();\n\t\t\tsharedString2.insertText(2, \"v\");\n\n\t\t\tcontainerRuntime2.rebase();\n\t\t\tcontainerRuntime1.flush();\n\t\t\tcontainerRuntime2.flush();\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tsharedString2.insertText(0, \"z\");\n\t\t\tcontainerRuntime1.flush();\n\t\t\tcontainerRuntime2.flush();\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tassert.strictEqual(sharedString1.getText(), \"zywvaubcd\");\n\t\t\tassert.strictEqual(\n\t\t\t\tsharedString1.getText(),\n\t\t\t\tsharedString2.getText(),\n\t\t\t\t\"SharedString eventual consistency broken\",\n\t\t\t);\n\t\t});\n\t});\n});\n"]}
@@ -1,174 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { strict as assert } from "assert";
6
- import { LocalReferenceCollection, MergeTreeDeltaType, ReferenceType, } from "@fluidframework/merge-tree";
7
- import { MockFluidDataStoreRuntime, MockContainerRuntimeFactory, MockStorage, } from "@fluidframework/test-runtime-utils";
8
- import { MockLogger } from "@fluidframework/telemetry-utils";
9
- import { AttachState } from "@fluidframework/container-definitions";
10
- import { SharedString } from "../sharedString.js";
11
- import { resetReentrancyLogCounter } from "../sequence.js";
12
- describe("SharedString op-reentrancy", () => {
13
- /**
14
- * This is an example scenario where reentrancy of submission of local ops was problematic which we saw in production.
15
- *
16
- * Reentrant local ops were a problem before #16815 as most SharedString local application methods were set up along
17
- * the following lines:
18
- * ```ts
19
- * const op = this.client.insert(start, content);
20
- * this.submitLocalMessage(op);
21
- * ```
22
- *
23
- * However, `this.client.insert` triggers SharedString's delta event. Thus, if the application uses that event to submit
24
- * further ops, from merge-tree's perspective they would have occurred *after* the first op, but the call to submit the op
25
- * to the container runtime would happen *before* the call to submit the outermost op.
26
- *
27
- * Symptoms included various merge-tree asserts that the pending segments queue was inconsistent on the client which
28
- * triggered a reentrant op (ex: 0x046) and doc corruption from the perspective of other clients.
29
- *
30
- * #16815 fixed this by moving op submission to before raising the `sequenceDelta` event.
31
- */
32
- for (const sharedStringPreventReentrancy of [undefined, true]) {
33
- describe(`with preventSharedStringReentrancy: ${sharedStringPreventReentrancy}`, () => {
34
- it("throws on local re-entrancy", () => {
35
- const factory = SharedString.getFactory();
36
- const dataStoreRuntime1 = new MockFluidDataStoreRuntime({
37
- attachState: AttachState.Detached,
38
- });
39
- dataStoreRuntime1.options = { sharedStringPreventReentrancy };
40
- const sharedString = factory.create(dataStoreRuntime1, "A");
41
- sharedString.insertText(0, "abcX");
42
- sharedString.on("sequenceDelta", ({ deltaOperation, isLocal }, target) => {
43
- if (deltaOperation === MergeTreeDeltaType.INSERT && isLocal) {
44
- target.removeRange(3, 4);
45
- }
46
- });
47
- assert.throws(() => sharedString.insertText(4, "e"), "Reentrancy detected");
48
- });
49
- });
50
- }
51
- describe("with sharedStringPreventReentrancy: false", () => {
52
- let sharedString;
53
- let sharedString2;
54
- let containerRuntimeFactory;
55
- let logger;
56
- beforeEach(() => {
57
- resetReentrancyLogCounter();
58
- containerRuntimeFactory = new MockContainerRuntimeFactory();
59
- const factory = SharedString.getFactory();
60
- logger = new MockLogger();
61
- const dataStoreRuntime1 = new MockFluidDataStoreRuntime({
62
- logger: logger.toTelemetryLogger(),
63
- });
64
- dataStoreRuntime1.setAttachState(AttachState.Attached);
65
- dataStoreRuntime1.options = { sharedStringPreventReentrancy: false };
66
- sharedString = factory.create(dataStoreRuntime1, "A");
67
- const containerRuntime1 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime1);
68
- const services1 = {
69
- deltaConnection: dataStoreRuntime1.createDeltaConnection(),
70
- objectStorage: new MockStorage(),
71
- };
72
- sharedString.connect(services1);
73
- const dataStoreRuntime2 = new MockFluidDataStoreRuntime();
74
- dataStoreRuntime2.options = { sharedStringPreventReentrancy: false };
75
- dataStoreRuntime2.setAttachState(AttachState.Attached);
76
- const containerRuntime2 = containerRuntimeFactory.createContainerRuntime(dataStoreRuntime2);
77
- const services2 = {
78
- deltaConnection: dataStoreRuntime2.createDeltaConnection(),
79
- objectStorage: new MockStorage(),
80
- };
81
- sharedString2 = factory.create(dataStoreRuntime2, "B");
82
- sharedString2.connect(services2);
83
- });
84
- it("remains consistent on reentrancy", () => {
85
- sharedString.insertText(0, "abcX");
86
- containerRuntimeFactory.processAllMessages();
87
- sharedString.on("sequenceDelta", ({ deltaOperation, isLocal }, target) => {
88
- if (deltaOperation === MergeTreeDeltaType.INSERT && isLocal) {
89
- target.removeRange(3, 4);
90
- }
91
- });
92
- sharedString.insertText(4, "e");
93
- containerRuntimeFactory.processAllMessages();
94
- for (const str of [sharedString, sharedString2]) {
95
- assert.equal(str.getText(), "abce");
96
- }
97
- });
98
- it("is empty after deleting reference pos in reentrant callback", () => {
99
- sharedString.insertText(0, "abcX");
100
- const { segment } = sharedString.getContainingSegment(0);
101
- assert(segment);
102
- const localRefs = LocalReferenceCollection.setOrGet(segment);
103
- const localRef = localRefs.createLocalRef(0, ReferenceType.SlideOnRemove, undefined);
104
- assert.notEqual(localRef.getSegment(), undefined);
105
- containerRuntimeFactory.processAllMessages();
106
- sharedString.on("sequenceDelta", ({ deltaOperation, isLocal }, target) => {
107
- if (deltaOperation === MergeTreeDeltaType.INSERT && isLocal) {
108
- const { segment: segment2 } = target.getContainingSegment(0);
109
- assert(segment2);
110
- assert.equal(segment, segment2);
111
- assert(segment2.localRefs);
112
- segment2.localRefs.removeLocalRef(localRef);
113
- }
114
- });
115
- sharedString.insertText(4, "e");
116
- containerRuntimeFactory.processAllMessages();
117
- sharedString.walkSegments((seg) => {
118
- if (!seg.localRefs) {
119
- return false;
120
- }
121
- assert.equal(seg.localRefs.empty, true);
122
- assert.equal(seg.localRefs.has(localRef), false);
123
- return false;
124
- });
125
- assert.equal(localRef.getSegment(), undefined);
126
- assert.equal(localRef.getOffset(), 0);
127
- });
128
- it("is empty after deleting segment containing simple reference pos in reentrant callback", () => {
129
- sharedString.insertText(0, "abcX");
130
- const { segment } = sharedString.getContainingSegment(0);
131
- assert(segment);
132
- const localRefs = LocalReferenceCollection.setOrGet(segment);
133
- const localRef = localRefs.createLocalRef(0, ReferenceType.Simple, undefined);
134
- assert.notEqual(localRef.getSegment(), undefined);
135
- containerRuntimeFactory.processAllMessages();
136
- sharedString.on("sequenceDelta", ({ deltaOperation, isLocal }, target) => {
137
- if (deltaOperation === MergeTreeDeltaType.INSERT && isLocal) {
138
- target.removeRange(0, 4);
139
- }
140
- });
141
- sharedString.insertText(4, "e");
142
- containerRuntimeFactory.processAllMessages();
143
- sharedString.walkSegments((seg) => {
144
- if (!seg.localRefs) {
145
- return false;
146
- }
147
- assert.equal(seg.localRefs.empty, true);
148
- assert.equal(seg.localRefs.has(localRef), false);
149
- return false;
150
- });
151
- assert.equal(localRef.getSegment(), undefined);
152
- assert.equal(localRef.getOffset(), 0);
153
- });
154
- it("logs reentrant events a fixed number of times", () => {
155
- let numberRemainingReentrantInserts = 10;
156
- sharedString.on("sequenceDelta", ({ isLocal }, target) => {
157
- if (isLocal && numberRemainingReentrantInserts > 0) {
158
- numberRemainingReentrantInserts--;
159
- target.insertText(target.getLength(), "1");
160
- }
161
- });
162
- sharedString.insertText(0, "A");
163
- containerRuntimeFactory.processAllMessages();
164
- const eventName = "fluid:MockFluidDataStoreRuntime:LocalOpReentry";
165
- logger.assertMatchStrict([
166
- { eventName, depth: 1 },
167
- { eventName, depth: 2 },
168
- { eventName, depth: 3 },
169
- ]);
170
- logger.assertMatchNone([{ eventName, depth: 4 }]);
171
- });
172
- });
173
- });
174
- //# sourceMappingURL=reentrancy.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reentrancy.spec.js","sourceRoot":"","sources":["../../src/test/reentrancy.spec.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 { strict as assert } from \"assert\";\nimport {\n\tLocalReferenceCollection,\n\tMergeTreeDeltaType,\n\tReferenceType,\n} from \"@fluidframework/merge-tree\";\nimport {\n\tMockFluidDataStoreRuntime,\n\tMockContainerRuntimeFactory,\n\tMockStorage,\n} from \"@fluidframework/test-runtime-utils\";\nimport { MockLogger } from \"@fluidframework/telemetry-utils\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { SharedString } from \"../sharedString.js\";\nimport { resetReentrancyLogCounter } from \"../sequence.js\";\n\ndescribe(\"SharedString op-reentrancy\", () => {\n\t/**\n\t * This is an example scenario where reentrancy of submission of local ops was problematic which we saw in production.\n\t *\n\t * Reentrant local ops were a problem before #16815 as most SharedString local application methods were set up along\n\t * the following lines:\n\t * ```ts\n\t * const op = this.client.insert(start, content);\n\t * this.submitLocalMessage(op);\n\t * ```\n\t *\n\t * However, `this.client.insert` triggers SharedString's delta event. Thus, if the application uses that event to submit\n\t * further ops, from merge-tree's perspective they would have occurred *after* the first op, but the call to submit the op\n\t * to the container runtime would happen *before* the call to submit the outermost op.\n\t *\n\t * Symptoms included various merge-tree asserts that the pending segments queue was inconsistent on the client which\n\t * triggered a reentrant op (ex: 0x046) and doc corruption from the perspective of other clients.\n\t *\n\t * #16815 fixed this by moving op submission to before raising the `sequenceDelta` event.\n\t */\n\tfor (const sharedStringPreventReentrancy of [undefined, true]) {\n\t\tdescribe(`with preventSharedStringReentrancy: ${sharedStringPreventReentrancy}`, () => {\n\t\t\tit(\"throws on local re-entrancy\", () => {\n\t\t\t\tconst factory = SharedString.getFactory();\n\t\t\t\tconst dataStoreRuntime1 = new MockFluidDataStoreRuntime({\n\t\t\t\t\tattachState: AttachState.Detached,\n\t\t\t\t});\n\t\t\t\tdataStoreRuntime1.options = { sharedStringPreventReentrancy };\n\n\t\t\t\tconst sharedString = factory.create(dataStoreRuntime1, \"A\");\n\t\t\t\tsharedString.insertText(0, \"abcX\");\n\n\t\t\t\tsharedString.on(\"sequenceDelta\", ({ deltaOperation, isLocal }, target) => {\n\t\t\t\t\tif (deltaOperation === MergeTreeDeltaType.INSERT && isLocal) {\n\t\t\t\t\t\ttarget.removeRange(3, 4);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tassert.throws(() => sharedString.insertText(4, \"e\"), \"Reentrancy detected\");\n\t\t\t});\n\t\t});\n\t}\n\n\tdescribe(\"with sharedStringPreventReentrancy: false\", () => {\n\t\tlet sharedString: SharedString;\n\t\tlet sharedString2: SharedString;\n\t\tlet containerRuntimeFactory: MockContainerRuntimeFactory;\n\t\tlet logger: MockLogger;\n\t\tbeforeEach(() => {\n\t\t\tresetReentrancyLogCounter();\n\t\t\tcontainerRuntimeFactory = new MockContainerRuntimeFactory();\n\n\t\t\tconst factory = SharedString.getFactory();\n\t\t\tlogger = new MockLogger();\n\t\t\tconst dataStoreRuntime1 = new MockFluidDataStoreRuntime({\n\t\t\t\tlogger: logger.toTelemetryLogger(),\n\t\t\t});\n\t\t\tdataStoreRuntime1.setAttachState(AttachState.Attached);\n\t\t\tdataStoreRuntime1.options = { sharedStringPreventReentrancy: false };\n\t\t\tsharedString = factory.create(dataStoreRuntime1, \"A\");\n\n\t\t\tconst containerRuntime1 =\n\t\t\t\tcontainerRuntimeFactory.createContainerRuntime(dataStoreRuntime1);\n\t\t\tconst services1 = {\n\t\t\t\tdeltaConnection: dataStoreRuntime1.createDeltaConnection(),\n\t\t\t\tobjectStorage: new MockStorage(),\n\t\t\t};\n\t\t\tsharedString.connect(services1);\n\n\t\t\tconst dataStoreRuntime2 = new MockFluidDataStoreRuntime();\n\t\t\tdataStoreRuntime2.options = { sharedStringPreventReentrancy: false };\n\t\t\tdataStoreRuntime2.setAttachState(AttachState.Attached);\n\t\t\tconst containerRuntime2 =\n\t\t\t\tcontainerRuntimeFactory.createContainerRuntime(dataStoreRuntime2);\n\t\t\tconst services2 = {\n\t\t\t\tdeltaConnection: dataStoreRuntime2.createDeltaConnection(),\n\t\t\t\tobjectStorage: new MockStorage(),\n\t\t\t};\n\n\t\t\tsharedString2 = factory.create(dataStoreRuntime2, \"B\");\n\t\t\tsharedString2.connect(services2);\n\t\t});\n\n\t\tit(\"remains consistent on reentrancy\", () => {\n\t\t\tsharedString.insertText(0, \"abcX\");\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tsharedString.on(\"sequenceDelta\", ({ deltaOperation, isLocal }, target) => {\n\t\t\t\tif (deltaOperation === MergeTreeDeltaType.INSERT && isLocal) {\n\t\t\t\t\ttarget.removeRange(3, 4);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tsharedString.insertText(4, \"e\");\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tfor (const str of [sharedString, sharedString2]) {\n\t\t\t\tassert.equal(str.getText(), \"abce\");\n\t\t\t}\n\t\t});\n\n\t\tit(\"is empty after deleting reference pos in reentrant callback\", () => {\n\t\t\tsharedString.insertText(0, \"abcX\");\n\t\t\tconst { segment } = sharedString.getContainingSegment(0);\n\t\t\tassert(segment);\n\t\t\tconst localRefs = LocalReferenceCollection.setOrGet(segment);\n\t\t\tconst localRef = localRefs.createLocalRef(0, ReferenceType.SlideOnRemove, undefined);\n\n\t\t\tassert.notEqual(localRef.getSegment(), undefined);\n\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tsharedString.on(\"sequenceDelta\", ({ deltaOperation, isLocal }, target) => {\n\t\t\t\tif (deltaOperation === MergeTreeDeltaType.INSERT && isLocal) {\n\t\t\t\t\tconst { segment: segment2 } = target.getContainingSegment(0);\n\t\t\t\t\tassert(segment2);\n\t\t\t\t\tassert.equal(segment, segment2);\n\t\t\t\t\tassert(segment2.localRefs);\n\t\t\t\t\tsegment2.localRefs.removeLocalRef(localRef);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tsharedString.insertText(4, \"e\");\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tsharedString.walkSegments((seg) => {\n\t\t\t\tif (!seg.localRefs) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tassert.equal(seg.localRefs.empty, true);\n\t\t\t\tassert.equal(seg.localRefs.has(localRef), false);\n\t\t\t\treturn false;\n\t\t\t});\n\n\t\t\tassert.equal(localRef.getSegment(), undefined);\n\t\t\tassert.equal(localRef.getOffset(), 0);\n\t\t});\n\n\t\tit(\"is empty after deleting segment containing simple reference pos in reentrant callback\", () => {\n\t\t\tsharedString.insertText(0, \"abcX\");\n\t\t\tconst { segment } = sharedString.getContainingSegment(0);\n\t\t\tassert(segment);\n\t\t\tconst localRefs = LocalReferenceCollection.setOrGet(segment);\n\t\t\tconst localRef = localRefs.createLocalRef(0, ReferenceType.Simple, undefined);\n\n\t\t\tassert.notEqual(localRef.getSegment(), undefined);\n\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tsharedString.on(\"sequenceDelta\", ({ deltaOperation, isLocal }, target) => {\n\t\t\t\tif (deltaOperation === MergeTreeDeltaType.INSERT && isLocal) {\n\t\t\t\t\ttarget.removeRange(0, 4);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tsharedString.insertText(4, \"e\");\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tsharedString.walkSegments((seg) => {\n\t\t\t\tif (!seg.localRefs) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tassert.equal(seg.localRefs.empty, true);\n\t\t\t\tassert.equal(seg.localRefs.has(localRef), false);\n\t\t\t\treturn false;\n\t\t\t});\n\n\t\t\tassert.equal(localRef.getSegment(), undefined);\n\t\t\tassert.equal(localRef.getOffset(), 0);\n\t\t});\n\n\t\tit(\"logs reentrant events a fixed number of times\", () => {\n\t\t\tlet numberRemainingReentrantInserts = 10;\n\t\t\tsharedString.on(\"sequenceDelta\", ({ isLocal }, target) => {\n\t\t\t\tif (isLocal && numberRemainingReentrantInserts > 0) {\n\t\t\t\t\tnumberRemainingReentrantInserts--;\n\t\t\t\t\ttarget.insertText(target.getLength(), \"1\");\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tsharedString.insertText(0, \"A\");\n\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\t\t\tconst eventName = \"fluid:MockFluidDataStoreRuntime:LocalOpReentry\";\n\t\t\tlogger.assertMatchStrict([\n\t\t\t\t{ eventName, depth: 1 },\n\t\t\t\t{ eventName, depth: 2 },\n\t\t\t\t{ eventName, depth: 3 },\n\t\t\t]);\n\t\t\tlogger.assertMatchNone([{ eventName, depth: 4 }]);\n\t\t});\n\t});\n});\n"]}