@fluidframework/sequence 1.4.0-121020 → 2.0.0-dev-rc.1.0.0.224419

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 (349) hide show
  1. package/.eslintrc.js +9 -11
  2. package/.mocharc.js +12 -0
  3. package/CHANGELOG.md +449 -0
  4. package/README.md +364 -183
  5. package/api-extractor-lint.json +4 -0
  6. package/api-extractor.json +2 -2
  7. package/api-report/sequence.api.md +741 -0
  8. package/dist/{defaultMap.js → defaultMap.cjs} +29 -22
  9. package/dist/defaultMap.cjs.map +1 -0
  10. package/dist/defaultMap.d.ts +7 -6
  11. package/dist/defaultMap.d.ts.map +1 -1
  12. package/dist/defaultMapInterfaces.cjs +7 -0
  13. package/dist/defaultMapInterfaces.cjs.map +1 -0
  14. package/dist/defaultMapInterfaces.d.ts +44 -12
  15. package/dist/defaultMapInterfaces.d.ts.map +1 -1
  16. package/dist/index.cjs +60 -0
  17. package/dist/index.cjs.map +1 -0
  18. package/dist/index.d.ts +14 -12
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/intervalCollection.cjs +1159 -0
  21. package/dist/intervalCollection.cjs.map +1 -0
  22. package/dist/intervalCollection.d.ts +461 -162
  23. package/dist/intervalCollection.d.ts.map +1 -1
  24. package/dist/intervalIndex/endpointInRangeIndex.cjs +66 -0
  25. package/dist/intervalIndex/endpointInRangeIndex.cjs.map +1 -0
  26. package/dist/intervalIndex/endpointInRangeIndex.d.ts +34 -0
  27. package/dist/intervalIndex/endpointInRangeIndex.d.ts.map +1 -0
  28. package/dist/intervalIndex/endpointIndex.cjs +47 -0
  29. package/dist/intervalIndex/endpointIndex.cjs.map +1 -0
  30. package/dist/intervalIndex/endpointIndex.d.ts +38 -0
  31. package/dist/intervalIndex/endpointIndex.d.ts.map +1 -0
  32. package/dist/intervalIndex/idIntervalIndex.cjs +44 -0
  33. package/dist/intervalIndex/idIntervalIndex.cjs.map +1 -0
  34. package/dist/intervalIndex/idIntervalIndex.d.ts +18 -0
  35. package/dist/intervalIndex/idIntervalIndex.d.ts.map +1 -0
  36. package/dist/intervalIndex/index.cjs +24 -0
  37. package/dist/intervalIndex/index.cjs.map +1 -0
  38. package/dist/intervalIndex/index.d.ts +13 -0
  39. package/dist/intervalIndex/index.d.ts.map +1 -0
  40. package/dist/{defaultMapInterfaces.js → intervalIndex/intervalIndex.cjs} +1 -1
  41. package/dist/intervalIndex/intervalIndex.cjs.map +1 -0
  42. package/dist/intervalIndex/intervalIndex.d.ts +30 -0
  43. package/dist/intervalIndex/intervalIndex.d.ts.map +1 -0
  44. package/dist/intervalIndex/intervalIndexUtils.cjs +22 -0
  45. package/dist/intervalIndex/intervalIndexUtils.cjs.map +1 -0
  46. package/dist/intervalIndex/intervalIndexUtils.d.ts +17 -0
  47. package/dist/intervalIndex/intervalIndexUtils.d.ts.map +1 -0
  48. package/dist/intervalIndex/overlappingIntervalsIndex.cjs +116 -0
  49. package/dist/intervalIndex/overlappingIntervalsIndex.cjs.map +1 -0
  50. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts +44 -0
  51. package/dist/intervalIndex/overlappingIntervalsIndex.d.ts.map +1 -0
  52. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.cjs +41 -0
  53. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.cjs.map +1 -0
  54. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts +11 -0
  55. package/dist/intervalIndex/overlappingSequenceIntervalsIndex.d.ts.map +1 -0
  56. package/dist/intervalIndex/sequenceIntervalIndexes.cjs +7 -0
  57. package/dist/intervalIndex/sequenceIntervalIndexes.cjs.map +1 -0
  58. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts +35 -0
  59. package/dist/intervalIndex/sequenceIntervalIndexes.d.ts.map +1 -0
  60. package/dist/intervalIndex/startpointInRangeIndex.cjs +66 -0
  61. package/dist/intervalIndex/startpointInRangeIndex.cjs.map +1 -0
  62. package/dist/intervalIndex/startpointInRangeIndex.d.ts +34 -0
  63. package/dist/intervalIndex/startpointInRangeIndex.d.ts.map +1 -0
  64. package/dist/intervalTree.cjs +80 -0
  65. package/dist/intervalTree.cjs.map +1 -0
  66. package/dist/intervalTree.d.ts +24 -0
  67. package/dist/intervalTree.d.ts.map +1 -0
  68. package/dist/intervals/index.cjs +23 -0
  69. package/dist/intervals/index.cjs.map +1 -0
  70. package/dist/intervals/index.d.ts +8 -0
  71. package/dist/intervals/index.d.ts.map +1 -0
  72. package/dist/intervals/interval.cjs +181 -0
  73. package/dist/intervals/interval.cjs.map +1 -0
  74. package/dist/intervals/interval.d.ts +84 -0
  75. package/dist/intervals/interval.d.ts.map +1 -0
  76. package/dist/intervals/intervalUtils.cjs +83 -0
  77. package/dist/intervals/intervalUtils.cjs.map +1 -0
  78. package/dist/intervals/intervalUtils.d.ts +230 -0
  79. package/dist/intervals/intervalUtils.d.ts.map +1 -0
  80. package/dist/intervals/sequenceInterval.cjs +378 -0
  81. package/dist/intervals/sequenceInterval.cjs.map +1 -0
  82. package/dist/intervals/sequenceInterval.d.ts +137 -0
  83. package/dist/intervals/sequenceInterval.d.ts.map +1 -0
  84. package/dist/{localValues.js → localValues.cjs} +1 -1
  85. package/dist/localValues.cjs.map +1 -0
  86. package/dist/localValues.d.ts +2 -1
  87. package/dist/localValues.d.ts.map +1 -1
  88. package/dist/{packageVersion.js → packageVersion.cjs} +2 -2
  89. package/dist/packageVersion.cjs.map +1 -0
  90. package/dist/packageVersion.d.ts +1 -1
  91. package/dist/packageVersion.d.ts.map +1 -1
  92. package/dist/revertibles.cjs +425 -0
  93. package/dist/revertibles.cjs.map +1 -0
  94. package/dist/revertibles.d.ts +86 -0
  95. package/dist/revertibles.d.ts.map +1 -0
  96. package/dist/sequence-alpha.d.ts +1315 -0
  97. package/dist/sequence-beta.d.ts +244 -0
  98. package/dist/sequence-public.d.ts +244 -0
  99. package/dist/sequence-untrimmed.d.ts +1803 -0
  100. package/dist/{sequence.js → sequence.cjs} +226 -156
  101. package/dist/sequence.cjs.map +1 -0
  102. package/dist/sequence.d.ts +125 -48
  103. package/dist/sequence.d.ts.map +1 -1
  104. package/dist/{sequenceDeltaEvent.js → sequenceDeltaEvent.cjs} +18 -8
  105. package/dist/sequenceDeltaEvent.cjs.map +1 -0
  106. package/dist/sequenceDeltaEvent.d.ts +24 -7
  107. package/dist/sequenceDeltaEvent.d.ts.map +1 -1
  108. package/dist/sequenceFactory.cjs +55 -0
  109. package/dist/sequenceFactory.cjs.map +1 -0
  110. package/dist/sequenceFactory.d.ts +3 -89
  111. package/dist/sequenceFactory.d.ts.map +1 -1
  112. package/dist/{sharedIntervalCollection.js → sharedIntervalCollection.cjs} +17 -22
  113. package/dist/sharedIntervalCollection.cjs.map +1 -0
  114. package/dist/sharedIntervalCollection.d.ts +12 -12
  115. package/dist/sharedIntervalCollection.d.ts.map +1 -1
  116. package/dist/{sharedSequence.js → sharedSequence.cjs} +29 -22
  117. package/dist/sharedSequence.cjs.map +1 -0
  118. package/dist/sharedSequence.d.ts +14 -2
  119. package/dist/sharedSequence.d.ts.map +1 -1
  120. package/dist/sharedString.cjs +286 -0
  121. package/dist/sharedString.cjs.map +1 -0
  122. package/dist/sharedString.d.ts +58 -22
  123. package/dist/sharedString.d.ts.map +1 -1
  124. package/dist/tsdoc-metadata.json +11 -0
  125. package/lib/{defaultMap.d.ts → defaultMap.d.mts} +7 -6
  126. package/lib/defaultMap.d.mts.map +1 -0
  127. package/lib/{defaultMap.js → defaultMap.mjs} +28 -21
  128. package/lib/defaultMap.mjs.map +1 -0
  129. package/lib/{defaultMapInterfaces.d.ts → defaultMapInterfaces.d.mts} +44 -12
  130. package/lib/defaultMapInterfaces.d.mts.map +1 -0
  131. package/lib/defaultMapInterfaces.mjs +6 -0
  132. package/lib/defaultMapInterfaces.mjs.map +1 -0
  133. package/lib/index.d.mts +17 -0
  134. package/lib/index.d.mts.map +1 -0
  135. package/lib/index.mjs +16 -0
  136. package/lib/index.mjs.map +1 -0
  137. package/lib/intervalCollection.d.mts +569 -0
  138. package/lib/intervalCollection.d.mts.map +1 -0
  139. package/lib/intervalCollection.mjs +1144 -0
  140. package/lib/intervalCollection.mjs.map +1 -0
  141. package/lib/intervalIndex/endpointInRangeIndex.d.mts +34 -0
  142. package/lib/intervalIndex/endpointInRangeIndex.d.mts.map +1 -0
  143. package/lib/intervalIndex/endpointInRangeIndex.mjs +61 -0
  144. package/lib/intervalIndex/endpointInRangeIndex.mjs.map +1 -0
  145. package/lib/intervalIndex/endpointIndex.d.mts +38 -0
  146. package/lib/intervalIndex/endpointIndex.d.mts.map +1 -0
  147. package/lib/intervalIndex/endpointIndex.mjs +42 -0
  148. package/lib/intervalIndex/endpointIndex.mjs.map +1 -0
  149. package/lib/intervalIndex/idIntervalIndex.d.mts +18 -0
  150. package/lib/intervalIndex/idIntervalIndex.d.mts.map +1 -0
  151. package/lib/intervalIndex/idIntervalIndex.mjs +40 -0
  152. package/lib/intervalIndex/idIntervalIndex.mjs.map +1 -0
  153. package/lib/intervalIndex/index.d.mts +13 -0
  154. package/lib/intervalIndex/index.d.mts.map +1 -0
  155. package/lib/intervalIndex/index.mjs +11 -0
  156. package/lib/intervalIndex/index.mjs.map +1 -0
  157. package/lib/intervalIndex/intervalIndex.d.mts +30 -0
  158. package/lib/intervalIndex/intervalIndex.d.mts.map +1 -0
  159. package/lib/{defaultMapInterfaces.js → intervalIndex/intervalIndex.mjs} +1 -1
  160. package/lib/intervalIndex/intervalIndex.mjs.map +1 -0
  161. package/lib/intervalIndex/intervalIndexUtils.d.mts +17 -0
  162. package/lib/intervalIndex/intervalIndexUtils.d.mts.map +1 -0
  163. package/lib/intervalIndex/intervalIndexUtils.mjs +18 -0
  164. package/lib/intervalIndex/intervalIndexUtils.mjs.map +1 -0
  165. package/lib/intervalIndex/overlappingIntervalsIndex.d.mts +44 -0
  166. package/lib/intervalIndex/overlappingIntervalsIndex.d.mts.map +1 -0
  167. package/lib/intervalIndex/overlappingIntervalsIndex.mjs +111 -0
  168. package/lib/intervalIndex/overlappingIntervalsIndex.mjs.map +1 -0
  169. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.mts +11 -0
  170. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.d.mts.map +1 -0
  171. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.mjs +37 -0
  172. package/lib/intervalIndex/overlappingSequenceIntervalsIndex.mjs.map +1 -0
  173. package/lib/intervalIndex/sequenceIntervalIndexes.d.mts +35 -0
  174. package/lib/intervalIndex/sequenceIntervalIndexes.d.mts.map +1 -0
  175. package/lib/intervalIndex/sequenceIntervalIndexes.mjs +6 -0
  176. package/lib/intervalIndex/sequenceIntervalIndexes.mjs.map +1 -0
  177. package/lib/intervalIndex/startpointInRangeIndex.d.mts +34 -0
  178. package/lib/intervalIndex/startpointInRangeIndex.d.mts.map +1 -0
  179. package/lib/intervalIndex/startpointInRangeIndex.mjs +61 -0
  180. package/lib/intervalIndex/startpointInRangeIndex.mjs.map +1 -0
  181. package/lib/intervalTree.d.mts +24 -0
  182. package/lib/intervalTree.d.mts.map +1 -0
  183. package/lib/intervalTree.mjs +76 -0
  184. package/lib/intervalTree.mjs.map +1 -0
  185. package/lib/intervals/index.d.mts +8 -0
  186. package/lib/intervals/index.d.mts.map +1 -0
  187. package/lib/intervals/index.mjs +8 -0
  188. package/lib/intervals/index.mjs.map +1 -0
  189. package/lib/intervals/interval.d.mts +84 -0
  190. package/lib/intervals/interval.d.mts.map +1 -0
  191. package/lib/intervals/interval.mjs +176 -0
  192. package/lib/intervals/interval.mjs.map +1 -0
  193. package/lib/intervals/intervalUtils.d.mts +230 -0
  194. package/lib/intervals/intervalUtils.d.mts.map +1 -0
  195. package/lib/intervals/intervalUtils.mjs +77 -0
  196. package/lib/intervals/intervalUtils.mjs.map +1 -0
  197. package/lib/intervals/sequenceInterval.d.mts +137 -0
  198. package/lib/intervals/sequenceInterval.d.mts.map +1 -0
  199. package/lib/intervals/sequenceInterval.mjs +370 -0
  200. package/lib/intervals/sequenceInterval.mjs.map +1 -0
  201. package/lib/{localValues.d.ts → localValues.d.mts} +3 -2
  202. package/lib/localValues.d.mts.map +1 -0
  203. package/lib/{localValues.js → localValues.mjs} +2 -2
  204. package/lib/localValues.mjs.map +1 -0
  205. package/lib/{packageVersion.d.ts → packageVersion.d.mts} +1 -1
  206. package/lib/{packageVersion.d.ts.map → packageVersion.d.mts.map} +1 -1
  207. package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
  208. package/lib/packageVersion.mjs.map +1 -0
  209. package/lib/revertibles.d.mts +86 -0
  210. package/lib/revertibles.d.mts.map +1 -0
  211. package/lib/revertibles.mjs +416 -0
  212. package/lib/revertibles.mjs.map +1 -0
  213. package/lib/sequence-alpha.d.mts +1315 -0
  214. package/lib/sequence-beta.d.mts +244 -0
  215. package/lib/sequence-public.d.mts +244 -0
  216. package/lib/sequence-untrimmed.d.mts +1803 -0
  217. package/lib/{sequence.d.ts → sequence.d.mts} +127 -50
  218. package/lib/sequence.d.mts.map +1 -0
  219. package/lib/{sequence.js → sequence.mjs} +225 -152
  220. package/lib/sequence.mjs.map +1 -0
  221. package/lib/{sequenceDeltaEvent.d.ts → sequenceDeltaEvent.d.mts} +24 -7
  222. package/lib/sequenceDeltaEvent.d.mts.map +1 -0
  223. package/lib/{sequenceDeltaEvent.js → sequenceDeltaEvent.mjs} +20 -8
  224. package/lib/sequenceDeltaEvent.mjs.map +1 -0
  225. package/lib/sequenceFactory.d.mts +22 -0
  226. package/lib/sequenceFactory.d.mts.map +1 -0
  227. package/lib/sequenceFactory.mjs +51 -0
  228. package/lib/sequenceFactory.mjs.map +1 -0
  229. package/lib/{sharedIntervalCollection.d.ts → sharedIntervalCollection.d.mts} +12 -12
  230. package/lib/sharedIntervalCollection.d.mts.map +1 -0
  231. package/lib/{sharedIntervalCollection.js → sharedIntervalCollection.mjs} +16 -21
  232. package/lib/sharedIntervalCollection.mjs.map +1 -0
  233. package/lib/{sharedSequence.d.ts → sharedSequence.d.mts} +15 -3
  234. package/lib/sharedSequence.d.mts.map +1 -0
  235. package/lib/{sharedSequence.js → sharedSequence.mjs} +30 -23
  236. package/lib/sharedSequence.mjs.map +1 -0
  237. package/lib/{sharedString.d.ts → sharedString.d.mts} +60 -24
  238. package/lib/sharedString.d.mts.map +1 -0
  239. package/lib/sharedString.mjs +281 -0
  240. package/lib/sharedString.mjs.map +1 -0
  241. package/package.json +146 -75
  242. package/prettier.config.cjs +8 -0
  243. package/sequence.test-files.tar +0 -0
  244. package/src/defaultMap.ts +417 -403
  245. package/src/defaultMapInterfaces.ts +157 -117
  246. package/src/index.ts +86 -26
  247. package/src/intervalCollection.ts +2043 -1563
  248. package/src/intervalIndex/endpointInRangeIndex.ts +116 -0
  249. package/src/intervalIndex/endpointIndex.ts +91 -0
  250. package/src/intervalIndex/idIntervalIndex.ts +64 -0
  251. package/src/intervalIndex/index.ts +25 -0
  252. package/src/intervalIndex/intervalIndex.ts +32 -0
  253. package/src/intervalIndex/intervalIndexUtils.ts +27 -0
  254. package/src/intervalIndex/overlappingIntervalsIndex.ts +187 -0
  255. package/src/intervalIndex/overlappingSequenceIntervalsIndex.ts +80 -0
  256. package/src/intervalIndex/sequenceIntervalIndexes.ts +34 -0
  257. package/src/intervalIndex/startpointInRangeIndex.ts +114 -0
  258. package/src/intervalTree.ts +98 -0
  259. package/src/intervals/index.ts +25 -0
  260. package/src/intervals/interval.ts +238 -0
  261. package/src/intervals/intervalUtils.ts +288 -0
  262. package/src/intervals/sequenceInterval.ts +616 -0
  263. package/src/localValues.ts +68 -73
  264. package/src/packageVersion.ts +1 -1
  265. package/src/revertibles.ts +693 -0
  266. package/src/sequence.ts +845 -690
  267. package/src/sequenceDeltaEvent.ts +164 -131
  268. package/src/sequenceFactory.ts +58 -214
  269. package/src/sharedIntervalCollection.ts +161 -152
  270. package/src/sharedSequence.ts +181 -167
  271. package/src/sharedString.ts +390 -234
  272. package/tsc-multi.test.json +10 -0
  273. package/tsconfig.json +11 -13
  274. package/.editorconfig +0 -7
  275. package/.vscode/launch.json +0 -15
  276. package/dist/defaultMap.js.map +0 -1
  277. package/dist/defaultMapInterfaces.js.map +0 -1
  278. package/dist/index.js +0 -44
  279. package/dist/index.js.map +0 -1
  280. package/dist/intervalCollection.js +0 -1250
  281. package/dist/intervalCollection.js.map +0 -1
  282. package/dist/localValues.js.map +0 -1
  283. package/dist/packageVersion.js.map +0 -1
  284. package/dist/sequence.js.map +0 -1
  285. package/dist/sequenceDeltaEvent.js.map +0 -1
  286. package/dist/sequenceFactory.js +0 -192
  287. package/dist/sequenceFactory.js.map +0 -1
  288. package/dist/sharedIntervalCollection.js.map +0 -1
  289. package/dist/sharedNumberSequence.d.ts +0 -50
  290. package/dist/sharedNumberSequence.d.ts.map +0 -1
  291. package/dist/sharedNumberSequence.js +0 -61
  292. package/dist/sharedNumberSequence.js.map +0 -1
  293. package/dist/sharedObjectSequence.d.ts +0 -50
  294. package/dist/sharedObjectSequence.d.ts.map +0 -1
  295. package/dist/sharedObjectSequence.js +0 -61
  296. package/dist/sharedObjectSequence.js.map +0 -1
  297. package/dist/sharedSequence.js.map +0 -1
  298. package/dist/sharedString.js +0 -187
  299. package/dist/sharedString.js.map +0 -1
  300. package/dist/sparsematrix.d.ts +0 -139
  301. package/dist/sparsematrix.d.ts.map +0 -1
  302. package/dist/sparsematrix.js +0 -332
  303. package/dist/sparsematrix.js.map +0 -1
  304. package/lib/defaultMap.d.ts.map +0 -1
  305. package/lib/defaultMap.js.map +0 -1
  306. package/lib/defaultMapInterfaces.d.ts.map +0 -1
  307. package/lib/defaultMapInterfaces.js.map +0 -1
  308. package/lib/index.d.ts +0 -27
  309. package/lib/index.d.ts.map +0 -1
  310. package/lib/index.js +0 -26
  311. package/lib/index.js.map +0 -1
  312. package/lib/intervalCollection.d.ts +0 -270
  313. package/lib/intervalCollection.d.ts.map +0 -1
  314. package/lib/intervalCollection.js +0 -1238
  315. package/lib/intervalCollection.js.map +0 -1
  316. package/lib/localValues.d.ts.map +0 -1
  317. package/lib/localValues.js.map +0 -1
  318. package/lib/packageVersion.js.map +0 -1
  319. package/lib/sequence.d.ts.map +0 -1
  320. package/lib/sequence.js.map +0 -1
  321. package/lib/sequenceDeltaEvent.d.ts.map +0 -1
  322. package/lib/sequenceDeltaEvent.js.map +0 -1
  323. package/lib/sequenceFactory.d.ts +0 -108
  324. package/lib/sequenceFactory.d.ts.map +0 -1
  325. package/lib/sequenceFactory.js +0 -186
  326. package/lib/sequenceFactory.js.map +0 -1
  327. package/lib/sharedIntervalCollection.d.ts.map +0 -1
  328. package/lib/sharedIntervalCollection.js.map +0 -1
  329. package/lib/sharedNumberSequence.d.ts +0 -50
  330. package/lib/sharedNumberSequence.d.ts.map +0 -1
  331. package/lib/sharedNumberSequence.js +0 -57
  332. package/lib/sharedNumberSequence.js.map +0 -1
  333. package/lib/sharedObjectSequence.d.ts +0 -50
  334. package/lib/sharedObjectSequence.d.ts.map +0 -1
  335. package/lib/sharedObjectSequence.js +0 -57
  336. package/lib/sharedObjectSequence.js.map +0 -1
  337. package/lib/sharedSequence.d.ts.map +0 -1
  338. package/lib/sharedSequence.js.map +0 -1
  339. package/lib/sharedString.d.ts.map +0 -1
  340. package/lib/sharedString.js +0 -183
  341. package/lib/sharedString.js.map +0 -1
  342. package/lib/sparsematrix.d.ts +0 -139
  343. package/lib/sparsematrix.d.ts.map +0 -1
  344. package/lib/sparsematrix.js +0 -323
  345. package/lib/sparsematrix.js.map +0 -1
  346. package/src/sharedNumberSequence.ts +0 -62
  347. package/src/sharedObjectSequence.ts +0 -62
  348. package/src/sparsematrix.ts +0 -421
  349. package/tsconfig.esnext.json +0 -7
