@fluidframework/merge-tree 2.12.0 → 2.13.0

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 (285) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/MergeTreeTextHelper.d.ts.map +1 -1
  3. package/dist/MergeTreeTextHelper.js +0 -2
  4. package/dist/MergeTreeTextHelper.js.map +1 -1
  5. package/dist/attributionPolicy.d.ts.map +1 -1
  6. package/dist/attributionPolicy.js +6 -16
  7. package/dist/attributionPolicy.js.map +1 -1
  8. package/dist/client.d.ts +3 -4
  9. package/dist/client.d.ts.map +1 -1
  10. package/dist/client.js +39 -28
  11. package/dist/client.js.map +1 -1
  12. package/dist/endOfTreeSegment.d.ts +2 -1
  13. package/dist/endOfTreeSegment.d.ts.map +1 -1
  14. package/dist/endOfTreeSegment.js.map +1 -1
  15. package/dist/index.d.ts +2 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -4
  18. package/dist/index.js.map +1 -1
  19. package/dist/mergeTree.d.ts +8 -7
  20. package/dist/mergeTree.d.ts.map +1 -1
  21. package/dist/mergeTree.js +190 -216
  22. package/dist/mergeTree.js.map +1 -1
  23. package/dist/mergeTreeNodeWalk.d.ts.map +1 -1
  24. package/dist/mergeTreeNodeWalk.js +3 -2
  25. package/dist/mergeTreeNodeWalk.js.map +1 -1
  26. package/dist/mergeTreeNodes.d.ts +76 -162
  27. package/dist/mergeTreeNodes.d.ts.map +1 -1
  28. package/dist/mergeTreeNodes.js +100 -112
  29. package/dist/mergeTreeNodes.js.map +1 -1
  30. package/dist/mergeTreeTracking.d.ts.map +1 -1
  31. package/dist/mergeTreeTracking.js +0 -2
  32. package/dist/mergeTreeTracking.js.map +1 -1
  33. package/dist/partialLengths.d.ts +2 -2
  34. package/dist/partialLengths.d.ts.map +1 -1
  35. package/dist/partialLengths.js +28 -26
  36. package/dist/partialLengths.js.map +1 -1
  37. package/dist/perspective.d.ts +3 -2
  38. package/dist/perspective.d.ts.map +1 -1
  39. package/dist/perspective.js +11 -4
  40. package/dist/perspective.js.map +1 -1
  41. package/dist/referencePositions.d.ts.map +1 -1
  42. package/dist/referencePositions.js +4 -1
  43. package/dist/referencePositions.js.map +1 -1
  44. package/dist/revertibles.d.ts.map +1 -1
  45. package/dist/revertibles.js +10 -11
  46. package/dist/revertibles.js.map +1 -1
  47. package/dist/segmentGroupCollection.d.ts +4 -4
  48. package/dist/segmentGroupCollection.d.ts.map +1 -1
  49. package/dist/segmentGroupCollection.js +0 -6
  50. package/dist/segmentGroupCollection.js.map +1 -1
  51. package/dist/segmentInfos.d.ts +257 -0
  52. package/dist/segmentInfos.d.ts.map +1 -0
  53. package/dist/segmentInfos.js +166 -0
  54. package/dist/segmentInfos.js.map +1 -0
  55. package/dist/snapshotLoader.d.ts.map +1 -1
  56. package/dist/snapshotLoader.js +38 -44
  57. package/dist/snapshotLoader.js.map +1 -1
  58. package/dist/snapshotV1.d.ts.map +1 -1
  59. package/dist/snapshotV1.js +9 -12
  60. package/dist/snapshotV1.js.map +1 -1
  61. package/dist/snapshotlegacy.d.ts +2 -2
  62. package/dist/snapshotlegacy.d.ts.map +1 -1
  63. package/dist/snapshotlegacy.js +5 -3
  64. package/dist/snapshotlegacy.js.map +1 -1
  65. package/dist/sortedSegmentSet.d.ts.map +1 -1
  66. package/dist/sortedSegmentSet.js +5 -8
  67. package/dist/sortedSegmentSet.js.map +1 -1
  68. package/dist/test/beastTest.spec.d.ts +0 -2
  69. package/dist/test/beastTest.spec.d.ts.map +1 -1
  70. package/dist/test/beastTest.spec.js +1 -5
  71. package/dist/test/beastTest.spec.js.map +1 -1
  72. package/dist/test/client.annotateMarker.spec.js.map +1 -1
  73. package/dist/test/client.applyMsg.spec.js +15 -12
  74. package/dist/test/client.applyMsg.spec.js.map +1 -1
  75. package/dist/test/client.attributionFarm.spec.js.map +1 -1
  76. package/dist/test/client.getPosition.spec.js +3 -2
  77. package/dist/test/client.getPosition.spec.js.map +1 -1
  78. package/dist/test/client.localReference.spec.js +6 -6
  79. package/dist/test/client.localReference.spec.js.map +1 -1
  80. package/dist/test/client.localReferenceFarm.spec.js.map +1 -1
  81. package/dist/test/client.rollback.spec.js.map +1 -1
  82. package/dist/test/dirname.cjs +0 -1
  83. package/dist/test/dirname.cjs.map +1 -1
  84. package/dist/test/index.d.ts +1 -1
  85. package/dist/test/index.d.ts.map +1 -1
  86. package/dist/test/index.js +2 -4
  87. package/dist/test/index.js.map +1 -1
  88. package/dist/test/mergeTree.annotate.spec.js +3 -0
  89. package/dist/test/mergeTree.annotate.spec.js.map +1 -1
  90. package/dist/test/mergeTree.insertingWalk.spec.js +1 -1
  91. package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
  92. package/dist/test/mergeTree.markRangeRemoved.spec.js +2 -0
  93. package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  94. package/dist/test/mergeTree.walk.spec.js.map +1 -1
  95. package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
  96. package/dist/test/mergeTreeOperationRunner.js +2 -3
  97. package/dist/test/mergeTreeOperationRunner.js.map +1 -1
  98. package/dist/test/obliterate.spec.js.map +1 -1
  99. package/dist/test/propertyManager.spec.js.map +1 -1
  100. package/dist/test/reconnectHelper.d.ts +2 -1
  101. package/dist/test/reconnectHelper.d.ts.map +1 -1
  102. package/dist/test/reconnectHelper.js.map +1 -1
  103. package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  104. package/dist/test/revertibleFarm.spec.js.map +1 -1
  105. package/dist/test/segmentGroupCollection.spec.js +15 -3
  106. package/dist/test/segmentGroupCollection.spec.js.map +1 -1
  107. package/dist/test/snapshot.utils.d.ts +2 -2
  108. package/dist/test/snapshot.utils.d.ts.map +1 -1
  109. package/dist/test/snapshot.utils.js.map +1 -1
  110. package/dist/test/sortedSegmentSet.spec.js +4 -3
  111. package/dist/test/sortedSegmentSet.spec.js.map +1 -1
  112. package/dist/test/testClient.d.ts +8 -6
  113. package/dist/test/testClient.d.ts.map +1 -1
  114. package/dist/test/testClient.js +29 -27
  115. package/dist/test/testClient.js.map +1 -1
  116. package/dist/test/testClientLogger.d.ts.map +1 -1
  117. package/dist/test/testClientLogger.js +6 -4
  118. package/dist/test/testClientLogger.js.map +1 -1
  119. package/dist/test/testUtils.d.ts +2 -2
  120. package/dist/test/testUtils.d.ts.map +1 -1
  121. package/dist/test/testUtils.js +32 -8
  122. package/dist/test/testUtils.js.map +1 -1
  123. package/dist/test/text.d.ts +2 -2
  124. package/dist/test/text.d.ts.map +1 -1
  125. package/dist/test/text.js +12 -6
  126. package/dist/test/text.js.map +1 -1
  127. package/dist/test/tracking.spec.js.map +1 -1
  128. package/dist/test/wordUnitTests.spec.js +1 -1
  129. package/dist/test/wordUnitTests.spec.js.map +1 -1
  130. package/dist/zamboni.d.ts.map +1 -1
  131. package/dist/zamboni.js +8 -7
  132. package/dist/zamboni.js.map +1 -1
  133. package/lib/MergeTreeTextHelper.d.ts.map +1 -1
  134. package/lib/MergeTreeTextHelper.js +0 -2
  135. package/lib/MergeTreeTextHelper.js.map +1 -1
  136. package/lib/attributionPolicy.d.ts.map +1 -1
  137. package/lib/attributionPolicy.js +6 -16
  138. package/lib/attributionPolicy.js.map +1 -1
  139. package/lib/client.d.ts +3 -4
  140. package/lib/client.d.ts.map +1 -1
  141. package/lib/client.js +40 -29
  142. package/lib/client.js.map +1 -1
  143. package/lib/endOfTreeSegment.d.ts +2 -1
  144. package/lib/endOfTreeSegment.d.ts.map +1 -1
  145. package/lib/endOfTreeSegment.js.map +1 -1
  146. package/lib/index.d.ts +2 -1
  147. package/lib/index.d.ts.map +1 -1
  148. package/lib/index.js +1 -1
  149. package/lib/index.js.map +1 -1
  150. package/lib/mergeTree.d.ts +8 -7
  151. package/lib/mergeTree.d.ts.map +1 -1
  152. package/lib/mergeTree.js +177 -205
  153. package/lib/mergeTree.js.map +1 -1
  154. package/lib/mergeTreeNodeWalk.d.ts.map +1 -1
  155. package/lib/mergeTreeNodeWalk.js +3 -2
  156. package/lib/mergeTreeNodeWalk.js.map +1 -1
  157. package/lib/mergeTreeNodes.d.ts +76 -162
  158. package/lib/mergeTreeNodes.d.ts.map +1 -1
  159. package/lib/mergeTreeNodes.js +95 -108
  160. package/lib/mergeTreeNodes.js.map +1 -1
  161. package/lib/mergeTreeTracking.d.ts.map +1 -1
  162. package/lib/mergeTreeTracking.js +0 -2
  163. package/lib/mergeTreeTracking.js.map +1 -1
  164. package/lib/partialLengths.d.ts +2 -2
  165. package/lib/partialLengths.d.ts.map +1 -1
  166. package/lib/partialLengths.js +25 -23
  167. package/lib/partialLengths.js.map +1 -1
  168. package/lib/perspective.d.ts +3 -2
  169. package/lib/perspective.d.ts.map +1 -1
  170. package/lib/perspective.js +11 -4
  171. package/lib/perspective.js.map +1 -1
  172. package/lib/referencePositions.d.ts.map +1 -1
  173. package/lib/referencePositions.js +4 -1
  174. package/lib/referencePositions.js.map +1 -1
  175. package/lib/revertibles.d.ts.map +1 -1
  176. package/lib/revertibles.js +8 -9
  177. package/lib/revertibles.js.map +1 -1
  178. package/lib/segmentGroupCollection.d.ts +4 -4
  179. package/lib/segmentGroupCollection.d.ts.map +1 -1
  180. package/lib/segmentGroupCollection.js +0 -6
  181. package/lib/segmentGroupCollection.js.map +1 -1
  182. package/lib/segmentInfos.d.ts +257 -0
  183. package/lib/segmentInfos.d.ts.map +1 -0
  184. package/lib/segmentInfos.js +145 -0
  185. package/lib/segmentInfos.js.map +1 -0
  186. package/lib/snapshotLoader.d.ts.map +1 -1
  187. package/lib/snapshotLoader.js +38 -44
  188. package/lib/snapshotLoader.js.map +1 -1
  189. package/lib/snapshotV1.d.ts.map +1 -1
  190. package/lib/snapshotV1.js +9 -12
  191. package/lib/snapshotV1.js.map +1 -1
  192. package/lib/snapshotlegacy.d.ts +2 -2
  193. package/lib/snapshotlegacy.d.ts.map +1 -1
  194. package/lib/snapshotlegacy.js +5 -3
  195. package/lib/snapshotlegacy.js.map +1 -1
  196. package/lib/sortedSegmentSet.d.ts.map +1 -1
  197. package/lib/sortedSegmentSet.js +5 -8
  198. package/lib/sortedSegmentSet.js.map +1 -1
  199. package/lib/test/beastTest.spec.d.ts +0 -2
  200. package/lib/test/beastTest.spec.d.ts.map +1 -1
  201. package/lib/test/beastTest.spec.js +0 -3
  202. package/lib/test/beastTest.spec.js.map +1 -1
  203. package/lib/test/client.annotateMarker.spec.js.map +1 -1
  204. package/lib/test/client.applyMsg.spec.js +15 -12
  205. package/lib/test/client.applyMsg.spec.js.map +1 -1
  206. package/lib/test/client.attributionFarm.spec.js.map +1 -1
  207. package/lib/test/client.getPosition.spec.js +3 -2
  208. package/lib/test/client.getPosition.spec.js.map +1 -1
  209. package/lib/test/client.localReference.spec.js +1 -1
  210. package/lib/test/client.localReference.spec.js.map +1 -1
  211. package/lib/test/client.localReferenceFarm.spec.js.map +1 -1
  212. package/lib/test/client.rollback.spec.js +1 -1
  213. package/lib/test/client.rollback.spec.js.map +1 -1
  214. package/lib/test/dirname.cjs +0 -1
  215. package/lib/test/dirname.cjs.map +1 -1
  216. package/lib/test/index.d.ts +1 -1
  217. package/lib/test/index.d.ts.map +1 -1
  218. package/lib/test/index.js +1 -1
  219. package/lib/test/index.js.map +1 -1
  220. package/lib/test/mergeTree.annotate.spec.js +3 -0
  221. package/lib/test/mergeTree.annotate.spec.js.map +1 -1
  222. package/lib/test/mergeTree.insertingWalk.spec.js +2 -2
  223. package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
  224. package/lib/test/mergeTree.markRangeRemoved.spec.js +2 -0
  225. package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
  226. package/lib/test/mergeTree.walk.spec.js.map +1 -1
  227. package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
  228. package/lib/test/mergeTreeOperationRunner.js +1 -2
  229. package/lib/test/mergeTreeOperationRunner.js.map +1 -1
  230. package/lib/test/obliterate.spec.js.map +1 -1
  231. package/lib/test/propertyManager.spec.js.map +1 -1
  232. package/lib/test/reconnectHelper.d.ts +2 -1
  233. package/lib/test/reconnectHelper.d.ts.map +1 -1
  234. package/lib/test/reconnectHelper.js.map +1 -1
  235. package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
  236. package/lib/test/revertibleFarm.spec.js.map +1 -1
  237. package/lib/test/segmentGroupCollection.spec.js +15 -3
  238. package/lib/test/segmentGroupCollection.spec.js.map +1 -1
  239. package/lib/test/snapshot.utils.d.ts +2 -2
  240. package/lib/test/snapshot.utils.d.ts.map +1 -1
  241. package/lib/test/snapshot.utils.js.map +1 -1
  242. package/lib/test/sortedSegmentSet.spec.js +4 -3
  243. package/lib/test/sortedSegmentSet.spec.js.map +1 -1
  244. package/lib/test/testClient.d.ts +8 -6
  245. package/lib/test/testClient.d.ts.map +1 -1
  246. package/lib/test/testClient.js +30 -28
  247. package/lib/test/testClient.js.map +1 -1
  248. package/lib/test/testClientLogger.d.ts.map +1 -1
  249. package/lib/test/testClientLogger.js +5 -3
  250. package/lib/test/testClientLogger.js.map +1 -1
  251. package/lib/test/testUtils.d.ts +2 -2
  252. package/lib/test/testUtils.d.ts.map +1 -1
  253. package/lib/test/testUtils.js +9 -8
  254. package/lib/test/testUtils.js.map +1 -1
  255. package/lib/test/text.d.ts +2 -2
  256. package/lib/test/text.d.ts.map +1 -1
  257. package/lib/test/text.js +12 -6
  258. package/lib/test/text.js.map +1 -1
  259. package/lib/test/tracking.spec.js.map +1 -1
  260. package/lib/test/wordUnitTests.spec.js +1 -1
  261. package/lib/test/wordUnitTests.spec.js.map +1 -1
  262. package/lib/zamboni.d.ts.map +1 -1
  263. package/lib/zamboni.js +7 -6
  264. package/lib/zamboni.js.map +1 -1
  265. package/package.json +17 -17
  266. package/src/MergeTreeTextHelper.ts +2 -4
  267. package/src/attributionPolicy.ts +5 -13
  268. package/src/client.ts +55 -44
  269. package/src/endOfTreeSegment.ts +3 -3
  270. package/src/index.ts +4 -6
  271. package/src/mergeTree.ts +245 -282
  272. package/src/mergeTreeNodeWalk.ts +3 -2
  273. package/src/mergeTreeNodes.ts +190 -322
  274. package/src/mergeTreeTracking.ts +0 -3
  275. package/src/partialLengths.ts +42 -27
  276. package/src/perspective.ts +27 -4
  277. package/src/referencePositions.ts +4 -1
  278. package/src/revertibles.ts +19 -13
  279. package/src/segmentGroupCollection.ts +7 -18
  280. package/src/segmentInfos.ts +377 -0
  281. package/src/snapshotLoader.ts +60 -57
  282. package/src/snapshotV1.ts +14 -16
  283. package/src/snapshotlegacy.ts +12 -17
  284. package/src/sortedSegmentSet.ts +6 -8
  285. package/src/zamboni.ts +10 -12
