@fluidframework/odsp-driver 1.2.7 → 2.0.0-dev.1.3.0.96595

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 (254) hide show
  1. package/.mocharc.js +12 -0
  2. package/README.md +19 -0
  3. package/dist/ReadBufferUtils.d.ts.map +1 -1
  4. package/dist/ReadBufferUtils.js +1 -0
  5. package/dist/ReadBufferUtils.js.map +1 -1
  6. package/dist/WriteBufferUtils.d.ts +3 -5
  7. package/dist/WriteBufferUtils.d.ts.map +1 -1
  8. package/dist/WriteBufferUtils.js +59 -55
  9. package/dist/WriteBufferUtils.js.map +1 -1
  10. package/dist/compactSnapshotParser.d.ts +2 -2
  11. package/dist/compactSnapshotParser.d.ts.map +1 -1
  12. package/dist/compactSnapshotParser.js +91 -34
  13. package/dist/compactSnapshotParser.js.map +1 -1
  14. package/dist/compactSnapshotWriter.d.ts +1 -2
  15. package/dist/compactSnapshotWriter.d.ts.map +1 -1
  16. package/dist/compactSnapshotWriter.js +17 -14
  17. package/dist/compactSnapshotWriter.js.map +1 -1
  18. package/dist/contracts.d.ts +1 -18
  19. package/dist/contracts.d.ts.map +1 -1
  20. package/dist/contracts.js.map +1 -1
  21. package/dist/createFile.d.ts +1 -1
  22. package/dist/createFile.d.ts.map +1 -1
  23. package/dist/createFile.js +53 -16
  24. package/dist/createFile.js.map +1 -1
  25. package/dist/createNewUtils.d.ts.map +1 -1
  26. package/dist/createNewUtils.js +0 -1
  27. package/dist/createNewUtils.js.map +1 -1
  28. package/dist/createOdspCreateContainerRequest.d.ts +4 -3
  29. package/dist/createOdspCreateContainerRequest.d.ts.map +1 -1
  30. package/dist/createOdspCreateContainerRequest.js +6 -3
  31. package/dist/createOdspCreateContainerRequest.js.map +1 -1
  32. package/dist/epochTracker.d.ts +1 -0
  33. package/dist/epochTracker.d.ts.map +1 -1
  34. package/dist/epochTracker.js +24 -5
  35. package/dist/epochTracker.js.map +1 -1
  36. package/dist/fetchSnapshot.d.ts +1 -2
  37. package/dist/fetchSnapshot.d.ts.map +1 -1
  38. package/dist/fetchSnapshot.js +22 -27
  39. package/dist/fetchSnapshot.js.map +1 -1
  40. package/dist/getFileLink.d.ts +3 -6
  41. package/dist/getFileLink.d.ts.map +1 -1
  42. package/dist/getFileLink.js +22 -33
  43. package/dist/getFileLink.js.map +1 -1
  44. package/dist/index.d.ts +1 -2
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +3 -3
  47. package/dist/index.js.map +1 -1
  48. package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
  49. package/dist/localOdspDriver/localOdspDocumentStorageManager.js +1 -2
  50. package/dist/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
  51. package/dist/odspDeltaStorageService.d.ts +3 -2
  52. package/dist/odspDeltaStorageService.d.ts.map +1 -1
  53. package/dist/odspDeltaStorageService.js +9 -12
  54. package/dist/odspDeltaStorageService.js.map +1 -1
  55. package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
  56. package/dist/odspDocumentDeltaConnection.js +3 -6
  57. package/dist/odspDocumentDeltaConnection.js.map +1 -1
  58. package/dist/odspDocumentService.d.ts +1 -0
  59. package/dist/odspDocumentService.d.ts.map +1 -1
  60. package/dist/odspDocumentService.js +12 -6
  61. package/dist/odspDocumentService.js.map +1 -1
  62. package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  63. package/dist/odspDocumentServiceFactoryCore.js +29 -6
  64. package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
  65. package/dist/odspDocumentStorageManager.d.ts +4 -4
  66. package/dist/odspDocumentStorageManager.d.ts.map +1 -1
  67. package/dist/odspDocumentStorageManager.js +82 -64
  68. package/dist/odspDocumentStorageManager.js.map +1 -1
  69. package/dist/odspDocumentStorageServiceBase.d.ts +1 -1
  70. package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
  71. package/dist/odspDocumentStorageServiceBase.js +4 -2
  72. package/dist/odspDocumentStorageServiceBase.js.map +1 -1
  73. package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
  74. package/dist/odspDriverUrlResolverForShareLink.js +4 -4
  75. package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
  76. package/dist/odspFluidFileLink.js +1 -1
  77. package/dist/odspFluidFileLink.js.map +1 -1
  78. package/dist/odspLocationRedirection.d.ts +14 -0
  79. package/dist/odspLocationRedirection.d.ts.map +1 -0
  80. package/dist/odspLocationRedirection.js +24 -0
  81. package/dist/odspLocationRedirection.js.map +1 -0
  82. package/dist/odspSnapshotParser.d.ts.map +1 -1
  83. package/dist/odspSnapshotParser.js +1 -2
  84. package/dist/odspSnapshotParser.js.map +1 -1
  85. package/dist/odspSummaryUploadManager.d.ts +6 -3
  86. package/dist/odspSummaryUploadManager.d.ts.map +1 -1
  87. package/dist/odspSummaryUploadManager.js +14 -17
  88. package/dist/odspSummaryUploadManager.js.map +1 -1
  89. package/dist/odspUrlHelper.js +2 -1
  90. package/dist/odspUrlHelper.js.map +1 -1
  91. package/dist/odspUtils.d.ts +11 -2
  92. package/dist/odspUtils.d.ts.map +1 -1
  93. package/dist/odspUtils.js +32 -5
  94. package/dist/odspUtils.js.map +1 -1
  95. package/dist/opsCaching.d.ts.map +1 -1
  96. package/dist/opsCaching.js +3 -2
  97. package/dist/opsCaching.js.map +1 -1
  98. package/dist/packageVersion.d.ts +1 -1
  99. package/dist/packageVersion.d.ts.map +1 -1
  100. package/dist/packageVersion.js +1 -1
  101. package/dist/packageVersion.js.map +1 -1
  102. package/dist/prefetchLatestSnapshot.d.ts +6 -4
  103. package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
  104. package/dist/prefetchLatestSnapshot.js +6 -4
  105. package/dist/prefetchLatestSnapshot.js.map +1 -1
  106. package/dist/retryUtils.d.ts.map +1 -1
  107. package/dist/retryUtils.js +8 -4
  108. package/dist/retryUtils.js.map +1 -1
  109. package/dist/zipItDataRepresentationUtils.d.ts +30 -18
  110. package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
  111. package/dist/zipItDataRepresentationUtils.js +170 -76
  112. package/dist/zipItDataRepresentationUtils.js.map +1 -1
  113. package/lib/ReadBufferUtils.d.ts.map +1 -1
  114. package/lib/ReadBufferUtils.js +1 -0
  115. package/lib/ReadBufferUtils.js.map +1 -1
  116. package/lib/WriteBufferUtils.d.ts +3 -5
  117. package/lib/WriteBufferUtils.d.ts.map +1 -1
  118. package/lib/WriteBufferUtils.js +61 -57
  119. package/lib/WriteBufferUtils.js.map +1 -1
  120. package/lib/compactSnapshotParser.d.ts +2 -2
  121. package/lib/compactSnapshotParser.d.ts.map +1 -1
  122. package/lib/compactSnapshotParser.js +92 -35
  123. package/lib/compactSnapshotParser.js.map +1 -1
  124. package/lib/compactSnapshotWriter.d.ts +1 -2
  125. package/lib/compactSnapshotWriter.d.ts.map +1 -1
  126. package/lib/compactSnapshotWriter.js +18 -15
  127. package/lib/compactSnapshotWriter.js.map +1 -1
  128. package/lib/contracts.d.ts +1 -18
  129. package/lib/contracts.d.ts.map +1 -1
  130. package/lib/contracts.js.map +1 -1
  131. package/lib/createFile.d.ts +1 -1
  132. package/lib/createFile.d.ts.map +1 -1
  133. package/lib/createFile.js +54 -17
  134. package/lib/createFile.js.map +1 -1
  135. package/lib/createNewUtils.d.ts.map +1 -1
  136. package/lib/createNewUtils.js +0 -1
  137. package/lib/createNewUtils.js.map +1 -1
  138. package/lib/createOdspCreateContainerRequest.d.ts +4 -3
  139. package/lib/createOdspCreateContainerRequest.d.ts.map +1 -1
  140. package/lib/createOdspCreateContainerRequest.js +6 -3
  141. package/lib/createOdspCreateContainerRequest.js.map +1 -1
  142. package/lib/epochTracker.d.ts +1 -0
  143. package/lib/epochTracker.d.ts.map +1 -1
  144. package/lib/epochTracker.js +26 -7
  145. package/lib/epochTracker.js.map +1 -1
  146. package/lib/fetchSnapshot.d.ts +1 -2
  147. package/lib/fetchSnapshot.d.ts.map +1 -1
  148. package/lib/fetchSnapshot.js +22 -27
  149. package/lib/fetchSnapshot.js.map +1 -1
  150. package/lib/getFileLink.d.ts +3 -6
  151. package/lib/getFileLink.d.ts.map +1 -1
  152. package/lib/getFileLink.js +24 -35
  153. package/lib/getFileLink.js.map +1 -1
  154. package/lib/index.d.ts +1 -2
  155. package/lib/index.d.ts.map +1 -1
  156. package/lib/index.js +1 -3
  157. package/lib/index.js.map +1 -1
  158. package/lib/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
  159. package/lib/localOdspDriver/localOdspDocumentStorageManager.js +1 -2
  160. package/lib/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
  161. package/lib/odspDeltaStorageService.d.ts +3 -2
  162. package/lib/odspDeltaStorageService.d.ts.map +1 -1
  163. package/lib/odspDeltaStorageService.js +9 -12
  164. package/lib/odspDeltaStorageService.js.map +1 -1
  165. package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
  166. package/lib/odspDocumentDeltaConnection.js +3 -6
  167. package/lib/odspDocumentDeltaConnection.js.map +1 -1
  168. package/lib/odspDocumentService.d.ts +1 -0
  169. package/lib/odspDocumentService.d.ts.map +1 -1
  170. package/lib/odspDocumentService.js +14 -8
  171. package/lib/odspDocumentService.js.map +1 -1
  172. package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
  173. package/lib/odspDocumentServiceFactoryCore.js +29 -6
  174. package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
  175. package/lib/odspDocumentStorageManager.d.ts +4 -4
  176. package/lib/odspDocumentStorageManager.d.ts.map +1 -1
  177. package/lib/odspDocumentStorageManager.js +83 -65
  178. package/lib/odspDocumentStorageManager.js.map +1 -1
  179. package/lib/odspDocumentStorageServiceBase.d.ts +1 -1
  180. package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -1
  181. package/lib/odspDocumentStorageServiceBase.js +4 -2
  182. package/lib/odspDocumentStorageServiceBase.js.map +1 -1
  183. package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
  184. package/lib/odspDriverUrlResolverForShareLink.js +4 -4
  185. package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
  186. package/lib/odspFluidFileLink.js +1 -1
  187. package/lib/odspFluidFileLink.js.map +1 -1
  188. package/lib/odspLocationRedirection.d.ts +14 -0
  189. package/lib/odspLocationRedirection.d.ts.map +1 -0
  190. package/lib/odspLocationRedirection.js +20 -0
  191. package/lib/odspLocationRedirection.js.map +1 -0
  192. package/lib/odspSnapshotParser.d.ts.map +1 -1
  193. package/lib/odspSnapshotParser.js +1 -2
  194. package/lib/odspSnapshotParser.js.map +1 -1
  195. package/lib/odspSummaryUploadManager.d.ts +6 -3
  196. package/lib/odspSummaryUploadManager.d.ts.map +1 -1
  197. package/lib/odspSummaryUploadManager.js +14 -17
  198. package/lib/odspSummaryUploadManager.js.map +1 -1
  199. package/lib/odspUrlHelper.js +2 -1
  200. package/lib/odspUrlHelper.js.map +1 -1
  201. package/lib/odspUtils.d.ts +11 -2
  202. package/lib/odspUtils.d.ts.map +1 -1
  203. package/lib/odspUtils.js +31 -5
  204. package/lib/odspUtils.js.map +1 -1
  205. package/lib/opsCaching.d.ts.map +1 -1
  206. package/lib/opsCaching.js +3 -2
  207. package/lib/opsCaching.js.map +1 -1
  208. package/lib/packageVersion.d.ts +1 -1
  209. package/lib/packageVersion.d.ts.map +1 -1
  210. package/lib/packageVersion.js +1 -1
  211. package/lib/packageVersion.js.map +1 -1
  212. package/lib/prefetchLatestSnapshot.d.ts +6 -4
  213. package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
  214. package/lib/prefetchLatestSnapshot.js +6 -4
  215. package/lib/prefetchLatestSnapshot.js.map +1 -1
  216. package/lib/retryUtils.d.ts.map +1 -1
  217. package/lib/retryUtils.js +9 -5
  218. package/lib/retryUtils.js.map +1 -1
  219. package/lib/zipItDataRepresentationUtils.d.ts +30 -18
  220. package/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
  221. package/lib/zipItDataRepresentationUtils.js +166 -75
  222. package/lib/zipItDataRepresentationUtils.js.map +1 -1
  223. package/package.json +33 -20
  224. package/src/ReadBufferUtils.ts +1 -0
  225. package/src/WriteBufferUtils.ts +67 -58
  226. package/src/compactSnapshotParser.ts +102 -40
  227. package/src/compactSnapshotWriter.ts +25 -17
  228. package/src/contracts.ts +2 -14
  229. package/src/createFile.ts +75 -15
  230. package/src/createNewUtils.ts +2 -4
  231. package/src/createOdspCreateContainerRequest.ts +7 -4
  232. package/src/epochTracker.ts +47 -7
  233. package/src/fetchSnapshot.ts +35 -31
  234. package/src/getFileLink.ts +26 -39
  235. package/src/index.ts +1 -3
  236. package/src/localOdspDriver/localOdspDocumentStorageManager.ts +2 -2
  237. package/src/odspDeltaStorageService.ts +8 -9
  238. package/src/odspDocumentDeltaConnection.ts +3 -5
  239. package/src/odspDocumentService.ts +16 -13
  240. package/src/odspDocumentServiceFactoryCore.ts +40 -4
  241. package/src/odspDocumentStorageManager.ts +64 -50
  242. package/src/odspDocumentStorageServiceBase.ts +4 -2
  243. package/src/odspDriverUrlResolverForShareLink.ts +2 -5
  244. package/src/odspFluidFileLink.ts +1 -1
  245. package/src/odspLocationRedirection.ts +23 -0
  246. package/src/odspSnapshotParser.ts +3 -4
  247. package/src/odspSummaryUploadManager.ts +10 -11
  248. package/src/odspUrlHelper.ts +1 -1
  249. package/src/odspUtils.ts +40 -7
  250. package/src/opsCaching.ts +3 -2
  251. package/src/packageVersion.ts +1 -1
  252. package/src/prefetchLatestSnapshot.ts +6 -4
  253. package/src/retryUtils.ts +8 -5
  254. package/src/zipItDataRepresentationUtils.ts +198 -75