@@ -2,77 +2,30 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { Deferred, bufferToString, assert } from "@fluidframework/common-utils";
6
- import { ChildLogger } from "@fluidframework/telemetry-utils";
7
- import { MessageType, } from "@fluidframework/protocol-definitions";
8
- import { Client, createAnnotateRangeOp, createGroupOp, createInsertOp, createRemoveRangeOp, LocalReference, matchProperties, MergeTreeDeltaType, ReferenceType, } from "@fluidframework/merge-tree";
5
+ import { assert, Deferred } from "@fluidframework/core-utils";
6
+ import { bufferToString } from "@fluid-internal/client-utils";
7
+ import { LoggingError, createChildLogger } from "@fluidframework/telemetry-utils";
8
+ import { MessageType } from "@fluidframework/protocol-definitions";
9
+ import {
10
+ // eslint-disable-next-line import/no-deprecated
11
+ Client, createAnnotateRangeOp,
12
+ // eslint-disable-next-line import/no-deprecated
13
+ createGroupOp, createInsertOp, createRemoveRangeOp, matchProperties, MergeTreeDeltaType, createObliterateRangeOp, } from "@fluidframework/merge-tree";
9
14
  import { ObjectStoragePartition, SummaryTreeBuilder } from "@fluidframework/runtime-utils";