@@ -0,0 +1,257 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { ISegmentInternal, ISegmentPrivate, MergeBlock } from "./mergeTreeNodes.js";
6
+ import type { ReferencePosition } from "./referencePositions.js";
7
+ export interface StringToType {
8
+ "string": string;
9
+ "number": number;
10
+ "object": object;
11
+ "array": [];
12
+ "boolean": boolean;
13
+ }
14
+ export declare function propExists<P extends string>(thing: unknown, prop: P): thing is Record<P, unknown>;
15
+ export declare function hasProp<P extends string, T extends keyof StringToType>(thing: unknown, prop: P, type: T): thing is Record<P, StringToType[typeof type]>;
16
+ export declare function propInstanceOf<P extends string, T>(thing: unknown, prop: P, type: new (...args: any[]) => T): thing is Record<P, T>;
17
+ /**
18
+ * Contains insertion information associated to an {@link ISegment}.
19
+ */
20
+ export interface IInsertionInfo {
21
+ /**
22
+ * Short clientId for the client that inserted this segment.
23
+ */
24
+ clientId: number;
25
+ /**
26
+ * Local seq at which this segment was inserted.
27
+ * This is defined if and only if the insertion of the segment is pending ack, i.e. `seq` is UnassignedSequenceNumber.
28
+ * Once the segment is acked, this field is cleared.
29
+ *
30
+ * @privateRemarks
31
+ * See {@link CollaborationWindow.localSeq} for more information on the semantics of localSeq.
32
+ */
33
+ localSeq?: number;
34
+ /**
35
+ * Seq at which this segment was inserted.
36
+ * If undefined, it is assumed the segment was inserted prior to the collab window's minimum sequence number.
37
+ */
38
+ seq: number;
39
+ }
40
+ /**
41
+ * Converts a segment-like object to an insertion info object if possible.
42
+ *
43
+ * @param segmentLike - The segment-like object to convert.
44
+ * @returns The insertion info object if the conversion is possible, otherwise undefined.
45
+ */
46
+ export declare const toInsertionInfo: (segmentLike: unknown) => IInsertionInfo | undefined;
47
+ /**
48
+ * A type-guard which determines if the segment has insertion info, and
49
+ * returns true if it does, along with applying strong typing.
50
+ *
51
+ * @param segmentLike - The segment-like object to check.
52
+ * @returns True if the segment has insertion info, otherwise false.
53
+ */
54
+ export declare const isInserted: (segmentLike: unknown) => segmentLike is IInsertionInfo;
55
+ /**
56
+ * Asserts that the segment has insertion info. Usage of this function should not produce a user facing error.
57
+ *
58
+ * @param segmentLike - The segment-like object to check.
59
+ * @throws Will throw an error if the segment does not have insertion info.
60
+ */
61
+ export declare const assertInserted: <T extends Partial<IInsertionInfo> | undefined>(segmentLike: ISegmentInternal | Partial<IInsertionInfo> | T) => asserts segmentLike is IInsertionInfo | Exclude<T, Partial<IInsertionInfo>>;
62
+ /**
63
+ * Common properties for a node in a merge tree.
64
+ */
65
+ export interface IMergeNodeInfo {
66
+ /**
67
+ * The parent merge block if the node is parented
68
+ */
69
+ parent: MergeBlock;
70
+ /**
71
+ * The index of this node in its parent's list of children.
72
+ */
73
+ index: number;
74
+ /**
75
+ * A string that can be used for comparing the location of this node to other `MergeNode`s in the same tree.
76
+ * `a.ordinal < b.ordinal` if and only if `a` comes before `b` in a pre-order traversal of the tree.
77
+ */
78
+ ordinal: string;
79
+ }
80
+ /**
81
+ * Converts a segment-like object to a merge node info object if possible.
82
+ *
83
+ * @param segmentLike - The segment-like object to convert.
84
+ * @returns The merge node info object if the conversion is possible, otherwise undefined.
85
+ */
86
+ export declare const toMergeNodeInfo: (nodeLike: unknown) => IMergeNodeInfo | undefined;
87
+ /**
88
+ * A type-guard which determines if the segment has merge node info, and
89
+ * returns true if it does, along with applying strong typing.
90
+ *
91
+ * @param nodeLike - The segment-like object to check.
92
+ * @returns True if the segment has merge node info, otherwise false.
93
+ */
94
+ export declare const isMergeNodeInfo: (nodeLike: unknown) => nodeLike is IMergeNodeInfo;
95
+ /**
96
+ * Asserts that the segment has merge node info. Usage of this function should not produce a user facing error.
97
+ *
98
+ * @param segmentLike - The segment-like object to check.
99
+ * @throws Will throw an error if the segment does not have merge node info.
100
+ */
101
+ export declare const assertMergeNode: <T extends Partial<IMergeNodeInfo> | undefined>(nodeLike: ISegmentInternal | ISegmentPrivate | Partial<IMergeNodeInfo> | T) => asserts nodeLike is IMergeNodeInfo | Exclude<T, Partial<IMergeNodeInfo>>;
102
+ /**
103
+ * Removes the merge node info. This is used to remove nodes from the merge-tree.
104
+ * @param segmentLike - The segment-like object to check.
105
+ * @returns This function will change the type of the provided node like to never via an assertion. This
106
+ * ensures no further usage of the removed merge node info is allowed. if continued use is required other
107
+ * type coercion methods should be used to correctly re-type the variable.
108
+ */
109
+ export declare const removeMergeNodeInfo: (nodeLike: IMergeNodeInfo) => asserts nodeLike is never;
110
+ /**
111
+ * Contains removal information associated to an {@link ISegment}.
112
+ * @legacy
113
+ * @alpha
114
+ * @deprecated - This interface will be removed in 2.20 with no replacement.
115
+ */
116
+ export interface IRemovalInfo {
117
+ /**
118
+ * Local seq at which this segment was removed, if the removal is yet-to-be acked.
119
+ */
120
+ localRemovedSeq?: number;
121
+ /**
122
+ * Seq at which this segment was removed.
123
+ */
124
+ removedSeq: number;
125
+ /**
126
+ * List of client IDs that have removed this segment.
127
+ * The client that actually removed the segment (i.e. whose removal op was sequenced first) is stored as the first
128
+ * client in this list. Other clients in the list have all issued concurrent ops to remove the segment.
129
+ * @remarks When this list has length \> 1, this is referred to as the "overlapping remove" case.
130
+ */
131
+ removedClientIds: number[];
132
+ }
133
+ /**
134
+ * Converts a segment-like object to a removal info object if possible.
135
+ *
136
+ * @param segmentLike - The segment-like object to convert.
137
+ * @returns The removal info object if the conversion is possible, otherwise undefined.
138
+ */
139
+ export declare const toRemovalInfo: (segmentLike: unknown) => IRemovalInfo | undefined;
140
+ /**
141
+ * A type-guard which determines if the segment has removal info, and
142
+ * returns true if it does, along with applying strong typing.
143
+ *
144
+ * @param segmentLike - The segment-like object to check.
145
+ * @returns True if the segment has removal info, otherwise false.
146
+ */
147
+ export declare const isRemoved: (segmentLike: unknown) => segmentLike is IRemovalInfo;
148
+ /**
149
+ * Asserts that the segment has removal info. Usage of this function should not produce a user facing error.
150
+ *
151
+ * @param segmentLike - The segment-like object to check.
152
+ * @throws Will throw an error if the segment does not have removal info.
153
+ */
154
+ export declare const assertRemoved: <T extends Partial<IRemovalInfo> | undefined>(segmentLike: ISegmentInternal | Partial<IRemovalInfo> | T) => asserts segmentLike is IRemovalInfo | Exclude<T, Partial<IRemovalInfo>>;
155
+ /**
156
+ * Removes the removal info. This is used in rollback.
157
+ * @param segmentLike - The segment-like object to check.
158
+ * @returns This function will change the type of the provided node like to never via an assertion. This
159
+ * ensures no further usage of the removed removal info is allowed. if continued use is required other
160
+ * type coercion methods should be use to correctly re-type the variable.
161
+ */
162
+ export declare const removeRemovalInfo: (nodeLike: IRemovalInfo) => asserts nodeLike is never;
163
+ /**
164
+ * Tracks information about when and where this segment was moved to.
165
+ *
166
+ * Note that merge-tree does not currently support moving and only supports
167
+ * obliterate. The fields below include "move" in their names to avoid renaming
168
+ * in the future, when moves _are_ supported.
169
+ * @legacy
170
+ * @alpha
171
+ * @deprecated - This interface will be removed in 2.20 with no replacement.
172
+ */
173
+ export interface IMoveInfo {
174
+ /**
175
+ * Local seq at which this segment was moved if the move is yet-to-be
176
+ * acked.
177
+ */
178
+ localMovedSeq?: number;
179
+ /**
180
+ * The first seq at which this segment was moved.
181
+ */
182
+ movedSeq: number;
183
+ /**
184
+ * All seqs at which this segment was moved. In the case of overlapping,
185
+ * concurrent moves this array will contain multiple seqs.
186
+ *
187
+ * The seq at `movedSeqs[i]` corresponds to the client id at `movedClientIds[i]`.
188
+ *
189
+ * The first element corresponds to the seq of the first move
190
+ */
191
+ movedSeqs: number[];
192
+ /**
193
+ * A reference to the inserted destination segment corresponding to this
194
+ * segment's move.
195
+ *
196
+ * If undefined, the move was an obliterate.
197
+ *
198
+ * Currently this field is unused, as we only support obliterate operations
199
+ */
200
+ moveDst?: ReferencePosition;
201
+ /**
202
+ * List of client IDs that have moved this segment.
203
+ *
204
+ * The client that actually moved the segment (i.e. whose move op was sequenced
205
+ * first) is stored as the first client in this list. Other clients in the
206
+ * list have all issued concurrent ops to move the segment.
207
+ */
208
+ movedClientIds: number[];
209
+ /**
210
+ * If this segment was inserted into a concurrently moved range and
211
+ * the move op was sequenced before the insertion op. In this case,
212
+ * the segment is visible only to the inserting client
213
+ *
214
+ * `wasMovedOnInsert` only applies for acked obliterates. That is, if
215
+ * a segment inserted by a remote client is moved on insertion by a local
216
+ * and unacked obliterate, we do not consider it as having been moved
217
+ * on insert
218
+ *
219
+ * If a segment is moved on insertion, its length is only ever visible to
220
+ * the client that inserted the segment. This is relevant in partial length
221
+ * calculations
222
+ */
223
+ wasMovedOnInsert: boolean;
224
+ }
225
+ export declare const toMoveInfo: (segmentLike: unknown) => IMoveInfo | undefined;
226
+ /**
227
+ * A type-guard which determines if the segment has move info, and
228
+ * returns true if it does, along with applying strong typing.
229
+ *
230
+ * @param segmentLike - The segment-like object to check.
231
+ * @returns True if the segment has move info, otherwise false.
232
+ */
233
+ export declare const isMoved: (segmentLike: unknown) => segmentLike is IMoveInfo;
234
+ /**
235
+ * Asserts that the segment has move info. Usage of this function should not produce a user facing error.
236
+ *
237
+ * @param segmentLike - The segment-like object to check.
238
+ * @throws Will throw an error if the segment does not have move info.
239
+ */
240
+ export declare const assertMoved: <T extends Partial<IMoveInfo> | undefined>(segmentLike: ISegmentInternal | Partial<IMoveInfo> | T) => asserts segmentLike is IMoveInfo | Exclude<T, Partial<IMoveInfo>>;
241
+ /**
242
+ * A union type representing any segment info.
243
+ */
244
+ export type SegmentInfo = IMergeNodeInfo | IInsertionInfo | IMoveInfo | IRemovalInfo;
245
+ /**
246
+ * A type representing a segment with additional info.
247
+ */
248
+ export type SegmentWithInfo<T extends SegmentInfo, S extends ISegmentPrivate = ISegmentPrivate> = S & T;
249
+ /**
250
+ * Overwrites the segment info on a segment-like object.
251
+ *
252
+ * @param segmentLike - The segment-like object to set the info on.
253
+ * @param info - The segment info to overwrite.
254
+ * @returns The segment-like object with the info set.
255
+ */
256
+ export declare const overwriteInfo: <T extends SegmentInfo, S extends ISegmentPrivate = ISegmentPrivate>(segmentLike: S, info: T) => SegmentWithInfo<T, S>;
257
+ //# sourceMappingURL=segmentInfos.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmentInfos.d.ts","sourceRoot":"","sources":["../src/segmentInfos.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,EAAE,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAC1C,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,CAAC,GACL,KAAK,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAE7B;AAED,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,YAAY,EACrE,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,CAAC,GACL,KAAK,IAAI,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,OAAO,IAAI,CAAC,CAAC,CAK/C;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EACjD,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAC7B,KAAK,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAEvB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,gBAAiB,OAAO,KAAG,cAAc,GAAG,SAG3D,CAAC;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,gBAAiB,OAAO,kCACJ,CAAC;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,CAAC,CAAC,SAAS,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,EAC1E,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,KACvD,OAAO,CAAC,WAAW,IAAI,cAAc,GAAG,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAM7E,CAAC;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,MAAM,EAAE,UAAU,CAAC;IAEnB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,aAAc,OAAO,KAAG,cAAc,GAAG,SAKxD,CAAC;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,aAAc,OAAO,+BACT,CAAC;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,CAAC,CAAC,SAAS,OAAO,CAAC,cAAc,CAAC,GAAG,SAAS,EAC3E,QAAQ,EAAE,gBAAgB,GAAG,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,KACtE,OAAO,CAAC,QAAQ,IAAI,cAAc,GAAG,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAM1E,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,OAAO,CAAC,QAAQ,IAAI,KAOjF,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC5B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,gBAAiB,OAAO,KAAG,YAAY,GAAG,SAIvD,CAAC;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,gBAAiB,OAAO,gCACL,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,CAAC,CAAC,SAAS,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,EACvE,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,KACrD,OAAO,CAAC,WAAW,IAAI,YAAY,GAAG,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CACkB,CAAC;AAE9F;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,OAAO,CAAC,QAAQ,IAAI,KAO7E,CAAC;AAEJ;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACzB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAE5B;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IAEzB;;;;;;;;;;;;;OAaG;IACH,gBAAgB,EAAE,OAAO,CAAC;CAC1B;AACD,eAAO,MAAM,UAAU,gBAAiB,OAAO,KAAG,SAAS,GAAG,SAMjD,CAAC;AAEd;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,gBAAiB,OAAO,6BACN,CAAC;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,CAAC,CAAC,SAAS,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,EAClE,WAAW,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,KAClD,OAAO,CAAC,WAAW,IAAI,SAAS,GAAG,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CACmB,CAAC;AAEzF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,GAAG,SAAS,GAAG,YAAY,CAAC;AAErF;;GAEG;AACH,MAAM,MAAM,eAAe,CAC1B,CAAC,SAAS,WAAW,EACrB,CAAC,SAAS,eAAe,GAAG,eAAe,IACxC,CAAC,GAAG,CAAC,CAAC;AAEV;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,oFAIZ,CAAC,QACR,CAAC,KACL,gBAAgB,CAAC,EAAE,CAAC,CAAqC,CAAC"}
@@ -0,0 +1,145 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { assert, isObject } from "@fluidframework/core-utils/internal";
6
+ import { MergeBlock } from "./mergeTreeNodes.js";
7
+ export function propExists(thing, prop) {
8
+ return isObject(thing) && prop in thing;
9
+ }
10
+ export function hasProp(thing, prop, type) {
11
+ return (propExists(thing, prop) &&
12
+ (type === "array" ? Array.isArray(thing[prop]) : typeof thing[prop] === type));
13
+ }
14
+ export function propInstanceOf(thing, prop, type) {
15
+ return propExists(thing, prop) && thing[prop] instanceof type;
16
+ }
17
+ /**
18
+ * Converts a segment-like object to an insertion info object if possible.
19
+ *
20
+ * @param segmentLike - The segment-like object to convert.
21
+ * @returns The insertion info object if the conversion is possible, otherwise undefined.
22
+ */
23
+ export const toInsertionInfo = (segmentLike) => hasProp(segmentLike, "clientId", "number") && hasProp(segmentLike, "seq", "number")
24
+ ? segmentLike
25
+ : undefined;
26
+ /**
27
+ * A type-guard which determines if the segment has insertion info, and
28
+ * returns true if it does, along with applying strong typing.
29
+ *
30
+ * @param segmentLike - The segment-like object to check.
31
+ * @returns True if the segment has insertion info, otherwise false.
32
+ */
33
+ export const isInserted = (segmentLike) => toInsertionInfo(segmentLike) !== undefined;
34
+ /**
35
+ * Asserts that the segment has insertion info. Usage of this function should not produce a user facing error.
36
+ *
37
+ * @param segmentLike - The segment-like object to check.
38
+ * @throws Will throw an error if the segment does not have insertion info.
39
+ */
40
+ export const assertInserted = (segmentLike) => assert(segmentLike === undefined || isInserted(segmentLike), 0xaa0 /* must be insertionInfo */);
41
+ /**
42
+ * Converts a segment-like object to a merge node info object if possible.
43
+ *
44
+ * @param segmentLike - The segment-like object to convert.
45
+ * @returns The merge node info object if the conversion is possible, otherwise undefined.
46
+ */
47
+ export const toMergeNodeInfo = (nodeLike) => propInstanceOf(nodeLike, "parent", MergeBlock) &&
48
+ hasProp(nodeLike, "ordinal", "string") &&
49
+ hasProp(nodeLike, "index", "number")
50
+ ? nodeLike
51
+ : undefined;
52
+ /**
53
+ * A type-guard which determines if the segment has merge node info, and
54
+ * returns true if it does, along with applying strong typing.
55
+ *
56
+ * @param nodeLike - The segment-like object to check.
57
+ * @returns True if the segment has merge node info, otherwise false.
58
+ */
59
+ export const isMergeNodeInfo = (nodeLike) => toMergeNodeInfo(nodeLike) !== undefined;
60
+ /**
61
+ * Asserts that the segment has merge node info. Usage of this function should not produce a user facing error.
62
+ *
63
+ * @param segmentLike - The segment-like object to check.
64
+ * @throws Will throw an error if the segment does not have merge node info.
65
+ */
66
+ export const assertMergeNode = (segmentLike) => assert(segmentLike === undefined || isMergeNodeInfo(segmentLike), 0xaa1 /* must be MergeNodeInfo */);
67
+ /**
68
+ * Removes the merge node info. This is used to remove nodes from the merge-tree.
69
+ * @param segmentLike - The segment-like object to check.
70
+ * @returns This function will change the type of the provided node like to never via an assertion. This
71
+ * ensures no further usage of the removed merge node info is allowed. if continued use is required other
72
+ * type coercion methods should be used to correctly re-type the variable.
73
+ */
74
+ export const removeMergeNodeInfo = (nodeLike) => Object.assign(nodeLike, {
75
+ parent: undefined,
76
+ index: undefined,
77
+ ordinal: undefined,
78
+ });
79
+ /**
80
+ * Converts a segment-like object to a removal info object if possible.
81
+ *
82
+ * @param segmentLike - The segment-like object to convert.
83
+ * @returns The removal info object if the conversion is possible, otherwise undefined.
84
+ */
85
+ export const toRemovalInfo = (segmentLike) => hasProp(segmentLike, "removedClientIds", "array") &&
86
+ hasProp(segmentLike, "removedSeq", "number")
87
+ ? segmentLike
88
+ : undefined;
89
+ /**
90
+ * A type-guard which determines if the segment has removal info, and
91
+ * returns true if it does, along with applying strong typing.
92
+ *
93
+ * @param segmentLike - The segment-like object to check.
94
+ * @returns True if the segment has removal info, otherwise false.
95
+ */
96
+ export const isRemoved = (segmentLike) => toRemovalInfo(segmentLike) !== undefined;
97
+ /**
98
+ * Asserts that the segment has removal info. Usage of this function should not produce a user facing error.
99
+ *
100
+ * @param segmentLike - The segment-like object to check.
101
+ * @throws Will throw an error if the segment does not have removal info.
102
+ */
103
+ export const assertRemoved = (segmentLike) => assert(segmentLike === undefined || isRemoved(segmentLike), 0xaa2 /* must be removalInfo */);
104
+ /**
105
+ * Removes the removal info. This is used in rollback.
106
+ * @param segmentLike - The segment-like object to check.
107
+ * @returns This function will change the type of the provided node like to never via an assertion. This
108
+ * ensures no further usage of the removed removal info is allowed. if continued use is required other
109
+ * type coercion methods should be use to correctly re-type the variable.
110
+ */
111
+ export const removeRemovalInfo = (nodeLike) => Object.assign(nodeLike, {
112
+ localRemovedSeq: undefined,
113
+ removedClientIds: undefined,
114
+ removedSeq: undefined,
115
+ });
116
+ export const toMoveInfo = (segmentLike) => hasProp(segmentLike, "movedClientIds", "array") &&
117
+ hasProp(segmentLike, "movedSeq", "number") &&
118
+ hasProp(segmentLike, "movedSeqs", "array") &&
119
+ hasProp(segmentLike, "wasMovedOnInsert", "boolean")
120
+ ? segmentLike
121
+ : undefined;
122
+ /**
123
+ * A type-guard which determines if the segment has move info, and
124
+ * returns true if it does, along with applying strong typing.
125
+ *
126
+ * @param segmentLike - The segment-like object to check.
127
+ * @returns True if the segment has move info, otherwise false.
128
+ */
129
+ export const isMoved = (segmentLike) => toMoveInfo(segmentLike) !== undefined;
130
+ /**
131
+ * Asserts that the segment has move info. Usage of this function should not produce a user facing error.
132
+ *
133
+ * @param segmentLike - The segment-like object to check.
134
+ * @throws Will throw an error if the segment does not have move info.
135
+ */
136
+ export const assertMoved = (segmentLike) => assert(segmentLike === undefined || isMoved(segmentLike), 0xaa3 /* must be moveInfo */);
137
+ /**
138
+ * Overwrites the segment info on a segment-like object.
139
+ *
140
+ * @param segmentLike - The segment-like object to set the info on.
141
+ * @param info - The segment info to overwrite.
142
+ * @returns The segment-like object with the info set.
143
+ */
144
+ export const overwriteInfo = (segmentLike, info) => Object.assign(segmentLike, info);
145
+ //# sourceMappingURL=segmentInfos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmentInfos.js","sourceRoot":"","sources":["../src/segmentInfos.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 { assert, isObject } from \"@fluidframework/core-utils/internal\";\n\nimport { ISegmentInternal, ISegmentPrivate, MergeBlock } from \"./mergeTreeNodes.js\";\nimport type { ReferencePosition } from \"./referencePositions.js\";\n\nexport interface StringToType {\n\t\"string\": string;\n\t\"number\": number;\n\t\"object\": object;\n\t\"array\": [];\n\t\"boolean\": boolean;\n}\n\nexport function propExists<P extends string>(\n\tthing: unknown,\n\tprop: P,\n): thing is Record<P, unknown> {\n\treturn isObject(thing) && prop in thing;\n}\n\nexport function hasProp<P extends string, T extends keyof StringToType>(\n\tthing: unknown,\n\tprop: P,\n\ttype: T,\n): thing is Record<P, StringToType[typeof type]> {\n\treturn (\n\t\tpropExists(thing, prop) &&\n\t\t(type === \"array\" ? Array.isArray(thing[prop]) : typeof thing[prop] === type)\n\t);\n}\n\nexport function propInstanceOf<P extends string, T>(\n\tthing: unknown,\n\tprop: P,\n\ttype: new (...args: any[]) => T,\n): thing is Record<P, T> {\n\treturn propExists(thing, prop) && thing[prop] instanceof type;\n}\n\n/**\n * Contains insertion information associated to an {@link ISegment}.\n */\nexport interface IInsertionInfo {\n\t/**\n\t * Short clientId for the client that inserted this segment.\n\t */\n\tclientId: number;\n\t/**\n\t * Local seq at which this segment was inserted.\n\t * This is defined if and only if the insertion of the segment is pending ack, i.e. `seq` is UnassignedSequenceNumber.\n\t * Once the segment is acked, this field is cleared.\n\t *\n\t * @privateRemarks\n\t * See {@link CollaborationWindow.localSeq} for more information on the semantics of localSeq.\n\t */\n\tlocalSeq?: number;\n\t/**\n\t * Seq at which this segment was inserted.\n\t * If undefined, it is assumed the segment was inserted prior to the collab window's minimum sequence number.\n\t */\n\tseq: number;\n}\n\n/**\n * Converts a segment-like object to an insertion info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The insertion info object if the conversion is possible, otherwise undefined.\n */\nexport const toInsertionInfo = (segmentLike: unknown): IInsertionInfo | undefined =>\n\thasProp(segmentLike, \"clientId\", \"number\") && hasProp(segmentLike, \"seq\", \"number\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has insertion info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has insertion info, otherwise false.\n */\nexport const isInserted = (segmentLike: unknown): segmentLike is IInsertionInfo =>\n\ttoInsertionInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has insertion info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have insertion info.\n */\nexport const assertInserted: <T extends Partial<IInsertionInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IInsertionInfo> | T,\n) => asserts segmentLike is IInsertionInfo | Exclude<T, Partial<IInsertionInfo>> = (\n\tsegmentLike,\n) =>\n\tassert(\n\t\tsegmentLike === undefined || isInserted(segmentLike),\n\t\t0xaa0 /* must be insertionInfo */,\n\t);\n\n/**\n * Common properties for a node in a merge tree.\n */\nexport interface IMergeNodeInfo {\n\t/**\n\t * The parent merge block if the node is parented\n\t */\n\tparent: MergeBlock;\n\n\t/**\n\t * The index of this node in its parent's list of children.\n\t */\n\tindex: number;\n\n\t/**\n\t * A string that can be used for comparing the location of this node to other `MergeNode`s in the same tree.\n\t * `a.ordinal < b.ordinal` if and only if `a` comes before `b` in a pre-order traversal of the tree.\n\t */\n\tordinal: string;\n}\n\n/**\n * Converts a segment-like object to a merge node info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The merge node info object if the conversion is possible, otherwise undefined.\n */\nexport const toMergeNodeInfo = (nodeLike: unknown): IMergeNodeInfo | undefined =>\n\tpropInstanceOf(nodeLike, \"parent\", MergeBlock) &&\n\thasProp(nodeLike, \"ordinal\", \"string\") &&\n\thasProp(nodeLike, \"index\", \"number\")\n\t\t? nodeLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has merge node info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param nodeLike - The segment-like object to check.\n * @returns True if the segment has merge node info, otherwise false.\n */\nexport const isMergeNodeInfo = (nodeLike: unknown): nodeLike is IMergeNodeInfo =>\n\ttoMergeNodeInfo(nodeLike) !== undefined;\n\n/**\n * Asserts that the segment has merge node info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have merge node info.\n */\nexport const assertMergeNode: <T extends Partial<IMergeNodeInfo> | undefined>(\n\tnodeLike: ISegmentInternal | ISegmentPrivate | Partial<IMergeNodeInfo> | T,\n) => asserts nodeLike is IMergeNodeInfo | Exclude<T, Partial<IMergeNodeInfo>> = (\n\tsegmentLike,\n) =>\n\tassert(\n\t\tsegmentLike === undefined || isMergeNodeInfo(segmentLike),\n\t\t0xaa1 /* must be MergeNodeInfo */,\n\t);\n\n/**\n * Removes the merge node info. This is used to remove nodes from the merge-tree.\n * @param segmentLike - The segment-like object to check.\n * @returns This function will change the type of the provided node like to never via an assertion. This\n * ensures no further usage of the removed merge node info is allowed. if continued use is required other\n * type coercion methods should be used to correctly re-type the variable.\n */\nexport const removeMergeNodeInfo: (nodeLike: IMergeNodeInfo) => asserts nodeLike is never = (\n\tnodeLike,\n) =>\n\tObject.assign<IMergeNodeInfo, Record<keyof IMergeNodeInfo, undefined>>(nodeLike, {\n\t\tparent: undefined,\n\t\tindex: undefined,\n\t\tordinal: undefined,\n\t});\n\n/**\n * Contains removal information associated to an {@link ISegment}.\n * @legacy\n * @alpha\n * @deprecated - This interface will be removed in 2.20 with no replacement.\n */\nexport interface IRemovalInfo {\n\t/**\n\t * Local seq at which this segment was removed, if the removal is yet-to-be acked.\n\t */\n\tlocalRemovedSeq?: number;\n\t/**\n\t * Seq at which this segment was removed.\n\t */\n\tremovedSeq: number;\n\t/**\n\t * List of client IDs that have removed this segment.\n\t * The client that actually removed the segment (i.e. whose removal op was sequenced first) is stored as the first\n\t * client in this list. Other clients in the list have all issued concurrent ops to remove the segment.\n\t * @remarks When this list has length \\> 1, this is referred to as the \"overlapping remove\" case.\n\t */\n\tremovedClientIds: number[];\n}\n\n/**\n * Converts a segment-like object to a removal info object if possible.\n *\n * @param segmentLike - The segment-like object to convert.\n * @returns The removal info object if the conversion is possible, otherwise undefined.\n */\nexport const toRemovalInfo = (segmentLike: unknown): IRemovalInfo | undefined =>\n\thasProp(segmentLike, \"removedClientIds\", \"array\") &&\n\thasProp(segmentLike, \"removedSeq\", \"number\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has removal info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has removal info, otherwise false.\n */\nexport const isRemoved = (segmentLike: unknown): segmentLike is IRemovalInfo =>\n\ttoRemovalInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has removal info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have removal info.\n */\nexport const assertRemoved: <T extends Partial<IRemovalInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IRemovalInfo> | T,\n) => asserts segmentLike is IRemovalInfo | Exclude<T, Partial<IRemovalInfo>> = (segmentLike) =>\n\tassert(segmentLike === undefined || isRemoved(segmentLike), 0xaa2 /* must be removalInfo */);\n\n/**\n * Removes the removal info. This is used in rollback.\n * @param segmentLike - The segment-like object to check.\n * @returns This function will change the type of the provided node like to never via an assertion. This\n * ensures no further usage of the removed removal info is allowed. if continued use is required other\n * type coercion methods should be use to correctly re-type the variable.\n */\nexport const removeRemovalInfo: (nodeLike: IRemovalInfo) => asserts nodeLike is never = (\n\tnodeLike,\n) =>\n\tObject.assign<IRemovalInfo, Record<keyof IRemovalInfo, undefined>>(nodeLike, {\n\t\tlocalRemovedSeq: undefined,\n\t\tremovedClientIds: undefined,\n\t\tremovedSeq: undefined,\n\t});\n\n/**\n * Tracks information about when and where this segment was moved to.\n *\n * Note that merge-tree does not currently support moving and only supports\n * obliterate. The fields below include \"move\" in their names to avoid renaming\n * in the future, when moves _are_ supported.\n * @legacy\n * @alpha\n * @deprecated - This interface will be removed in 2.20 with no replacement.\n */\nexport interface IMoveInfo {\n\t/**\n\t * Local seq at which this segment was moved if the move is yet-to-be\n\t * acked.\n\t */\n\tlocalMovedSeq?: number;\n\n\t/**\n\t * The first seq at which this segment was moved.\n\t */\n\tmovedSeq: number;\n\n\t/**\n\t * All seqs at which this segment was moved. In the case of overlapping,\n\t * concurrent moves this array will contain multiple seqs.\n\t *\n\t * The seq at `movedSeqs[i]` corresponds to the client id at `movedClientIds[i]`.\n\t *\n\t * The first element corresponds to the seq of the first move\n\t */\n\tmovedSeqs: number[];\n\n\t/**\n\t * A reference to the inserted destination segment corresponding to this\n\t * segment's move.\n\t *\n\t * If undefined, the move was an obliterate.\n\t *\n\t * Currently this field is unused, as we only support obliterate operations\n\t */\n\tmoveDst?: ReferencePosition;\n\n\t/**\n\t * List of client IDs that have moved this segment.\n\t *\n\t * The client that actually moved the segment (i.e. whose move op was sequenced\n\t * first) is stored as the first client in this list. Other clients in the\n\t * list have all issued concurrent ops to move the segment.\n\t */\n\tmovedClientIds: number[];\n\n\t/**\n\t * If this segment was inserted into a concurrently moved range and\n\t * the move op was sequenced before the insertion op. In this case,\n\t * the segment is visible only to the inserting client\n\t *\n\t * `wasMovedOnInsert` only applies for acked obliterates. That is, if\n\t * a segment inserted by a remote client is moved on insertion by a local\n\t * and unacked obliterate, we do not consider it as having been moved\n\t * on insert\n\t *\n\t * If a segment is moved on insertion, its length is only ever visible to\n\t * the client that inserted the segment. This is relevant in partial length\n\t * calculations\n\t */\n\twasMovedOnInsert: boolean;\n}\nexport const toMoveInfo = (segmentLike: unknown): IMoveInfo | undefined =>\n\thasProp(segmentLike, \"movedClientIds\", \"array\") &&\n\thasProp(segmentLike, \"movedSeq\", \"number\") &&\n\thasProp(segmentLike, \"movedSeqs\", \"array\") &&\n\thasProp(segmentLike, \"wasMovedOnInsert\", \"boolean\")\n\t\t? segmentLike\n\t\t: undefined;\n\n/**\n * A type-guard which determines if the segment has move info, and\n * returns true if it does, along with applying strong typing.\n *\n * @param segmentLike - The segment-like object to check.\n * @returns True if the segment has move info, otherwise false.\n */\nexport const isMoved = (segmentLike: unknown): segmentLike is IMoveInfo =>\n\ttoMoveInfo(segmentLike) !== undefined;\n\n/**\n * Asserts that the segment has move info. Usage of this function should not produce a user facing error.\n *\n * @param segmentLike - The segment-like object to check.\n * @throws Will throw an error if the segment does not have move info.\n */\nexport const assertMoved: <T extends Partial<IMoveInfo> | undefined>(\n\tsegmentLike: ISegmentInternal | Partial<IMoveInfo> | T,\n) => asserts segmentLike is IMoveInfo | Exclude<T, Partial<IMoveInfo>> = (segmentLike) =>\n\tassert(segmentLike === undefined || isMoved(segmentLike), 0xaa3 /* must be moveInfo */);\n\n/**\n * A union type representing any segment info.\n */\nexport type SegmentInfo = IMergeNodeInfo | IInsertionInfo | IMoveInfo | IRemovalInfo;\n\n/**\n * A type representing a segment with additional info.\n */\nexport type SegmentWithInfo<\n\tT extends SegmentInfo,\n\tS extends ISegmentPrivate = ISegmentPrivate,\n> = S & T;\n\n/**\n * Overwrites the segment info on a segment-like object.\n *\n * @param segmentLike - The segment-like object to set the info on.\n * @param info - The segment info to overwrite.\n * @returns The segment-like object with the info set.\n */\nexport const overwriteInfo = <\n\tT extends SegmentInfo,\n\tS extends ISegmentPrivate = ISegmentPrivate,\n>(\n\tsegmentLike: S,\n\tinfo: T,\n): SegmentWithInfo<T, S> => Object.assign(segmentLike, info);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"snapshotLoader.d.ts","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,EACN,mBAAmB,EAGnB,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAW3C,qBAAa,cAAc;IAIzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAG3B,OAAO,EAAE,sBAAsB,EAE/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACrC,MAAM,EAAE,mBAAmB,EACV,UAAU,EAAE,gBAAgB;IAKjC,UAAU,CACtB,QAAQ,EAAE,sBAAsB,GAC9B,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAA;KAAE,CAAC;YAiBnD,qBAAqB;IA2BnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAwD5B;IAEF,OAAO,CAAC,UAAU;YAsCJ,QAAQ;IA0FtB,OAAO,CAAC,kBAAkB;IAsB1B;;;;;OAKG;YACW,cAAc;CAQ5B"}
1
+ {"version":3,"file":"snapshotLoader.d.ts","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,EACN,mBAAmB,EAGnB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAoB3C,qBAAa,cAAc;IAIzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAG3B,OAAO,EAAE,sBAAsB,EAE/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACrC,MAAM,EAAE,mBAAmB,EACV,UAAU,EAAE,gBAAgB;IAKjC,UAAU,CACtB,QAAQ,EAAE,sBAAsB,GAC9B,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAA;KAAE,CAAC;YAiBnD,qBAAqB;IA2BnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAqD5B;IAEF,OAAO,CAAC,UAAU;YAsCJ,QAAQ;IAwFtB,OAAO,CAAC,kBAAkB;IAsB1B;;;;;OAKG;YACW,cAAc;CAQ5B"}
@@ -8,62 +8,57 @@ import { AttachState } from "@fluidframework/container-definitions";
8
8
  import { assert } from "@fluidframework/core-utils/internal";
