@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.
- package/.mocharc.js +12 -0
- package/README.md +19 -0
- package/dist/ReadBufferUtils.d.ts.map +1 -1
- package/dist/ReadBufferUtils.js +1 -0
- package/dist/ReadBufferUtils.js.map +1 -1
- package/dist/WriteBufferUtils.d.ts +3 -5
- package/dist/WriteBufferUtils.d.ts.map +1 -1
- package/dist/WriteBufferUtils.js +59 -55
- package/dist/WriteBufferUtils.js.map +1 -1
- package/dist/compactSnapshotParser.d.ts +2 -2
- package/dist/compactSnapshotParser.d.ts.map +1 -1
- package/dist/compactSnapshotParser.js +91 -34
- package/dist/compactSnapshotParser.js.map +1 -1
- package/dist/compactSnapshotWriter.d.ts +1 -2
- package/dist/compactSnapshotWriter.d.ts.map +1 -1
- package/dist/compactSnapshotWriter.js +17 -14
- package/dist/compactSnapshotWriter.js.map +1 -1
- package/dist/contracts.d.ts +1 -18
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/createFile.d.ts +1 -1
- package/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js +53 -16
- package/dist/createFile.js.map +1 -1
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +0 -1
- package/dist/createNewUtils.js.map +1 -1
- package/dist/createOdspCreateContainerRequest.d.ts +4 -3
- package/dist/createOdspCreateContainerRequest.d.ts.map +1 -1
- package/dist/createOdspCreateContainerRequest.js +6 -3
- package/dist/createOdspCreateContainerRequest.js.map +1 -1
- package/dist/epochTracker.d.ts +1 -0
- package/dist/epochTracker.d.ts.map +1 -1
- package/dist/epochTracker.js +24 -5
- package/dist/epochTracker.js.map +1 -1
- package/dist/fetchSnapshot.d.ts +1 -2
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +22 -27
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.d.ts +3 -6
- package/dist/getFileLink.d.ts.map +1 -1
- package/dist/getFileLink.js +22 -33
- package/dist/getFileLink.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.js +1 -2
- package/dist/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts +3 -2
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +9 -12
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/dist/odspDocumentDeltaConnection.js +3 -6
- package/dist/odspDocumentDeltaConnection.js.map +1 -1
- package/dist/odspDocumentService.d.ts +1 -0
- package/dist/odspDocumentService.d.ts.map +1 -1
- package/dist/odspDocumentService.js +12 -6
- package/dist/odspDocumentService.js.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.js +29 -6
- package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts +4 -4
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +82 -64
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/dist/odspDocumentStorageServiceBase.js +4 -2
- package/dist/odspDocumentStorageServiceBase.js.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.js +4 -4
- package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/dist/odspFluidFileLink.js +1 -1
- package/dist/odspFluidFileLink.js.map +1 -1
- package/dist/odspLocationRedirection.d.ts +14 -0
- package/dist/odspLocationRedirection.d.ts.map +1 -0
- package/dist/odspLocationRedirection.js +24 -0
- package/dist/odspLocationRedirection.js.map +1 -0
- package/dist/odspSnapshotParser.d.ts.map +1 -1
- package/dist/odspSnapshotParser.js +1 -2
- package/dist/odspSnapshotParser.js.map +1 -1
- package/dist/odspSummaryUploadManager.d.ts +6 -3
- package/dist/odspSummaryUploadManager.d.ts.map +1 -1
- package/dist/odspSummaryUploadManager.js +14 -17
- package/dist/odspSummaryUploadManager.js.map +1 -1
- package/dist/odspUrlHelper.js +2 -1
- package/dist/odspUrlHelper.js.map +1 -1
- package/dist/odspUtils.d.ts +11 -2
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +32 -5
- package/dist/odspUtils.js.map +1 -1
- package/dist/opsCaching.d.ts.map +1 -1
- package/dist/opsCaching.js +3 -2
- package/dist/opsCaching.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/prefetchLatestSnapshot.d.ts +6 -4
- package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
- package/dist/prefetchLatestSnapshot.js +6 -4
- package/dist/prefetchLatestSnapshot.js.map +1 -1
- package/dist/retryUtils.d.ts.map +1 -1
- package/dist/retryUtils.js +8 -4
- package/dist/retryUtils.js.map +1 -1
- package/dist/zipItDataRepresentationUtils.d.ts +30 -18
- package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/dist/zipItDataRepresentationUtils.js +170 -76
- package/dist/zipItDataRepresentationUtils.js.map +1 -1
- package/lib/ReadBufferUtils.d.ts.map +1 -1
- package/lib/ReadBufferUtils.js +1 -0
- package/lib/ReadBufferUtils.js.map +1 -1
- package/lib/WriteBufferUtils.d.ts +3 -5
- package/lib/WriteBufferUtils.d.ts.map +1 -1
- package/lib/WriteBufferUtils.js +61 -57
- package/lib/WriteBufferUtils.js.map +1 -1
- package/lib/compactSnapshotParser.d.ts +2 -2
- package/lib/compactSnapshotParser.d.ts.map +1 -1
- package/lib/compactSnapshotParser.js +92 -35
- package/lib/compactSnapshotParser.js.map +1 -1
- package/lib/compactSnapshotWriter.d.ts +1 -2
- package/lib/compactSnapshotWriter.d.ts.map +1 -1
- package/lib/compactSnapshotWriter.js +18 -15
- package/lib/compactSnapshotWriter.js.map +1 -1
- package/lib/contracts.d.ts +1 -18
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/createFile.d.ts +1 -1
- package/lib/createFile.d.ts.map +1 -1
- package/lib/createFile.js +54 -17
- package/lib/createFile.js.map +1 -1
- package/lib/createNewUtils.d.ts.map +1 -1
- package/lib/createNewUtils.js +0 -1
- package/lib/createNewUtils.js.map +1 -1
- package/lib/createOdspCreateContainerRequest.d.ts +4 -3
- package/lib/createOdspCreateContainerRequest.d.ts.map +1 -1
- package/lib/createOdspCreateContainerRequest.js +6 -3
- package/lib/createOdspCreateContainerRequest.js.map +1 -1
- package/lib/epochTracker.d.ts +1 -0
- package/lib/epochTracker.d.ts.map +1 -1
- package/lib/epochTracker.js +26 -7
- package/lib/epochTracker.js.map +1 -1
- package/lib/fetchSnapshot.d.ts +1 -2
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +22 -27
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/getFileLink.d.ts +3 -6
- package/lib/getFileLink.d.ts.map +1 -1
- package/lib/getFileLink.js +24 -35
- package/lib/getFileLink.js.map +1 -1
- package/lib/index.d.ts +1 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -3
- package/lib/index.js.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.js +1 -2
- package/lib/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts +3 -2
- package/lib/odspDeltaStorageService.d.ts.map +1 -1
- package/lib/odspDeltaStorageService.js +9 -12
- package/lib/odspDeltaStorageService.js.map +1 -1
- package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/lib/odspDocumentDeltaConnection.js +3 -6
- package/lib/odspDocumentDeltaConnection.js.map +1 -1
- package/lib/odspDocumentService.d.ts +1 -0
- package/lib/odspDocumentService.d.ts.map +1 -1
- package/lib/odspDocumentService.js +14 -8
- package/lib/odspDocumentService.js.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.js +29 -6
- package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
- package/lib/odspDocumentStorageManager.d.ts +4 -4
- package/lib/odspDocumentStorageManager.d.ts.map +1 -1
- package/lib/odspDocumentStorageManager.js +83 -65
- package/lib/odspDocumentStorageManager.js.map +1 -1
- package/lib/odspDocumentStorageServiceBase.d.ts +1 -1
- package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/lib/odspDocumentStorageServiceBase.js +4 -2
- package/lib/odspDocumentStorageServiceBase.js.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.js +4 -4
- package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/lib/odspFluidFileLink.js +1 -1
- package/lib/odspFluidFileLink.js.map +1 -1
- package/lib/odspLocationRedirection.d.ts +14 -0
- package/lib/odspLocationRedirection.d.ts.map +1 -0
- package/lib/odspLocationRedirection.js +20 -0
- package/lib/odspLocationRedirection.js.map +1 -0
- package/lib/odspSnapshotParser.d.ts.map +1 -1
- package/lib/odspSnapshotParser.js +1 -2
- package/lib/odspSnapshotParser.js.map +1 -1
- package/lib/odspSummaryUploadManager.d.ts +6 -3
- package/lib/odspSummaryUploadManager.d.ts.map +1 -1
- package/lib/odspSummaryUploadManager.js +14 -17
- package/lib/odspSummaryUploadManager.js.map +1 -1
- package/lib/odspUrlHelper.js +2 -1
- package/lib/odspUrlHelper.js.map +1 -1
- package/lib/odspUtils.d.ts +11 -2
- package/lib/odspUtils.d.ts.map +1 -1
- package/lib/odspUtils.js +31 -5
- package/lib/odspUtils.js.map +1 -1
- package/lib/opsCaching.d.ts.map +1 -1
- package/lib/opsCaching.js +3 -2
- package/lib/opsCaching.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/prefetchLatestSnapshot.d.ts +6 -4
- package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
- package/lib/prefetchLatestSnapshot.js +6 -4
- package/lib/prefetchLatestSnapshot.js.map +1 -1
- package/lib/retryUtils.d.ts.map +1 -1
- package/lib/retryUtils.js +9 -5
- package/lib/retryUtils.js.map +1 -1
- package/lib/zipItDataRepresentationUtils.d.ts +30 -18
- package/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/lib/zipItDataRepresentationUtils.js +166 -75
- package/lib/zipItDataRepresentationUtils.js.map +1 -1
- package/package.json +33 -20
- package/src/ReadBufferUtils.ts +1 -0
- package/src/WriteBufferUtils.ts +67 -58
- package/src/compactSnapshotParser.ts +102 -40
- package/src/compactSnapshotWriter.ts +25 -17
- package/src/contracts.ts +2 -14
- package/src/createFile.ts +75 -15
- package/src/createNewUtils.ts +2 -4
- package/src/createOdspCreateContainerRequest.ts +7 -4
- package/src/epochTracker.ts +47 -7
- package/src/fetchSnapshot.ts +35 -31
- package/src/getFileLink.ts +26 -39
- package/src/index.ts +1 -3
- package/src/localOdspDriver/localOdspDocumentStorageManager.ts +2 -2
- package/src/odspDeltaStorageService.ts +8 -9
- package/src/odspDocumentDeltaConnection.ts +3 -5
- package/src/odspDocumentService.ts +16 -13
- package/src/odspDocumentServiceFactoryCore.ts +40 -4
- package/src/odspDocumentStorageManager.ts +64 -50
- package/src/odspDocumentStorageServiceBase.ts +4 -2
- package/src/odspDriverUrlResolverForShareLink.ts +2 -5
- package/src/odspFluidFileLink.ts +1 -1
- package/src/odspLocationRedirection.ts +23 -0
- package/src/odspSnapshotParser.ts +3 -4
- package/src/odspSummaryUploadManager.ts +10 -11
- package/src/odspUrlHelper.ts +1 -1
- package/src/odspUtils.ts +40 -7
- package/src/opsCaching.ts +3 -2
- package/src/packageVersion.ts +1 -1
- package/src/prefetchLatestSnapshot.ts +6 -4
- package/src/retryUtils.ts +8 -5
- package/src/zipItDataRepresentationUtils.ts +198 -75
package/src/WriteBufferUtils.ts
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { assert,
|
|
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():
|
|
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 =
|
|
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
|
|
144
|
+
* @param content - string to be serialized.
|
|
147
145
|
* @param dictionary - Const strings dictionary to be used while serializing.
|
|
148
146
|
*/
|
|
149
|
-
function
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
42
|
-
blobs.set(
|
|
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 =
|
|
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
|
|
87
|
+
const trees = {};
|
|
88
|
+
const snapshotTree: ISnapshotTree = {
|
|
71
89
|
blobs: {},
|
|
72
|
-
|
|
73
|
-
trees: {},
|
|
90
|
+
trees,
|
|
74
91
|
};
|
|
75
|
-
for (
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
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
|
-
|
|
157
|
+
trees[path] = readTreeSection(records.children);
|
|
87
158
|
} else {
|
|
88
|
-
|
|
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 =
|
|
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
|
|
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:
|
|
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 =
|
|
132
|
-
["mrv", "cv", "lsn", "snapshot", "blobs", "deltas"], false);
|
|
194
|
+
const records = getNodeProps(root);
|
|
133
195
|
|
|
134
|
-
|
|
135
|
-
|
|
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(
|
|
202
|
+
assert(parseFloat(snapshotMinReadVersion) >= parseFloat(mrv),
|
|
141
203
|
0x20f /* "Driver min read version should >= to server minReadVersion" */);
|
|
142
|
-
assert(parseFloat(
|
|
204
|
+
assert(parseFloat(cv) >= parseFloat(snapshotMinReadVersion),
|
|
143
205
|
0x210 /* "Snapshot should be created with minReadVersion or above" */);
|
|
144
|
-
assert(currentReadVersion ===
|
|
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 {
|
|
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.
|
|
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
|
-
|
|
36
|
-
blobNode.addString("data"
|
|
40
|
+
addDictionaryStringProperty(blobNode, "id", storageBlobId);
|
|
41
|
+
blobNode.addString("data");
|
|
37
42
|
if (blob instanceof ArrayBuffer) {
|
|
38
|
-
blobNode.addBlob(new Uint8Array(blob)
|
|
43
|
+
blobNode.addBlob(new Uint8Array(blob));
|
|
39
44
|
} else {
|
|
40
|
-
blobNode.addBlob(new Uint8Array(stringToBuffer(blob.contents, blob.encoding ?? "utf-8"))
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
75
|
-
|
|
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.
|
|
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.
|
|
124
|
+
rootNode.addDictionaryString("deltas");
|
|
117
125
|
const opsNode = rootNode.addNode();
|
|
118
126
|
addNumberProperty(opsNode, "firstSequenceNumber", firstSequenceNumber);
|
|
119
|
-
opsNode.
|
|
127
|
+
opsNode.addDictionaryString("deltas");
|
|
120
128
|
const deltaNode = opsNode.addNode("list");
|
|
121
129
|
ops.forEach((op) => {
|
|
122
|
-
deltaNode.addString(JSON.stringify(op)
|
|
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):
|
|
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
|
}
|