@@ -3,8 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { assert, unreachableCase } from "@fluidframework/common-utils";
7
- import { ReadBuffer } from "./ReadBufferUtils";
6
+ import { assert, IsoBuffer } from "@fluidframework/common-utils";
8
7
  import {
9
8
  BlobCore,
10
9
  codeToBytesMap,
@@ -13,7 +12,6 @@ import {
13
12
  MarkerCodesEnd,
14
13
  MarkerCodesStart,
15
14
  NodeCore,
16
- TreeBuilder,
17
15
  } from "./zipItDataRepresentationUtils";
18
16
 
19
17
  /**
@@ -52,11 +50,11 @@ export class WriteBuffer {
52
50
  assert(code === 0, 0x226 /* Should write complete data */);
53
51
  }
54
52
 
55
- public done(): ReadBuffer {
53
+ public done(): Uint8Array {
56
54
  assert(this.data !== undefined, 0x227 /* "Data should be there" */);
57
55
  // We can slice it to have smaller memory representation.
58
56
  // But it will be way more expensive in terms of CPU cycles!
59
- const buffer = new ReadBuffer(this.data.subarray(0, this.index));
57
+ const buffer = this.data.subarray(0, this.index);
60
58
  this.data = undefined;
61
59
  return buffer;
62
60
  }
@@ -143,56 +141,66 @@ const boolToCodeMap = [
143
141
  /**
144
142
  * Implementation of serialization of blobs in buffer with Marker Codes etc.
145
143
  * @param buffer - Buffer to serialize to.
146
- * @param blob - blob to be serialized.
144
+ * @param content - string to be serialized.
147
145
  * @param dictionary - Const strings dictionary to be used while serializing.
148
146
  */
149
- function serializeBlob(buffer: WriteBuffer, blob: BlobCore, dictionary: Map<string, number>) {
150
- const data = blob.buffer;
151
- const lengthOfDataLen = calcLength(data.length);
152
- if (blob.constString) {
153
- const content = blob.toString();
154
- let id = dictionary.get(content);
155
- let idLength: number;
156
- if (id === undefined) {
157
- id = dictionary.size + 1;
158
- idLength = calcLength(id);
159
- dictionary.set(content, id);
160
- let code: number;
161
- if (lengthOfDataLen > 1 || idLength > 1) {
162
- code = MarkerCodes.ConstStringDeclareBig;
163
- } else {
164
- code = MarkerCodes.ConstStringDeclare;
165
- }
166
- // Write marker code for const string.
167
- buffer.write(code);
168
- const bytes = getValueSafely(codeToBytesMap, code);
169
- assert(bytes >= lengthOfDataLen, 0x283 /* "Length of data len should fit in the bytes from the map" */);
170
- assert(bytes >= idLength, 0x284 /* "Length of id should fit in the bytes from the map" */);
171
- // Assign and write id for const string.
172
- buffer.write(id, bytes);
173
- // Write length of const string.
174
- buffer.write(data.length, bytes);
175
- // Write const string data.
176
- for (const element of data) {
177
- buffer.write(element);
178
- }
179
- } else {
180
- idLength = calcLength(id);
147
+ function serializeDictionaryString(buffer: WriteBuffer, content: string, dictionary: Map<string, number>) {
148
+ let id = dictionary.get(content);
149
+ let idLength: number;
150
+ if (id === undefined) {
151
+ const data = IsoBuffer.from(content, "utf8");
152
+ const lengthOfDataLen = calcLength(data.length);
153
+
154
+ id = dictionary.size + 1;
155
+ idLength = calcLength(id);
156
+ dictionary.set(content, id);
157
+ const code = lengthOfDataLen > 1 || idLength > 1
158
+ ? MarkerCodes.ConstStringDeclareBig
159
+ : MarkerCodes.ConstStringDeclare;
160
+ // Write marker code for const string.
161
+ buffer.write(code);
162
+ const bytes = getValueSafely(codeToBytesMap, code);
163
+ assert(bytes >= lengthOfDataLen, 0x283 /* "Length of data len should fit in the bytes from the map" */);
164
+ assert(bytes >= idLength, 0x284 /* "Length of id should fit in the bytes from the map" */);
165
+ // Assign and write id for const string.
166
+ buffer.write(id, bytes);
167
+ // Write length of const string.
168
+ buffer.write(data.length, bytes);
169
+ // Write const string data.
170
+ for (const element of data) {
171
+ buffer.write(element);
181
172
  }
182
- // Write Marker Code
183
- buffer.write(getValueSafely(constStringBytesToCodeMap, idLength));
184
- // Write id of const string
185
- buffer.write(id, idLength);
186
173
  } else {
187
- // Write Marker code.
188
- buffer.write(blob.useUtf8Code ? getValueSafely(utf8StringBytesToCodeMap, lengthOfDataLen)
189
- : getValueSafely(binaryBytesToCodeMap, lengthOfDataLen));
190
- // Write actual data if length greater than 0, otherwise Marker Code is enough.
191
- if (lengthOfDataLen > 0) {
192
- buffer.write(data.length, lengthOfDataLen);
193
- for (const element of data) {
194
- buffer.write(element);
195
- }
174
+ idLength = calcLength(id);
175
+ }
176
+ // Write Marker Code
177
+ buffer.write(getValueSafely(constStringBytesToCodeMap, idLength));
178
+ // Write id of const string
179
+ buffer.write(id, idLength);
180
+ }
181
+
182
+ function serializeString(buffer: WriteBuffer, content: string, codeMap = binaryBytesToCodeMap) {
183
+ serializeBlob(
184
+ buffer,
185
+ IsoBuffer.from(content, "utf8"),
186
+ utf8StringBytesToCodeMap);
187
+ }
188
+
189
+ /**
190
+ * Implementation of serialization of blobs in buffer with Marker Codes etc.
191
+ * @param buffer - Buffer to serialize to.
192
+ * @param blob - blob to be serialized.
193
+ * @param dictionary - Const strings dictionary to be used while serializing.
194
+ */
195
+ function serializeBlob(buffer: WriteBuffer, data: Uint8Array, codeMap: Record<number, number> = binaryBytesToCodeMap) {
196
+ const lengthOfDataLen = calcLength(data.length);
197
+ // Write Marker code.
198
+ buffer.write(getValueSafely(codeMap, lengthOfDataLen));
199
+ // Write actual data if length greater than 0, otherwise Marker Code is enough.
200
+ if (lengthOfDataLen > 0) {
201
+ buffer.write(data.length, lengthOfDataLen);
202
+ for (const element of data) {
203
+ buffer.write(element);
196
204
  }
197
205
  }
198
206
  }
@@ -215,7 +223,7 @@ function serializeNodeCore(buffer: WriteBuffer, nodeCore: NodeCore, dictionary:
215
223
  serializeNodeCore(buffer, child, dictionary);
216
224
  buffer.write(endCode);
217
225
  } else if (child instanceof BlobCore) {
218
- serializeBlob(buffer, child, dictionary);
226
+ serializeBlob(buffer, child.buffer);
219
227
  } else if (typeof child === "number") {
220
228
  // Calculate length in which integer will be stored
221
229
  const len = calcLength(child);
@@ -228,7 +236,12 @@ function serializeNodeCore(buffer: WriteBuffer, nodeCore: NodeCore, dictionary:
228
236
  } else if (typeof child === "boolean") {
229
237
  buffer.write(boolToCodeMap[child ? 1 : 0]);
230
238
  } else {
231
- unreachableCase(child, "Unsupported node type");
239
+ assert(child._stringElement, 0x3dd /* Unsupported node type */);
240
+ if (child.dictionary) {
241
+ serializeDictionaryString(buffer, child.content, dictionary);
242
+ } else {
243
+ serializeString(buffer, child.content);
244
+ }
232
245
  }
233
246
  }
234
247
  }
@@ -248,11 +261,7 @@ export class TreeBuilderSerializer extends NodeCoreSerializer {
248
261
  super();
249
262
  }
250
263
 
251
- static load(buffer: ReadBuffer): TreeBuilder {
252
- return TreeBuilder.load(buffer);
253
- }
254
-
255
- public serialize(): ReadBuffer {
264
+ public serialize(): Uint8Array {
256
265
  const buffer = new WriteBuffer();
257
266
  super.serialize(buffer);
258
267
  return buffer.done();
@@ -5,15 +5,16 @@
5
5
 
6
6
  import { assert } from "@fluidframework/common-utils";
7
7
  import { ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
8
+ import { ITelemetryLogger } from "@fluidframework/common-definitions";
8
9
  import { ISnapshotContents } from "./odspPublicUtils";
9
10
  import { ReadBuffer } from "./ReadBufferUtils";
10
- import { ISnapshotTreeEx } from "./contracts";
11
11
  import {
12
12
  assertBlobCoreInstance,
13
+ getStringInstance,
13
14
  assertBoolInstance,
14
15
  assertNodeCoreInstance,
15
16
  assertNumberInstance,
16
- getAndValidateNodeProps,
17
+ getNodeProps,
17
18
  NodeCore,
18
19
  NodeTypes,
19
20
  TreeBuilder,
@@ -34,12 +35,28 @@ interface ISnapshotSection {
34
35
  function readBlobSection(node: NodeTypes) {
35
36
  assertNodeCoreInstance(node, "TreeBlobs should be of type NodeCore");
36
37
  const blobs: Map<string, ArrayBuffer> = new Map();
37
- for (let count = 0; count < node.length; ++count) {
38
- const blob = node.getNode(count);
39
- const records = getAndValidateNodeProps(blob, ["id", "data"]);
38
+ for (const blob of node) {
39
+ assertNodeCoreInstance(blob, "blob should be node");
40
+
41
+ /**
42
+ * Perf optimization - the most common cases!
43
+ * This is essentially unrolling code below for faster processing
44
+ * It speeds up tree parsing by 2-3x times!
45
+ */
46
+ if (blob.length === 4 && blob.getMaybeString(0) === "id" && blob.getMaybeString(2) === "data") {
47
+ // "id": <node name>
48
+ // "data": <blob>
49
+ blobs.set(blob.getString(1), blob.getBlob(3).arrayBuffer);
50
+ continue;
51
+ }
52
+
53
+ /**
54
+ * More generalized workflow
55
+ */
56
+ const records = getNodeProps(blob);
40
57
  assertBlobCoreInstance(records.data, "data should be of BlobCore type");
41
- assertBlobCoreInstance(records.id, "blob id should be of BlobCore type");
42
- blobs.set(records.id.toString(), records.data.arrayBuffer);
58
+ const id = getStringInstance(records.id, "blob id should be string");
59
+ blobs.set(id, records.data.arrayBuffer);
43
60
  }
44
61
  return blobs;
45
62
  }
@@ -51,7 +68,7 @@ function readBlobSection(node: NodeTypes) {
51
68
  function readOpsSection(node: NodeTypes) {
52
69
  assertNodeCoreInstance(node, "Deltas should be of type NodeCore");
53
70
  const ops: ISequencedDocumentMessage[] = [];
54
- const records = getAndValidateNodeProps(node, ["firstSequenceNumber", "deltas"]);
71
+ const records = getNodeProps(node);
55
72
  assertNumberInstance(records.firstSequenceNumber, "Seq number should be a number");
56
73
  assertNodeCoreInstance(records.deltas, "Deltas should be a Node");
57
74
  for (let i = 0; i < records.deltas.length; ++i) {
@@ -67,31 +84,79 @@ function readOpsSection(node: NodeTypes) {
67
84
  * @param node - tree node to de-serialize from
68
85
  */
69
86
  function readTreeSection(node: NodeCore) {
70
- const snapshotTree: ISnapshotTreeEx = {
87
+ const trees = {};
88
+ const snapshotTree: ISnapshotTree = {
71
89
  blobs: {},
72
- commits: {},
73
- trees: {},
90
+ trees,
74
91
  };
75
- for (let count = 0; count < node.length; count++) {
76
- const treeNode = node.getNode(count);
77
- const records = getAndValidateNodeProps(treeNode,
78
- ["name", "value", "children", "unreferenced"], false);
79
- assertBlobCoreInstance(records.name, "Path should be of BlobCore");
80
- const path = records.name.toString();
92
+ for (const treeNode of node) {
93
+ assertNodeCoreInstance(treeNode, "tree nodes should be nodes");
94
+
95
+ /**
96
+ * Perf optimization - the most common cases!
97
+ * This is essentially unrolling code below for faster processing
98
+ * It speeds up tree parsing by 2-3x times!
99
+ */
100
+ const length = treeNode.length;
101
+ if (length > 0 && treeNode.getMaybeString(0) === "name") {
102
+ if (length === 4) {
103
+ const content = treeNode.getMaybeString(2);
104
+ // "name": <node name>
105
+ // "children": <blob id>
106
+ if (content === "children") {
107
+ trees[treeNode.getString(1)] = readTreeSection(treeNode.getNode(3));
108
+ continue;
109
+ }
110
+ // "name": <node name>
111
+ // "value": <blob id>
112
+ if (content === "value") {
113
+ snapshotTree.blobs[treeNode.getString(1)] = treeNode.getString(3);
114
+ continue;
115
+ }
116
+ }
117
+
118
+ // "name": <node name>
119
+ // "nodeType": 3
120
+ // "value": <blob id>
121
+ if (length === 6 &&
122
+ treeNode.getMaybeString(2) === "nodeType" &&
123
+ treeNode.getMaybeString(4) === "value") {
124
+ snapshotTree.blobs[treeNode.getString(1)] = treeNode.getString(5);
125
+ continue;
126
+ }
127
+
128
+ // "name": <node name>
129
+ // "unreferenced": true
130
+ // "children": <blob id>
131
+ if (length === 6 &&
132
+ treeNode.getMaybeString(2) === "unreferenced" &&
133
+ treeNode.getMaybeString(4) === "children") {
134
+ trees[treeNode.getString(1)] = readTreeSection(treeNode.getNode(5));
135
+ assert(treeNode.getBool(3), 0x3db /* Unreferenced if present should be true */);
136
+ snapshotTree.unreferenced = true;
137
+ continue;
138
+ }
139
+ }
140
+
141
+ /**
142
+ * More generalized workflow
143
+ */
144
+ const records = getNodeProps(treeNode);
145
+
146
+ if (records.unreferenced !== undefined) {
147
+ assertBoolInstance(records.unreferenced, "Unreferenced flag should be bool");
148
+ assert(records.unreferenced, 0x281 /* "Unreferenced if present should be true" */);
149
+ snapshotTree.unreferenced = true;
150
+ }
151
+
152
+ const path = getStringInstance(records.name, "Path name should be string");
81
153
  if (records.value !== undefined) {
82
- assertBlobCoreInstance(records.value, "Blob value should be BlobCore");
83
- snapshotTree.blobs[path] = records.value.toString();
154
+ snapshotTree.blobs[path] = getStringInstance(records.value, "Blob value should be string");
84
155
  } else if (records.children !== undefined) {
85
156
  assertNodeCoreInstance(records.children, "Trees should be of type NodeCore");
86
- snapshotTree.trees[path] = readTreeSection(records.children);
157
+ trees[path] = readTreeSection(records.children);
87
158
  } else {
88
- snapshotTree.trees[path] = { blobs: {}, commits: {}, trees: {} };
89
- }
90
- if (records.unreferenced !== undefined) {
91
- assertBoolInstance(records.unreferenced, "Unreferenced flag should be bool");
92
- const unreferenced = records.unreferenced.valueOf();
93
- assert(unreferenced, 0x281 /* "Unreferenced if present should be true" */);
94
- snapshotTree.unreferenced = unreferenced;
159
+ trees[path] = { blobs: {}, trees: {} };
95
160
  }
96
161
  }
97
162
  return snapshotTree;
@@ -103,14 +168,12 @@ function readTreeSection(node: NodeCore) {
103
168
  */
104
169
  function readSnapshotSection(node: NodeTypes): ISnapshotSection {
105
170
  assertNodeCoreInstance(node, "Snapshot should be of type NodeCore");
106
- const records = getAndValidateNodeProps(node,
107
- ["id", "sequenceNumber", "treeNodes"]);
171
+ const records = getNodeProps(node);
108
172
 
109
173
  assertNodeCoreInstance(records.treeNodes, "TreeNodes should be of type NodeCore");
110
174
  assertNumberInstance(records.sequenceNumber, "sequenceNumber should be of type number");
111
- assertBlobCoreInstance(records.id, "snapshotId should be BlobCore");
112
175
  const snapshotTree: ISnapshotTree = readTreeSection(records.treeNodes);
113
- snapshotTree.id = records.id.toString();
176
+ snapshotTree.id = getStringInstance(records.id, "snapshotId should be string");
114
177
  const sequenceNumber = records.sequenceNumber.valueOf();
115
178
  return {
116
179
  sequenceNumber,
@@ -123,25 +186,24 @@ function readSnapshotSection(node: NodeTypes): ISnapshotSection {
123
186
  * @param buffer - Compact snapshot to be parsed into tree/blobs/ops.
124
187
  * @returns - tree, blobs and ops from the snapshot.
125
188
  */
126
- export function parseCompactSnapshotResponse(buffer: ReadBuffer): ISnapshotContents {
127
- const builder = TreeBuilder.load(buffer);
189
+ export function parseCompactSnapshotResponse(buffer: Uint8Array, logger: ITelemetryLogger): ISnapshotContents {
190
+ const builder = TreeBuilder.load(new ReadBuffer(buffer), logger);
128
191
  assert(builder.length === 1, 0x219 /* "1 root should be there" */);
129
192
  const root = builder.getNode(0);
130
193
 
131
- const records = getAndValidateNodeProps(root,
132
- ["mrv", "cv", "lsn", "snapshot", "blobs", "deltas"], false);
194
+ const records = getNodeProps(root);
133
195
 
134
- assertBlobCoreInstance(records.mrv, "minReadVersion should be of BlobCore type");
135
- assertBlobCoreInstance(records.cv, "createVersion should be of BlobCore type");
196
+ const mrv = getStringInstance(records.mrv, "minReadVersion should be string");
197
+ const cv = getStringInstance(records.cv, "createVersion should be string");
136
198
  if (records.lsn !== undefined) {
137
199
  assertNumberInstance(records.lsn, "lsn should be a number");
138
200
  }
139
201
 
140
- assert(parseFloat(snapshotMinReadVersion) >= parseFloat(records.mrv.toString()),
202
+ assert(parseFloat(snapshotMinReadVersion) >= parseFloat(mrv),
141
203
  0x20f /* "Driver min read version should >= to server minReadVersion" */);
142
- assert(parseFloat(records.cv.toString()) >= parseFloat(snapshotMinReadVersion),
204
+ assert(parseFloat(cv) >= parseFloat(snapshotMinReadVersion),
143
205
  0x210 /* "Snapshot should be created with minReadVersion or above" */);
144
- assert(currentReadVersion === records.cv.toString(),
206
+ assert(currentReadVersion === cv,
145
207
  0x2c2 /* "Create Version should be equal to currentReadVersion" */);
146
208
 
147
209
  return {
@@ -7,9 +7,14 @@ import { assert, stringToBuffer } from "@fluidframework/common-utils";
7
7
  import { IBlob, ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
8
8
  import { snapshotMinReadVersion } from "./compactSnapshotParser";
9
9
  import { ISnapshotContents } from "./odspPublicUtils";
10
- import { ReadBuffer } from "./ReadBufferUtils";
11
10
  import { TreeBuilderSerializer } from "./WriteBufferUtils";
12
- import { addBoolProperty, addNumberProperty, addStringProperty, NodeCore } from "./zipItDataRepresentationUtils";
11
+ import {
12
+ addBoolProperty,
13
+ addNumberProperty,
14
+ addStringProperty,
15
+ addDictionaryStringProperty,
16
+ NodeCore,
17
+ } from "./zipItDataRepresentationUtils";
13
18
 
14
19
  /**
15
20
  * Writes header section of the snapshot.
@@ -28,16 +33,16 @@ function writeSnapshotProps(node: NodeCore, latestSequenceNumber: number) {
28
33
  * @param blobs - blobs that is being serialized
29
34
  */
30
35
  function writeBlobsSection(snapshotNode: NodeCore, blobs: Map<string, IBlob | ArrayBuffer>) {
31
- snapshotNode.addString("blobs", true);
36
+ snapshotNode.addDictionaryString("blobs");
32
37
  const blobsNode = snapshotNode.addNode("list");
33
38
  for (const [storageBlobId, blob] of blobs) {
34
39
  const blobNode = blobsNode.addNode();
35
- addStringProperty(blobNode, "id", storageBlobId, true);
36
- blobNode.addString("data", true);
40
+ addDictionaryStringProperty(blobNode, "id", storageBlobId);
41
+ blobNode.addString("data");
37
42
  if (blob instanceof ArrayBuffer) {
38
- blobNode.addBlob(new Uint8Array(blob), false);
43
+ blobNode.addBlob(new Uint8Array(blob));
39
44
  } else {
40
- blobNode.addBlob(new Uint8Array(stringToBuffer(blob.contents, blob.encoding ?? "utf-8")), false);
45
+ blobNode.addBlob(new Uint8Array(stringToBuffer(blob.contents, blob.encoding ?? "utf-8")));
41
46
  }
42
47
  }
43
48
  }
@@ -48,7 +53,7 @@ function writeBlobsSection(snapshotNode: NodeCore, blobs: Map<string, IBlob | Ar
48
53
  * @param snapshotTree - snapshot tree that is being serialized
49
54
  */
50
55
  function writeTreeSection(snapshotNode: NodeCore, snapshotTree: ISnapshotTree) {
51
- snapshotNode.addString("treeNodes", true);
56
+ snapshotNode.addDictionaryString("treeNodes");
52
57
  const treesNode = snapshotNode.addNode("list");
53
58
  writeTreeSectionCore(treesNode, snapshotTree);
54
59
  }
@@ -56,13 +61,16 @@ function writeTreeSection(snapshotNode: NodeCore, snapshotTree: ISnapshotTree) {
56
61
  function writeTreeSectionCore(treesNode: NodeCore, snapshotTree: ISnapshotTree) {
57
62
  for (const [path, value] of Object.entries(snapshotTree.trees)) {
58
63
  const treeNode = treesNode.addNode();
59
- addStringProperty(treeNode, "name", path);
64
+ // Many leaf nodes in the tree have same names like "content", "body", "header"
65
+ // We could be smarter here and not use dictionary where we are sure reuse is unlikely, but
66
+ // it does not feel like it's worth it.
67
+ addDictionaryStringProperty(treeNode, "name", path);
60
68
  if (snapshotTree.unreferenced) {
61
69
  addBoolProperty(treeNode, "unreferenced", snapshotTree.unreferenced);
62
70
  }
63
71
  // Only write children prop if either blobs or trees are present.
64
72
  if (Object.keys(value.blobs).length > 0 || Object.keys(value.trees).length > 0) {
65
- treeNode.addString("children", true);
73
+ treeNode.addDictionaryString("children");
66
74
  const childNode = treeNode.addNode("list");
67
75
  writeTreeSectionCore(childNode, value);
68
76
  }
@@ -71,8 +79,8 @@ function writeTreeSectionCore(treesNode: NodeCore, snapshotTree: ISnapshotTree)
71
79
  if (snapshotTree.blobs) {
72
80
  for (const [path, id] of Object.entries(snapshotTree.blobs)) {
73
81
  const blobNode = treesNode.addNode();
74
- addStringProperty(blobNode, "name", path);
75
- addStringProperty(blobNode, "value", id, true);
82
+ addDictionaryStringProperty(blobNode, "name", path);
83
+ addDictionaryStringProperty(blobNode, "value", id);
76
84
  }
77
85
  }
78
86
  }
@@ -89,7 +97,7 @@ function writeSnapshotSection(
89
97
  snapshotTree: ISnapshotTree,
90
98
  snapshotSequenceNumber: number,
91
99
  ) {
92
- rootNode.addString("snapshot", true);
100
+ rootNode.addDictionaryString("snapshot");
93
101
  const snapshotNode = rootNode.addNode();
94
102
 
95
103
  const snapshotId = snapshotTree.id;
@@ -113,13 +121,13 @@ function writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]) {
113
121
  firstSequenceNumber = ops[0].sequenceNumber;
114
122
  }
115
123
  if (firstSequenceNumber !== undefined) {
116
- rootNode.addString("deltas", true);
124
+ rootNode.addDictionaryString("deltas");
117
125
  const opsNode = rootNode.addNode();
118
126
  addNumberProperty(opsNode, "firstSequenceNumber", firstSequenceNumber);
119
- opsNode.addString("deltas", true);
127
+ opsNode.addDictionaryString("deltas");
120
128
  const deltaNode = opsNode.addNode("list");
121
129
  ops.forEach((op) => {
122
- deltaNode.addString(JSON.stringify(op), false);
130
+ deltaNode.addString(JSON.stringify(op));
123
131
  });
124
132
  }
125
133
  }
@@ -129,7 +137,7 @@ function writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]) {
129
137
  * @param snapshotContents - snapshot tree contents to serialize
130
138
  * @returns - ReadBuffer - binary representation of the data.
131
139
  */
132
- export function convertToCompactSnapshot(snapshotContents: ISnapshotContents): ReadBuffer {
140
+ export function convertToCompactSnapshot(snapshotContents: ISnapshotContents): Uint8Array {
133
141
  const builder = new TreeBuilderSerializer();
134
142
  // Create the root node.
135
143
  const rootNode = builder.addNode();
package/src/contracts.ts CHANGED
@@ -7,20 +7,6 @@ import * as api from "@fluidframework/protocol-definitions";
7
7
  import { HostStoragePolicy } from "@fluidframework/odsp-driver-definitions";
8
8
  import { ISnapshotContents } from "./odspPublicUtils";
9
9
 
10
- /** https://portal.microsofticm.com/imp/v3/incidents/details/308931013/home
11
- * The commits property was removed from protocol-definitions but in order to support back compat, we will
12
- * temporarily add back in this local structure in order to upload the snapshot to support rolling back to 0.58.
13
- * Notice this entire interface will be removed once the backward compatibility is not required anymore.
14
- */
15
- export interface ISnapshotTreeEx {
16
- id?: string;
17
- blobs: { [path: string]: string; };
18
- commits: { [path: string]: string; };
19
- trees: { [path: string]: ISnapshotTreeEx; };
20
- // Indicates that this tree is unreferenced. If this is not present, the tree is considered referenced.
21
- unreferenced?: true;
22
- }
23
-
24
10
  /**
25
11
  * Socket storage discovery api response
26
12
  */
@@ -216,6 +202,8 @@ export interface ICreateFileResponse {
216
202
  itemId: string;
217
203
  itemUrl: string;
218
204
  sequenceNumber: number;
205
+ // sharing object contains shareId, sharingLink data or error in the response
206
+ sharing?: any;
219
207
  sharingLink?: string;
220
208
  sharingLinkErrorReason?: string;
221
209
  }