9
9
  import { UsageError, createChildLogger, } from "@fluidframework/telemetry-utils/internal";
10
10
  import { NonCollabClient, UniversalSequenceNumber } from "./constants.js";
11
+ import { overwriteInfo, } from "./segmentInfos.js";
11
12
  import { hasMergeInfo, } from "./snapshotChunks.js";
12
13
  import { SnapshotV1 } from "./snapshotV1.js";
13
14
  import { SnapshotLegacy } from "./snapshotlegacy.js";
14
15
  export class SnapshotLoader {
15
- constructor(runtime,
16
- // eslint-disable-next-line import/no-deprecated
17
- client, mergeTree, logger, serializer) {
16
+ constructor(runtime, client, mergeTree, logger, serializer) {
18
17
  this.runtime = runtime;
19
18
  this.client = client;
20
19
  this.mergeTree = mergeTree;
21
20
  this.serializer = serializer;
22
21
  this.specToSegment = (spec) => {
23
- let seg;
24
22
  if (hasMergeInfo(spec)) {
25
- seg = this.client.specToSegment(spec.json);
26
- // `specToSegment()` initializes `seg` with the LocalClientId. Overwrite this with
27
- // the `spec` client (if specified). Otherwise overwrite with `NonCollabClient`.
28
- seg.clientId =
29
- spec.client === undefined
23
+ const seg = overwriteInfo(this.client.specToSegment(spec.json), {
24
+ clientId: spec.client === undefined
30
25
  ? NonCollabClient
31
- : this.client.getOrAddShortClientId(spec.client);
32
- seg.seq = spec.seq ?? UniversalSequenceNumber;
26
+ : this.client.getOrAddShortClientId(spec.client),
27
+ seq: spec.seq ?? UniversalSequenceNumber,
28
+ });
33
29
  if (spec.removedSeq !== undefined) {
34
- seg.removedSeq = spec.removedSeq;
30
+ // this format had a bug where it didn't store all the overlap clients
31
+ // this is for back compat, so we change the singular id to an array
32
+ // this will only cause problems if there is an overlapping delete
33
+ // spanning the snapshot, which should be rare
34
+ const specAsBuggyFormat = spec;
35
+ if (specAsBuggyFormat.removedClient !== undefined) {
36
+ spec.removedClientIds ?? (spec.removedClientIds = [specAsBuggyFormat.removedClient]);
37
+ }
38
+ assert(spec.removedClientIds !== undefined, 0xaa4 /* must have removedClient ids */);
39
+ // eslint-disable-next-line import/no-deprecated
40
+ overwriteInfo(seg, {
41
+ removedSeq: spec.removedSeq,
42
+ removedClientIds: spec.removedClientIds.map((id) => this.client.getOrAddShortClientId(id)),
43
+ });
35
44
  }
36
45
  if (spec.movedSeq !== undefined) {
37
- seg.movedSeq = spec.movedSeq;
46
+ assert(spec.movedClientIds !== undefined && spec.movedSeqs !== undefined, 0xaa5 /* must have movedIds ids */);
47
+ // eslint-disable-next-line import/no-deprecated
48
+ overwriteInfo(seg, {
49
+ movedSeq: spec.movedSeq,
50
+ movedSeqs: spec.movedSeqs,
51
+ movedClientIds: spec.movedClientIds.map((id) => this.client.getOrAddShortClientId(id)),
52
+ // BUG? This isn't persisted
53
+ wasMovedOnInsert: false,
54
+ });
38
55
  }
39
- if (spec.movedSeqs !== undefined) {
40
- seg.movedSeqs = spec.movedSeqs;
41
- }
42
- // this format had a bug where it didn't store all the overlap clients
43
- // this is for back compat, so we change the singular id to an array
44
- // this will only cause problems if there is an overlapping delete
45
- // spanning the snapshot, which should be rare
46
- const specAsBuggyFormat = spec;
47
- if (specAsBuggyFormat.removedClient !== undefined) {
48
- seg.removedClientIds = [
49
- this.client.getOrAddShortClientId(specAsBuggyFormat.removedClient),
50
- ];
51
- }
52
- if (spec.removedClientIds !== undefined) {
53
- seg.removedClientIds = spec.removedClientIds?.map((sid) => this.client.getOrAddShortClientId(sid));
54
- }
55
- if (spec.movedClientIds !== undefined) {
56
- seg.movedClientIds = spec.movedClientIds?.map((sid) => this.client.getOrAddShortClientId(sid));
57
- }
58
- }
59
- else {
60
- seg = this.client.specToSegment(spec);
61
- seg.seq = UniversalSequenceNumber;
62
- // `specToSegment()` initializes `seg` with the LocalClientId. We must overwrite this with
63
- // `NonCollabClient`.
64
- seg.clientId = NonCollabClient;
56
+ return seg;
65
57
  }
66
- return seg;
58
+ return overwriteInfo(this.client.specToSegment(spec), {
59
+ seq: UniversalSequenceNumber,
60
+ clientId: NonCollabClient,
61
+ });
67
62
  };
68
63
  this.logger = createChildLogger({ logger, namespace: "SnapshotLoader" });
69
64
  }
@@ -159,16 +154,15 @@ export class SnapshotLoader {
159
154
  }
160
155
  };
161
156
  for (const seg of segs) {
162
- const cli = seg.clientId;
163
- const seq = seg.seq;
157
+ const { clientId, seq } = seg;
164
158
  // If the segment can be batch inserted, add it to the 'batch' array. Otherwise, flush
165
159
  // any batched segments and then insert the current segment individually.
166
- if (cli === NonCollabClient && seq === UniversalSequenceNumber) {
160
+ if (clientId === NonCollabClient && seq === UniversalSequenceNumber) {
167
161
  batch.push(seg);
168
162
  }
169
163
  else {
170
164
  flushBatch();
171
- append([seg], cli, seq);
165
+ append([seg], clientId, seq);
172
166
  }
173
167
  }
174
168
  flushBatch();