10
15
  import { makeHandlesSerializable, parseHandles, SharedObject, } from "@fluidframework/shared-object-base";
11
- import { SequenceIntervalCollectionValueType, } from "./intervalCollection";
12
- import { DefaultMap } from "./defaultMap";
13
- import { SequenceDeltaEvent, SequenceMaintenanceEvent } from "./sequenceDeltaEvent";
16
+ import { DefaultMap } from "./defaultMap.mjs";
17
+ import { SequenceIntervalCollectionValueType, } from "./intervalCollection.mjs";
18
+ import { SequenceDeltaEvent, SequenceMaintenanceEvent } from "./sequenceDeltaEvent.mjs";
14
19
  const snapshotFileName = "header";
15
20
  const contentPath = "content";
21
+ /**
22
+ * @alpha
23
+ */
16
24
  export class SharedSegmentSequence extends SharedObject {
17
- constructor(dataStoreRuntime, id, attributes, segmentFromSpec) {
18
- super(id, dataStoreRuntime, attributes, "fluid_sequence_");
19
- this.dataStoreRuntime = dataStoreRuntime;
20
- this.id = id;
21
- this.segmentFromSpec = segmentFromSpec;
22
- // Deferred that triggers once the object is loaded
23
- this.loadedDeferred = new Deferred();
24
- // cache out going ops created when partial loading
25
- this.loadedDeferredOutgoingOps = [];
26
- // cache incoming ops that arrive when partial loading
27
- this.deferIncomingOps = true;
28
- this.loadedDeferredIncomingOps = [];
29
- this.messagesSinceMSNChange = [];
30
- this.loadedDeferred.promise.catch((error) => {
31
- this.logger.sendErrorEvent({ eventName: "SequenceLoadFailed" }, error);
32
- });
33
- this.client = new Client(segmentFromSpec, ChildLogger.create(this.logger, "SharedSegmentSequence.MergeTreeClient"), dataStoreRuntime.options);
34
- super.on("newListener", (event) => {
35
- switch (event) {
36
- case "sequenceDelta":
37
- if (!this.client.mergeTreeDeltaCallback) {
38
- this.client.mergeTreeDeltaCallback = (opArgs, deltaArgs) => {
39
- this.emit("sequenceDelta", new SequenceDeltaEvent(opArgs, deltaArgs, this.client), this);
40
- };
41
- }
42
- break;
43
- case "maintenance":
44
- if (!this.client.mergeTreeMaintenanceCallback) {
45
- this.client.mergeTreeMaintenanceCallback = (args, opArgs) => {
46
- this.emit("maintenance", new SequenceMaintenanceEvent(opArgs, args, this.client), this);
47
- };
48
- }
49
- break;
50
- default:
51
- }
52
- });
53
- super.on("removeListener", (event) => {
54
- switch (event) {
55
- case "sequenceDelta":
56
- if (super.listenerCount(event) === 0) {
57
- this.client.mergeTreeDeltaCallback = undefined;
58
- }
59
- break;
60
- case "maintenance":
61
- if (super.listenerCount(event) === 0) {
62
- this.client.mergeTreeMaintenanceCallback = undefined;
63
- }
64
- break;
65
- default:
66
- break;
67
- }
68
- });
69
- this.intervalCollections = new DefaultMap(this.serializer, this.handle, (op, localOpMetadata) => this.submitLocalMessage(op, localOpMetadata), new SequenceIntervalCollectionValueType());
70
- }
71
25
  get loaded() {
72
26
  return this.loadedDeferred.promise;
73
27
  }
74
28
  static createOpsFromDelta(event) {
75
- var _a, _b;
76
29
  const ops = [];
77
30
  for (const r of event.ranges) {
78
31
  switch (event.deltaOperation) {
@@ -80,14 +33,15 @@ export class SharedSegmentSequence extends SharedObject {
80
33
  const lastAnnotate = ops[ops.length - 1];
81
34
  const props = {};
82
35
  for (const key of Object.keys(r.propertyDeltas)) {
83
- props[key] = (_b = (_a = r.segment.properties) === null || _a === void 0 ? void 0 : _a[key]) !== null && _b !== void 0 ? _b : null;
36
+ props[key] = r.segment.properties?.[key] ?? null;
84
37
  }
85
- if (lastAnnotate && lastAnnotate.pos2 === r.position &&
38
+ if (lastAnnotate &&
39
+ lastAnnotate.pos2 === r.position &&
86
40
  matchProperties(lastAnnotate.props, props)) {
87
41
  lastAnnotate.pos2 += r.segment.cachedLength;
88
42
  }
89
43
  else {
90
- ops.push(createAnnotateRangeOp(r.position, r.position + r.segment.cachedLength, props, undefined));
44
+ ops.push(createAnnotateRangeOp(r.position, r.position + r.segment.cachedLength, props));
91
45
  }
92
46
  break;
93
47
  }
@@ -96,7 +50,8 @@ export class SharedSegmentSequence extends SharedObject {
96
50
  break;
97
51
  case MergeTreeDeltaType.REMOVE: {
98
52
  const lastRem = ops[ops.length - 1];
99
- if ((lastRem === null || lastRem === void 0 ? void 0 : lastRem.pos1) === r.position) {
53
+ if (lastRem?.pos1 === r.position) {
54
+ assert(lastRem.pos2 !== undefined, 0x3ff /* pos2 should not be undefined here */);
100
55
  lastRem.pos2 += r.segment.cachedLength;
101
56
  }
102
57
  else {
@@ -104,26 +59,94 @@ export class SharedSegmentSequence extends SharedObject {
104
59
  }
105
60
  break;
106
61
  }
62
+ case MergeTreeDeltaType.OBLITERATE: {
63
+ const lastRem = ops[ops.length - 1];
64
+ if (lastRem?.pos1 === r.position) {
65
+ assert(lastRem.pos2 !== undefined, 0x874 /* pos2 should not be undefined here */);
66
+ lastRem.pos2 += r.segment.cachedLength;
67
+ }
68
+ else {
69
+ ops.push(createObliterateRangeOp(r.position, r.position + r.segment.cachedLength));
70
+ }
71
+ break;
72
+ }
107
73
  default:
108
74
  }
109
75
  }
110
76
  return ops;
111
77
  }
78
+ constructor(dataStoreRuntime, id, attributes, segmentFromSpec) {
79
+ super(id, dataStoreRuntime, attributes, "fluid_sequence_");
80
+ this.dataStoreRuntime = dataStoreRuntime;
81
+ this.id = id;
82
+ this.segmentFromSpec = segmentFromSpec;
83
+ /** `Deferred` that triggers once the object is loaded */
84
+ this.loadedDeferred = new Deferred();
85
+ // cache out going ops created when partial loading
86
+ this.loadedDeferredOutgoingOps = [];
87
+ // cache incoming ops that arrive when partial loading
88
+ this.deferIncomingOps = true;
89
+ this.loadedDeferredIncomingOps = [];
90
+ this.messagesSinceMSNChange = [];
91
+ this.guardReentrancy =
92
+ dataStoreRuntime.options.sharedStringPreventReentrancy ?? true
93
+ ? ensureNoReentrancy
94
+ : createReentrancyDetector((depth) => {
95
+ if (totalReentrancyLogs > 0) {
96
+ totalReentrancyLogs--;
97
+ this.logger.sendTelemetryEvent({ eventName: "LocalOpReentry", depth }, new LoggingError(reentrancyErrorMessage));
98
+ }
99
+ });
100
+ this.loadedDeferred.promise.catch((error) => {
101
+ this.logger.sendErrorEvent({ eventName: "SequenceLoadFailed" }, error);
102
+ });
103
+ // eslint-disable-next-line import/no-deprecated
104
+ this.client = new Client(segmentFromSpec, createChildLogger({
105
+ logger: this.logger,
106
+ namespace: "SharedSegmentSequence.MergeTreeClient",
107
+ }), dataStoreRuntime.options);
108
+ this.client.prependListener("delta", (opArgs, deltaArgs) => {
109
+ const event = new SequenceDeltaEvent(opArgs, deltaArgs, this.client);
110
+ if (opArgs.stashed !== true && event.isLocal) {
111
+ this.submitSequenceMessage(opArgs.op);
112
+ }
113
+ this.emit("sequenceDelta", event, this);
114
+ });
115
+ this.client.on("maintenance", (args, opArgs) => {
116
+ this.emit("maintenance", new SequenceMaintenanceEvent(opArgs, args, this.client), this);
117
+ });
118
+ this.intervalCollections = new DefaultMap(this.serializer, this.handle, (op, localOpMetadata) => this.submitLocalMessage(op, localOpMetadata), new SequenceIntervalCollectionValueType(), dataStoreRuntime.options);
119
+ }
112
120
  /**
113
121
  * @param start - The inclusive start of the range to remove
114
122
  * @param end - The exclusive end of the range to remove
115
123
  */
116
124
  removeRange(start, end) {
117
- const removeOp = this.client.removeRangeLocal(start, end);
118
- if (removeOp) {
119
- this.submitSequenceMessage(removeOp);
120
- }
121
- return removeOp;
125
+ this.guardReentrancy(() => this.client.removeRangeLocal(start, end));
122
126
  }
127
+ /**
128
+ * Obliterate is similar to remove, but differs in that segments concurrently
129
+ * inserted into an obliterated range will also be removed
130
+ *
131
+ * @param start - The inclusive start of the range to obliterate
132
+ * @param end - The exclusive end of the range to obliterate
133
+ */
134
+ obliterateRange(start, end) {
135
+ this.guardReentrancy(() => this.client.obliterateRangeLocal(start, end));
136
+ }
137
+ /**
138
+ * @deprecated The ability to create group ops will be removed in an upcoming
139
+ * release, as group ops are redundant with the native batching capabilities
140
+ * of the runtime
141
+ */
123
142
  groupOperation(groupOp) {
124
- this.client.localTransaction(groupOp);
125
- this.submitSequenceMessage(groupOp);
143
+ this.guardReentrancy(() => this.client.localTransaction(groupOp));
126
144
  }
145
+ /**
146
+ * Finds the segment information (i.e. segment + offset) corresponding to a character position in the SharedString.
147
+ * If the position is past the end of the string, `segment` and `offset` on the returned object may be undefined.
148
+ * @param pos - Character position (index) into the current local view of the SharedString.
149
+ */
127
150
  getContainingSegment(pos) {
128
151
  return this.client.getContainingSegment(pos);
129
152
  }
@@ -147,14 +170,10 @@ export class SharedSegmentSequence extends SharedObject {
147
170
  * @param start - The inclusive start position of the range to annotate
148
171
  * @param end - The exclusive end position of the range to annotate
149
172
  * @param props - The properties to annotate the range with
150
- * @param combiningOp - Optional. Specifies how to combine values for the property, such as "incr" for increment.
151
173
  *
152
174
  */
153
- annotateRange(start, end, props, combiningOp) {
154
- const annotateOp = this.client.annotateRangeLocal(start, end, props, combiningOp);
155
- if (annotateOp) {
156
- this.submitSequenceMessage(annotateOp);
157
- }
175
+ annotateRange(start, end, props) {
176
+ this.guardReentrancy(() => this.client.annotateRangeLocal(start, end, props));
158
177
  }
159
178
  getPropertiesAtPosition(pos) {
160
179
  return this.client.getPropertiesAtPosition(pos);
@@ -163,27 +182,28 @@ export class SharedSegmentSequence extends SharedObject {
163
182
  return this.client.getRangeExtentsOfPosition(pos);
164
183
  }
165
184
  /**
166
- * @deprecated - use createLocalReferencePosition
185
+ * Creates a `LocalReferencePosition` on this SharedString. If the refType does not include
186
+ * ReferenceType.Transient, the returned reference will be added to the localRefs on the provided segment.
187
+ * @param segment - Segment to add the local reference on
188
+ * @param offset - Offset on the segment at which to place the local reference
189
+ * @param refType - ReferenceType for the created local reference
190
+ * @param properties - PropertySet to place on the created local reference
167
191
  */
168
- createPositionReference(segment, offset, refType) {
169
- const lref = new LocalReference(this.client, segment, offset, refType);
170
- if (refType !== ReferenceType.Transient) {
171
- this.addLocalReference(lref);
172
- }
173
- return lref;
174
- }
175
- createLocalReferencePosition(segment, offset, refType, properties) {
176
- return this.client.createLocalReferencePosition(segment, offset, refType, properties);
192
+ createLocalReferencePosition(segment, offset, refType, properties, slidingPreference, canSlideToEndpoint) {
193
+ return this.client.createLocalReferencePosition(segment, offset, refType, properties, slidingPreference, canSlideToEndpoint);
177
194
  }
178
195
  /**
179
- * @deprecated - use localReferencePositionToPosition
196
+ * Resolves a `ReferencePosition` into a character position using this client's perspective.
180
197
  */
181
- localRefToPos(localRef) {
182
- return this.client.localReferencePositionToPosition(localRef);
183
- }
184
198
  localReferencePositionToPosition(lref) {
185
199
  return this.client.localReferencePositionToPosition(lref);
186
200
  }
201
+ /**
202
+ * Removes a `LocalReferencePosition` from this SharedString.
203
+ */
204
+ removeLocalReferencePosition(lref) {
205
+ return this.client.removeLocalReferencePosition(lref);
206
+ }
187
207
  /**
188
208
  * Resolves a remote client's position against the local sequence
189
209
  * and returns the remote client's position relative to the local
@@ -209,29 +229,14 @@ export class SharedSegmentSequence extends SharedObject {
209
229
  const metadata = this.client.peekPendingSegmentGroups(message.type === MergeTreeDeltaType.GROUP ? message.ops.length : 1);
210
230
  // if loading isn't complete, we need to cache
211
231
  // local ops until loading is complete, and then
212
- // they will be resent
232
+ // they will be present
213
233
  if (!this.loadedDeferred.isCompleted) {
214
- this.loadedDeferredOutgoingOps.push([translated, metadata]);
234
+ this.loadedDeferredOutgoingOps.push(metadata ? [translated, metadata] : translated);
215
235
  }
216
236
  else {
217
237
  this.submitLocalMessage(translated, metadata);
218
238
  }
219
239
  }
220
- /**
221
- * @deprecated - use createLocalReferencePosition
222
- */
223
- addLocalReference(lref) {
224
- return this.client.addLocalReference(lref);
225
- }
226
- /**
227
- * @deprecated - use removeLocalReferencePosition
228
- */
229
- removeLocalReference(lref) {
230
- return this.client.removeLocalReferencePosition(lref);
231
- }
232
- removeLocalReferencePosition(lref) {
233
- return this.client.removeLocalReferencePosition(lref);
234
- }
235
240
  /**
236
241
  * Given a position specified relative to a marker id, lookup the marker
237
242
  * and convert the position to a character position.
@@ -242,53 +247,70 @@ export class SharedSegmentSequence extends SharedObject {
242
247
  }
243
248
  /**
244
249
  * Walk the underlying segments of the sequence.
245
- * The walked segments may extend beyond the range
246
- * if the segments cross the ranges start or end boundaries.
247
- * Set split range to true to ensure only segments within the
248
- * range are walked.
250
+ * The walked segments may extend beyond the range if the segments cross the
251
+ * ranges start or end boundaries.
249
252
  *
250
- * @param handler - The function to handle each segment
253
+ * Set split range to true to ensure only segments within the range are walked.
254
+ *
255
+ * @param handler - The function to handle each segment. Traversal ends if
256
+ * this function returns true.
251
257
  * @param start - Optional. The start of range walk.
252
258
  * @param end - Optional. The end of range walk
253
259
  * @param accum - Optional. An object that will be passed to the handler for accumulation
254
260
  * @param splitRange - Optional. Splits boundary segments on the range boundaries
255
261
  */
256
262
  walkSegments(handler, start, end, accum, splitRange = false) {
257
- return this.client.walkSegments(handler, start, end, accum, splitRange);
258
- }
259
- getStackContext(startPos, rangeLabels) {
260
- return this.client.getStackContext(startPos, rangeLabels);
263
+ this.client.walkSegments(handler, start, end, accum, splitRange);
261
264
  }
265
+ /**
266
+ * @returns The most recent sequence number which has been acked by the server and processed by this
267
+ * SharedSegmentSequence.
268
+ */
262
269
  getCurrentSeq() {
263
270
  return this.client.getCurrentSeq();
264
271
  }
272
+ /**
273
+ * Inserts a segment directly before a `ReferencePosition`.
274
+ * @param refPos - The reference position to insert the segment at
275
+ * @param segment - The segment to insert
276
+ */
265
277
  insertAtReferencePosition(pos, segment) {
266
- const insertOp = this.client.insertAtReferencePositionLocal(pos, segment);
267
- if (insertOp) {
268
- this.submitSequenceMessage(insertOp);
269
- }
278
+ this.guardReentrancy(() => this.client.insertAtReferencePositionLocal(pos, segment));
270
279
  }
271
280
  /**
272
- * @deprecated - IntervalCollections are created on a first-write wins basis, and concurrent creates
273
- * are supported. Use `getIntervalCollection` instead.
281
+ * Inserts a segment
282
+ * @param start - The position to insert the segment at
283
+ * @param spec - The segment to inserts spec
274
284
  */
275
- async waitIntervalCollection(label) {
276
- return this.intervalCollections.get(label);
285
+ insertFromSpec(pos, spec) {
286
+ const segment = this.segmentFromSpec(spec);
287
+ this.guardReentrancy(() => this.client.insertSegmentLocal(pos, segment));
277
288
  }
289
+ /**
290
+ * Retrieves the interval collection keyed on `label`. If no such interval collection exists,
291
+ * creates one.
292
+ */
278
293
  getIntervalCollection(label) {
279
294
  return this.intervalCollections.get(label);
280
295
  }
281
296
  /**
282
- * @returns an iterable object that enumerates the IntervalCollection labels
283
- * Usage:
297
+ * @returns An iterable object that enumerates the IntervalCollection labels.
298
+ *
299
+ * @example
300
+ *
301
+ * ```typescript
284
302
  * const iter = this.getIntervalCollectionKeys();
285
303
  * for (key of iter)
286
304
  * const collection = this.getIntervalCollection(key);
287
305
  * ...
288
- */
306
+ * ```
307
+ */
289
308
  getIntervalCollectionLabels() {
290
309
  return this.intervalCollections.keys();
291
310
  }
311
+ /**
312
+ * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}
313
+ */
292
314
  summarizeCore(serializer, telemetryContext) {
293
315
  const builder = new SummaryTreeBuilder();
294
316
  // conditionally write the interval collection blob
@@ -325,19 +347,24 @@ export class SharedSegmentSequence extends SharedObject {
325
347
  const insert = this.client.insertSegmentLocal(insertIndex, segment);
326
348
  if (insert) {
327
349
  if (start < end) {
328
- const remove = this.client.removeRangeLocal(start, end);
329
- this.submitSequenceMessage(createGroupOp(insert, remove));
330
- }
331
- else {
332
- this.submitSequenceMessage(insert);
350
+ this.client.removeRangeLocal(start, end);
333
351
  }
334
352
  }
335
353
  }
354
+ /**
355
+ * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onConnect}
356
+ */
336
357
  onConnect() {
337
358
  // Update merge tree collaboration information with new client ID and then resend pending ops
338
359
  this.client.startOrUpdateCollaboration(this.runtime.clientId);
339
360
  }
361
+ /**
362
+ * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}
363
+ */
340
364
  onDisconnect() { }
365
+ /**
366
+ * {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitCore}
367
+ */
341
368
  reSubmitCore(content, localOpMetadata) {
342
369
  if (!this.intervalCollections.tryResubmitMessage(content, localOpMetadata)) {
343
370
  this.submitSequenceMessage(this.client.regeneratePendingOp(content, localOpMetadata));
@@ -347,7 +374,6 @@ export class SharedSegmentSequence extends SharedObject {
347
374
  * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}
348
375
  */
349
376
  async loadCore(storage) {
350
- var _a;
351
377
  if (await storage.contains(snapshotFileName)) {
352
378
  const blob = await storage.readBlob(snapshotFileName);
353
379
  const header = bufferToString(blob, "utf8");
@@ -364,10 +390,11 @@ export class SharedSegmentSequence extends SharedObject {
364
390
  .then((msgs) => {
365
391
  msgs.forEach((m) => {
366
392
  const collabWindow = this.client.getCollabWindow();
367
- if (m.minimumSequenceNumber < collabWindow.minSeq
368
- || m.referenceSequenceNumber < collabWindow.minSeq
369
- || m.sequenceNumber <= collabWindow.minSeq
370
- || m.sequenceNumber <= collabWindow.currentSeq) {
393
+ if (m.minimumSequenceNumber < collabWindow.minSeq ||
394
+ m.referenceSequenceNumber < collabWindow.minSeq ||
395
+ m.sequenceNumber <= collabWindow.minSeq ||
396
+ // sequenceNumber could be the same if messages are part of a grouped batch
397
+ m.sequenceNumber < collabWindow.currentSeq) {
371
398
  throw new Error(`Invalid catchup operations in snapshot: ${JSON.stringify({
372
399
  op: {
373
400
  seq: m.sequenceNumber,
@@ -387,7 +414,7 @@ export class SharedSegmentSequence extends SharedObject {
387
414
  .catch((error) => {
388
415
  this.loadFinished(error);
389
416
  });
390
- if (((_a = this.dataStoreRuntime.options) === null || _a === void 0 ? void 0 : _a.sequenceInitializeFromHeaderOnly) !== true) {
417
+ if (this.dataStoreRuntime.options?.sequenceInitializeFromHeaderOnly !== true) {
391
418
  // if we not doing partial load, await the catch up ops,
392
419
  // and the finalization of the load
393
420
  await loadCatchUpOps;
@@ -397,6 +424,9 @@ export class SharedSegmentSequence extends SharedObject {
397
424
  this.loadFinished(error);
398
425
  }
399
426
  }
427
+ /**
428
+ * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}
429
+ */
400
430
  processCore(message, local, localOpMetadata) {
401
431
  // if loading isn't complete, we need to cache all
402
432
  // incoming ops to be applied after loading is complete
@@ -412,14 +442,19 @@ export class SharedSegmentSequence extends SharedObject {
412
442
  }
413
443
  }
414
444
  }
445
+ /**
446
+ * {@inheritDoc @fluidframework/shared-object-base#SharedObject.didAttach}
447
+ */
415
448
  didAttach() {
416
- var _a;
417
449
  // If we are not local, and we've attached we need to start generating and sending ops
418
450
  // so start collaboration and provide a default client id incase we are not connected
419
451
  if (this.isAttached()) {
420
- this.client.startOrUpdateCollaboration((_a = this.runtime.clientId) !== null && _a !== void 0 ? _a : "attached");
452
+ this.client.startOrUpdateCollaboration(this.runtime.clientId ?? "attached");
421
453
  }
422
454
  }
455
+ /**
456
+ * {@inheritDoc @fluidframework/shared-object-base#SharedObject.initializeLocalCore}
457
+ */
423
458
  initializeLocalCore() {
424
459
  super.initializeLocalCore();
425
460
  this.loadFinished();
@@ -428,18 +463,19 @@ export class SharedSegmentSequence extends SharedObject {
428
463
  * {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}
429
464
  */
430
465
  applyStashedOp(content) {
431
- return this.client.applyStashedOp(content);
466
+ return this.client.applyStashedOp(parseHandles(content, this.serializer));
432
467
  }
433
468
  summarizeMergeTree(serializer) {
434
469
  // Are we fully loaded? If not, things will go south
435
470
  assert(this.loadedDeferred.isCompleted, 0x074 /* "Snapshot called when not fully loaded" */);
436
471
  const minSeq = this.runtime.deltaManager.minimumSequenceNumber;
437
472
  this.processMinSequenceNumberChanged(minSeq);
438
- this.messagesSinceMSNChange.forEach((m) => { m.minimumSequenceNumber = minSeq; });
473
+ this.messagesSinceMSNChange.forEach((m) => {
474
+ m.minimumSequenceNumber = minSeq;
475
+ });
439
476
  return this.client.summarize(this.runtime, this.handle, serializer, this.messagesSinceMSNChange);
440
477
  }
441
478
  processMergeTreeMsg(rawMessage, local) {
442
- var _a, _b;
443
479
  const message = parseHandles(rawMessage, this.serializer);
444
480
  const ops = [];
445
481
  function transformOps(event) {
@@ -447,23 +483,28 @@ export class SharedSegmentSequence extends SharedObject {
447
483
  }
448
484
  const needsTransformation = message.referenceSequenceNumber !== message.sequenceNumber - 1;
449
485
  let stashMessage = message;
450
- if (((_a = this.runtime.options) === null || _a === void 0 ? void 0 : _a.newMergeTreeSnapshotFormat) !== true) {
486
+ if (this.runtime.options?.newMergeTreeSnapshotFormat !== true) {
451
487
  if (needsTransformation) {
452
488
  this.on("sequenceDelta", transformOps);
453
489
  }
454
490
  }
455
491
  this.client.applyMsg(message, local);
456
- if (((_b = this.runtime.options) === null || _b === void 0 ? void 0 : _b.newMergeTreeSnapshotFormat) !== true) {
492
+ if (this.runtime.options?.newMergeTreeSnapshotFormat !== true) {
457
493
  if (needsTransformation) {
458
494
  this.removeListener("sequenceDelta", transformOps);
459
495
  // shallow clone the message as we only overwrite top level properties,
460
496
  // like referenceSequenceNumber and content only
461
- stashMessage = Object.assign(Object.assign({}, message), { referenceSequenceNumber: stashMessage.sequenceNumber - 1, contents: ops.length !== 1 ? createGroupOp(...ops) : ops[0] });
497
+ stashMessage = {
498
+ ...message,
499
+ referenceSequenceNumber: stashMessage.sequenceNumber - 1,
500
+ // eslint-disable-next-line import/no-deprecated
501
+ contents: ops.length !== 1 ? createGroupOp(...ops) : ops[0],
502
+ };
462
503
  }
463
504
  this.messagesSinceMSNChange.push(stashMessage);
464
505
  // Do GC every once in a while...
465
- if (this.messagesSinceMSNChange.length > 20
466
- && this.messagesSinceMSNChange[20].sequenceNumber < message.minimumSequenceNumber) {
506
+ if (this.messagesSinceMSNChange.length > 20 &&
507
+ this.messagesSinceMSNChange[20].sequenceNumber < message.minimumSequenceNumber) {
467
508
  this.processMinSequenceNumberChanged(message.minimumSequenceNumber);
468
509
  }
469
510
  }
@@ -523,4 +564,36 @@ export class SharedSegmentSequence extends SharedObject {
523
564
  }
524
565
  }
525
566
  }
526
- //# sourceMappingURL=sequence.js.map
567
+ function createReentrancyDetector(onReentrancy) {
568
+ let depth = 0;
569
+ function detectReentrancy(callback) {
570
+ if (depth > 0) {
571
+ onReentrancy(depth);
572
+ }
573
+ depth++;
574
+ try {
575
+ return callback();
576
+ }
577
+ finally {
578
+ depth--;
579
+ }
580
+ }
581
+ return detectReentrancy;
582
+ }
583
+ /**
584
+ * Apps which generate reentrant behavior may do so at a high frequency.
585
+ * Logging even per-SharedSegmentSequence instance might be too noisy, and having a few logs from a session
586
+ * is likely enough.
587
+ */
588
+ let totalReentrancyLogs = 3;
589
+ /**
590
+ * Resets the reentrancy log counter. Test-only API.
591
+ */
592
+ export function resetReentrancyLogCounter() {
593
+ totalReentrancyLogs = 3;
594
+ }
595
+ const reentrancyErrorMessage = "Reentrancy detected in sequence local ops";
596
+ const ensureNoReentrancy = createReentrancyDetector(() => {
597
+ throw new LoggingError(reentrancyErrorMessage);
598
+ });
599
+ //# sourceMappingURL=sequence.mjs.map