@fluidframework/odsp-driver 2.0.0-dev-rc.1.0.0.228517 → 2.0.0-dev-rc.1.0.0.232845
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/api-report/odsp-driver.api.md +5 -5
- package/dist/compactSnapshotParser.d.ts +2 -2
- package/dist/compactSnapshotParser.d.ts.map +1 -1
- package/dist/compactSnapshotParser.js +8 -7
- package/dist/compactSnapshotParser.js.map +1 -1
- package/dist/compactSnapshotWriter.d.ts +2 -2
- package/dist/compactSnapshotWriter.d.ts.map +1 -1
- package/dist/compactSnapshotWriter.js +1 -1
- package/dist/compactSnapshotWriter.js.map +1 -1
- package/dist/contracts.d.ts +14 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +5 -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 +9 -28
- package/dist/createFile.js.map +1 -1
- package/dist/createNewContainerOnExistingFile.d.ts.map +1 -1
- package/dist/createNewContainerOnExistingFile.js.map +1 -1
- package/dist/createNewUtils.d.ts +2 -2
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +4 -3
- package/dist/createNewUtils.js.map +1 -1
- package/dist/createOdspCreateContainerRequest.d.ts +2 -2
- package/dist/createOdspCreateContainerRequest.d.ts.map +1 -1
- package/dist/createOdspCreateContainerRequest.js.map +1 -1
- package/dist/epochTracker.d.ts.map +1 -1
- package/dist/epochTracker.js +3 -4
- package/dist/epochTracker.js.map +1 -1
- package/dist/fetchSnapshot.d.ts +4 -4
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +12 -13
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.d.ts.map +1 -1
- package/dist/getFileLink.js +3 -3
- package/dist/getFileLink.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentService.d.ts +3 -2
- package/dist/localOdspDriver/localOdspDocumentService.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentService.js +3 -1
- package/dist/localOdspDriver/localOdspDocumentService.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts +2 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.js +3 -0
- package/dist/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
- package/dist/odsp-driver-alpha.d.ts +4 -3
- package/dist/odsp-driver-beta.d.ts +3 -3
- package/dist/odsp-driver-public.d.ts +3 -3
- package/dist/odsp-driver-untrimmed.d.ts +5 -4
- package/dist/odspCache.d.ts +2 -2
- package/dist/odspCache.d.ts.map +1 -1
- package/dist/odspCache.js.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.d.ts +5 -1
- package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.js +56 -5
- package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
- package/dist/odspDocumentService.d.ts +3 -2
- package/dist/odspDocumentService.d.ts.map +1 -1
- package/dist/odspDocumentService.js +6 -3
- package/dist/odspDocumentService.js.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.js +1 -8
- package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts +2 -1
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +30 -11
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts +3 -3
- package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/dist/odspDocumentStorageServiceBase.js +3 -3
- package/dist/odspDocumentStorageServiceBase.js.map +1 -1
- package/dist/odspDriverUrlResolver.d.ts.map +1 -1
- package/dist/odspDriverUrlResolver.js +2 -11
- package/dist/odspDriverUrlResolver.js.map +1 -1
- package/dist/odspError.d.ts.map +1 -1
- package/dist/odspError.js +2 -2
- package/dist/odspError.js.map +1 -1
- package/dist/odspPublicUtils.d.ts +1 -0
- package/dist/odspPublicUtils.d.ts.map +1 -1
- package/dist/odspPublicUtils.js.map +1 -1
- package/dist/odspSnapshotParser.d.ts +2 -2
- package/dist/odspSnapshotParser.d.ts.map +1 -1
- package/dist/odspSnapshotParser.js +2 -1
- package/dist/odspSnapshotParser.js.map +1 -1
- package/dist/odspUtils.d.ts +11 -7
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +20 -16
- package/dist/odspUtils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/retryErrorsStorageAdapter.d.ts +2 -1
- package/dist/retryErrorsStorageAdapter.d.ts.map +1 -1
- package/dist/retryErrorsStorageAdapter.js +8 -0
- package/dist/retryErrorsStorageAdapter.js.map +1 -1
- package/dist/retryUtils.js +1 -1
- package/dist/retryUtils.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/zipItDataRepresentationUtils.js +2 -2
- package/dist/zipItDataRepresentationUtils.js.map +1 -1
- package/lib/compactSnapshotParser.d.mts +2 -2
- package/lib/compactSnapshotParser.d.mts.map +1 -1
- package/lib/compactSnapshotParser.mjs +8 -7
- package/lib/compactSnapshotParser.mjs.map +1 -1
- package/lib/compactSnapshotWriter.d.mts +2 -2
- package/lib/compactSnapshotWriter.d.mts.map +1 -1
- package/lib/compactSnapshotWriter.mjs +1 -1
- package/lib/compactSnapshotWriter.mjs.map +1 -1
- package/lib/contracts.d.mts +14 -0
- package/lib/contracts.d.mts.map +1 -1
- package/lib/contracts.mjs +4 -0
- package/lib/contracts.mjs.map +1 -1
- package/lib/createFile.d.mts +1 -1
- package/lib/createFile.d.mts.map +1 -1
- package/lib/createFile.mjs +10 -29
- package/lib/createFile.mjs.map +1 -1
- package/lib/createNewContainerOnExistingFile.d.mts.map +1 -1
- package/lib/createNewContainerOnExistingFile.mjs.map +1 -1
- package/lib/createNewUtils.d.mts +2 -2
- package/lib/createNewUtils.d.mts.map +1 -1
- package/lib/createNewUtils.mjs +4 -3
- package/lib/createNewUtils.mjs.map +1 -1
- package/lib/createOdspCreateContainerRequest.d.mts +2 -2
- package/lib/createOdspCreateContainerRequest.d.mts.map +1 -1
- package/lib/createOdspCreateContainerRequest.mjs.map +1 -1
- package/lib/epochTracker.d.mts.map +1 -1
- package/lib/epochTracker.mjs +4 -5
- package/lib/epochTracker.mjs.map +1 -1
- package/lib/fetchSnapshot.d.mts +4 -4
- package/lib/fetchSnapshot.d.mts.map +1 -1
- package/lib/fetchSnapshot.mjs +13 -14
- package/lib/fetchSnapshot.mjs.map +1 -1
- package/lib/getFileLink.d.mts.map +1 -1
- package/lib/getFileLink.mjs +3 -3
- package/lib/getFileLink.mjs.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentService.d.mts +3 -2
- package/lib/localOdspDriver/localOdspDocumentService.d.mts.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentService.mjs +3 -1
- package/lib/localOdspDriver/localOdspDocumentService.mjs.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.d.mts +2 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.d.mts.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.mjs +3 -0
- package/lib/localOdspDriver/localOdspDocumentStorageManager.mjs.map +1 -1
- package/lib/odsp-driver-alpha.d.mts +4 -3
- package/lib/odsp-driver-beta.d.mts +3 -3
- package/lib/odsp-driver-public.d.mts +3 -3
- package/lib/odsp-driver-untrimmed.d.mts +5 -4
- package/lib/odspCache.d.mts +2 -2
- package/lib/odspCache.d.mts.map +1 -1
- package/lib/odspCache.mjs.map +1 -1
- package/lib/odspDelayLoadedDeltaStream.d.mts +5 -1
- package/lib/odspDelayLoadedDeltaStream.d.mts.map +1 -1
- package/lib/odspDelayLoadedDeltaStream.mjs +57 -6
- package/lib/odspDelayLoadedDeltaStream.mjs.map +1 -1
- package/lib/odspDocumentService.d.mts +3 -2
- package/lib/odspDocumentService.d.mts.map +1 -1
- package/lib/odspDocumentService.mjs +6 -3
- package/lib/odspDocumentService.mjs.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.d.mts.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.mjs +2 -9
- package/lib/odspDocumentServiceFactoryCore.mjs.map +1 -1
- package/lib/odspDocumentStorageManager.d.mts +2 -1
- package/lib/odspDocumentStorageManager.d.mts.map +1 -1
- package/lib/odspDocumentStorageManager.mjs +33 -14
- package/lib/odspDocumentStorageManager.mjs.map +1 -1
- package/lib/odspDocumentStorageServiceBase.d.mts +3 -3
- package/lib/odspDocumentStorageServiceBase.d.mts.map +1 -1
- package/lib/odspDocumentStorageServiceBase.mjs +3 -3
- package/lib/odspDocumentStorageServiceBase.mjs.map +1 -1
- package/lib/odspDriverUrlResolver.d.mts.map +1 -1
- package/lib/odspDriverUrlResolver.mjs +4 -13
- package/lib/odspDriverUrlResolver.mjs.map +1 -1
- package/lib/odspError.d.mts.map +1 -1
- package/lib/odspError.mjs +2 -2
- package/lib/odspError.mjs.map +1 -1
- package/lib/odspPublicUtils.d.mts +1 -0
- package/lib/odspPublicUtils.d.mts.map +1 -1
- package/lib/odspPublicUtils.mjs.map +1 -1
- package/lib/odspSnapshotParser.d.mts +2 -2
- package/lib/odspSnapshotParser.d.mts.map +1 -1
- package/lib/odspSnapshotParser.mjs +2 -1
- package/lib/odspSnapshotParser.mjs.map +1 -1
- package/lib/odspUtils.d.mts +11 -7
- package/lib/odspUtils.d.mts.map +1 -1
- package/lib/odspUtils.mjs +19 -16
- package/lib/odspUtils.mjs.map +1 -1
- package/lib/packageVersion.d.mts +1 -1
- package/lib/packageVersion.mjs +1 -1
- package/lib/packageVersion.mjs.map +1 -1
- package/lib/retryErrorsStorageAdapter.d.mts +2 -1
- package/lib/retryErrorsStorageAdapter.d.mts.map +1 -1
- package/lib/retryErrorsStorageAdapter.mjs +9 -1
- package/lib/retryErrorsStorageAdapter.mjs.map +1 -1
- package/lib/retryUtils.mjs +2 -2
- package/lib/retryUtils.mjs.map +1 -1
- package/lib/zipItDataRepresentationUtils.mjs +2 -2
- package/lib/zipItDataRepresentationUtils.mjs.map +1 -1
- package/package.json +25 -16
- package/src/compactSnapshotParser.ts +10 -9
- package/src/compactSnapshotWriter.ts +3 -3
- package/src/contracts.ts +17 -0
- package/src/createFile.ts +10 -38
- package/src/createNewContainerOnExistingFile.ts +2 -2
- package/src/createNewUtils.ts +7 -6
- package/src/createOdspCreateContainerRequest.ts +2 -2
- package/src/epochTracker.ts +4 -4
- package/src/fetchSnapshot.ts +21 -22
- package/src/getFileLink.ts +3 -3
- package/src/localOdspDriver/localOdspDocumentService.ts +9 -2
- package/src/localOdspDriver/localOdspDocumentStorageManager.ts +10 -3
- package/src/odspCache.ts +2 -2
- package/src/odspDelayLoadedDeltaStream.ts +67 -6
- package/src/odspDocumentService.ts +10 -2
- package/src/odspDocumentServiceFactoryCore.ts +3 -11
- package/src/odspDocumentStorageManager.ts +60 -27
- package/src/odspDocumentStorageServiceBase.ts +8 -5
- package/src/odspDriverUrlResolver.ts +3 -17
- package/src/odspError.ts +2 -3
- package/src/odspPublicUtils.ts +1 -0
- package/src/odspSnapshotParser.ts +5 -6
- package/src/odspUtils.ts +34 -28
- package/src/packageVersion.ts +1 -1
- package/src/retryErrorsStorageAdapter.ts +12 -1
- package/src/retryUtils.ts +2 -2
- package/src/zipItDataRepresentationUtils.ts +2 -2
- /package/{.eslintrc.js → .eslintrc.cjs} +0 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { performance } from "@fluid-internal/client-utils";
|
|
7
|
+
import { ISignalEnvelope } from "@fluidframework/core-interfaces";
|
|
7
8
|
import { assert } from "@fluidframework/core-utils";
|
|
8
9
|
import {
|
|
9
10
|
IFluidErrorBase,
|
|
@@ -14,20 +15,23 @@ import {
|
|
|
14
15
|
IDocumentDeltaConnection,
|
|
15
16
|
IResolvedUrl,
|
|
16
17
|
IDocumentServicePolicies,
|
|
17
|
-
DriverErrorType,
|
|
18
18
|
} from "@fluidframework/driver-definitions";
|
|
19
19
|
import {
|
|
20
20
|
DeltaStreamConnectionForbiddenError,
|
|
21
21
|
NonRetryableError,
|
|
22
22
|
} from "@fluidframework/driver-utils";
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
IClient,
|
|
25
|
+
ISequencedDocumentMessage,
|
|
26
|
+
ISignalMessage,
|
|
27
|
+
} from "@fluidframework/protocol-definitions";
|
|
24
28
|
import {
|
|
25
29
|
IOdspResolvedUrl,
|
|
26
30
|
TokenFetchOptions,
|
|
27
31
|
HostStoragePolicy,
|
|
28
32
|
InstrumentedStorageTokenFetcher,
|
|
29
33
|
ISocketStorageDiscovery,
|
|
30
|
-
|
|
34
|
+
OdspErrorTypes,
|
|
31
35
|
} from "@fluidframework/odsp-driver-definitions";
|
|
32
36
|
import { hasFacetCodes } from "@fluidframework/odsp-doclib-utils";
|
|
33
37
|
import { IOdspCache } from "./odspCache";
|
|
@@ -40,6 +44,7 @@ import {
|
|
|
40
44
|
import { fetchJoinSession } from "./vroom";
|
|
41
45
|
import { EpochTracker } from "./epochTracker";
|
|
42
46
|
import { pkgVersion as driverVersion } from "./packageVersion";
|
|
47
|
+
import { policyLabelsUpdatesSignalType } from "./contracts";
|
|
43
48
|
|
|
44
49
|
/**
|
|
45
50
|
* This OdspDelayLoadedDeltaStream is used by OdspDocumentService.ts to delay load the delta connection
|
|
@@ -55,6 +60,12 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
55
60
|
|
|
56
61
|
private _relayServiceTenantAndSessionId: string | undefined;
|
|
57
62
|
|
|
63
|
+
// Tracks the time at which the Policy Labels were updated the last time. This is used to resolve race conditions
|
|
64
|
+
// between label updates from the join session and the Fluid signals and they could have same or different timestamps.
|
|
65
|
+
// So this timestamp is updated with timestamp from the service/signals with the most recent timestamp. We could also
|
|
66
|
+
// receive stale data from join session as that call is made at intervals, so we need to update with only most recent data.
|
|
67
|
+
private labelUpdateTimestamp: number = -1;
|
|
68
|
+
|
|
58
69
|
/**
|
|
59
70
|
* @param odspResolvedUrl - resolved url identifying document that will be managed by this service instance.
|
|
60
71
|
* @param policies - Document service policies.
|
|
@@ -82,6 +93,7 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
82
93
|
private readonly hostPolicy: HostStoragePolicy,
|
|
83
94
|
private readonly epochTracker: EpochTracker,
|
|
84
95
|
private readonly opsReceived: (ops: ISequencedDocumentMessage[]) => void,
|
|
96
|
+
private readonly metadataUpdateHandler: (metadata: Record<string, string>) => void,
|
|
85
97
|
private readonly socketReferenceKeyPrefix?: string,
|
|
86
98
|
) {
|
|
87
99
|
this.joinSessionKey = getJoinSessionCacheKey(this.odspResolvedUrl);
|
|
@@ -155,13 +167,18 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
155
167
|
throw this.annotateConnectionError(
|
|
156
168
|
new NonRetryableError(
|
|
157
169
|
"Websocket token is null",
|
|
158
|
-
|
|
170
|
+
OdspErrorTypes.fetchTokenError,
|
|
159
171
|
{ driverVersion },
|
|
160
172
|
),
|
|
161
173
|
"getWebsocketToken",
|
|
162
174
|
!requestWebsocketTokenFromJoinSession,
|
|
163
175
|
);
|
|
164
176
|
}
|
|
177
|
+
if (websocketEndpoint.sensitivityLabelsInfo !== undefined) {
|
|
178
|
+
this.emitMetaDataUpdateEvent({
|
|
179
|
+
sensitivityLabelsInfo: websocketEndpoint.sensitivityLabelsInfo,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
165
182
|
try {
|
|
166
183
|
const connection = await this.createDeltaConnection(
|
|
167
184
|
websocketEndpoint.tenantId,
|
|
@@ -173,6 +190,9 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
173
190
|
connection.on("op", (documentId, ops: ISequencedDocumentMessage[]) => {
|
|
174
191
|
this.opsReceived(ops);
|
|
175
192
|
});
|
|
193
|
+
connection.on("signal", this.signalHandler);
|
|
194
|
+
// Also process the initial signals
|
|
195
|
+
this.signalHandler(connection.initialSignals);
|
|
176
196
|
// On disconnect with 401/403 error code, we can just clear the joinSession cache as we will again
|
|
177
197
|
// get the auth error on reconnecting and face latency.
|
|
178
198
|
connection.once("disconnect", (error: any) => {
|
|
@@ -181,7 +201,7 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
181
201
|
if (
|
|
182
202
|
typeof error === "object" &&
|
|
183
203
|
error !== null &&
|
|
184
|
-
error.errorType ===
|
|
204
|
+
error.errorType === OdspErrorTypes.authorizationError
|
|
185
205
|
) {
|
|
186
206
|
this.cache.sessionJoinCache.remove(this.joinSessionKey);
|
|
187
207
|
}
|
|
@@ -211,6 +231,26 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
211
231
|
});
|
|
212
232
|
}
|
|
213
233
|
|
|
234
|
+
private readonly signalHandler = (signalsArg: ISignalMessage | ISignalMessage[]) => {
|
|
235
|
+
const signals = Array.isArray(signalsArg) ? signalsArg : [signalsArg];
|
|
236
|
+
signals.forEach((signal: ISignalMessage) => {
|
|
237
|
+
// Make sure it is not for a specific client as `PolicyLabelsUpdate` is meant for all clients.
|
|
238
|
+
if (signal.clientId === null) {
|
|
239
|
+
// We could have some issues/irregularities in parsing signals, so put it in try/catch block
|
|
240
|
+
// and ignore the error as we can have labels update later on through join session response.
|
|
241
|
+
let envelope: ISignalEnvelope | undefined;
|
|
242
|
+
try {
|
|
243
|
+
envelope = JSON.parse(signal.content as string) as ISignalEnvelope;
|
|
244
|
+
} catch (err) {}
|
|
245
|
+
if (envelope?.contents?.type === policyLabelsUpdatesSignalType) {
|
|
246
|
+
this.emitMetaDataUpdateEvent({
|
|
247
|
+
sensitivityLabelsInfo: JSON.stringify(envelope.contents.content),
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
};
|
|
253
|
+
|
|
214
254
|
private clearJoinSessionTimer() {
|
|
215
255
|
if (this.joinSessionRefreshTimer !== undefined) {
|
|
216
256
|
clearTimeout(this.joinSessionRefreshTimer);
|
|
@@ -273,7 +313,7 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
273
313
|
this.clearJoinSessionTimer();
|
|
274
314
|
throw new NonRetryableError(
|
|
275
315
|
"JoinSessionRefreshTimerNotCancelled",
|
|
276
|
-
|
|
316
|
+
OdspErrorTypes.genericError,
|
|
277
317
|
{
|
|
278
318
|
driverVersion,
|
|
279
319
|
details: JSON.stringify({
|
|
@@ -339,6 +379,12 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
339
379
|
isRefreshingJoinSession,
|
|
340
380
|
this.hostPolicy.sessionOptions?.unauthenticatedUserDisplayName,
|
|
341
381
|
);
|
|
382
|
+
// Emit event only in case it is fetched from the network.
|
|
383
|
+
if (joinSessionResponse.sensitivityLabelsInfo !== undefined) {
|
|
384
|
+
this.emitMetaDataUpdateEvent({
|
|
385
|
+
sensitivityLabelsInfo: joinSessionResponse.sensitivityLabelsInfo,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
342
388
|
return {
|
|
343
389
|
entryTime: Date.now(),
|
|
344
390
|
joinSessionResponse,
|
|
@@ -402,6 +448,21 @@ export class OdspDelayLoadedDeltaStream {
|
|
|
402
448
|
return response.joinSessionResponse;
|
|
403
449
|
}
|
|
404
450
|
|
|
451
|
+
private emitMetaDataUpdateEvent(metadata: Record<string, string>) {
|
|
452
|
+
const label = JSON.parse(metadata.sensitivityLabelsInfo) as {
|
|
453
|
+
labels: unknown;
|
|
454
|
+
timestamp: number;
|
|
455
|
+
};
|
|
456
|
+
const time = label.timestamp;
|
|
457
|
+
assert(time > 0, "time should be positive");
|
|
458
|
+
if (time > this.labelUpdateTimestamp) {
|
|
459
|
+
this.labelUpdateTimestamp = time;
|
|
460
|
+
this.metadataUpdateHandler({
|
|
461
|
+
sensitivityLabelsInfo: metadata.sensitivityLabelsInfo,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
405
466
|
private calculateJoinSessionRefreshDelta(
|
|
406
467
|
responseFetchTime: number,
|
|
407
468
|
refreshSessionDurationSeconds: number,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
createChildMonitoringContext,
|
|
9
9
|
MonitoringContext,
|
|
10
10
|
} from "@fluidframework/telemetry-utils";
|
|
11
|
+
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
11
12
|
import { assert } from "@fluidframework/core-utils";
|
|
12
13
|
import {
|
|
13
14
|
IDocumentDeltaConnection,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
IResolvedUrl,
|
|
17
18
|
IDocumentStorageService,
|
|
18
19
|
IDocumentServicePolicies,
|
|
20
|
+
IDocumentServiceEvents,
|
|
19
21
|
} from "@fluidframework/driver-definitions";
|
|
20
22
|
import { IClient, ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
21
23
|
import {
|
|
@@ -40,7 +42,10 @@ import type { OdspDelayLoadedDeltaStream } from "./odspDelayLoadedDeltaStream";
|
|
|
40
42
|
* The DocumentService manages the Socket.IO connection and manages routing requests to connected
|
|
41
43
|
* clients
|
|
42
44
|
*/
|
|
43
|
-
export class OdspDocumentService
|
|
45
|
+
export class OdspDocumentService
|
|
46
|
+
extends TypedEventEmitter<IDocumentServiceEvents>
|
|
47
|
+
implements IDocumentService
|
|
48
|
+
{
|
|
44
49
|
private readonly _policies: IDocumentServicePolicies;
|
|
45
50
|
|
|
46
51
|
// Promise to load socket module only once.
|
|
@@ -123,6 +128,7 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
123
128
|
private readonly socketReferenceKeyPrefix?: string,
|
|
124
129
|
private readonly clientIsSummarizer?: boolean,
|
|
125
130
|
) {
|
|
131
|
+
super();
|
|
126
132
|
this._policies = {
|
|
127
133
|
// load in storage-only mode if a file version is specified
|
|
128
134
|
storageOnly: odspResolvedUrl.fileVersion !== undefined,
|
|
@@ -141,6 +147,7 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
141
147
|
});
|
|
142
148
|
|
|
143
149
|
this.hostPolicy = hostPolicy;
|
|
150
|
+
this.hostPolicy.supportGetSnapshotApi = this._policies.supportGetSnapshotApi;
|
|
144
151
|
if (this.clientIsSummarizer) {
|
|
145
152
|
this.hostPolicy = { ...this.hostPolicy, summarizerClient: true };
|
|
146
153
|
}
|
|
@@ -282,6 +289,7 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
282
289
|
this.hostPolicy,
|
|
283
290
|
this.epochTracker,
|
|
284
291
|
(ops: ISequencedDocumentMessage[]) => this.opsReceived(ops),
|
|
292
|
+
(metadata: Record<string, string>) => this.emit("metadataUpdate", metadata),
|
|
285
293
|
this.socketReferenceKeyPrefix,
|
|
286
294
|
);
|
|
287
295
|
return this.odspDelayLoadedDeltaStream;
|
|
@@ -289,7 +297,7 @@ export class OdspDocumentService implements IDocumentService {
|
|
|
289
297
|
|
|
290
298
|
public dispose(error?: any) {
|
|
291
299
|
// Error might indicate mismatch between client & server knowledge about file
|
|
292
|
-
// (
|
|
300
|
+
// (OdspErrorTypes.fileOverwrittenInStorage).
|
|
293
301
|
// For example, file might have been overwritten in storage without generating new epoch
|
|
294
302
|
// In such case client cached info is stale and has to be removed.
|
|
295
303
|
if (error !== undefined) {
|
|
@@ -26,7 +26,6 @@ import {
|
|
|
26
26
|
IOdspUrlParts,
|
|
27
27
|
SharingLinkScope,
|
|
28
28
|
SharingLinkRole,
|
|
29
|
-
ShareLinkTypes,
|
|
30
29
|
ISharingLinkKind,
|
|
31
30
|
ISocketStorageDiscovery,
|
|
32
31
|
IRelaySessionAwareDriverFactory,
|
|
@@ -102,7 +101,7 @@ export class OdspDocumentServiceFactoryCore
|
|
|
102
101
|
};
|
|
103
102
|
|
|
104
103
|
let fileInfo: INewFileInfo | IExistingFileInfo;
|
|
105
|
-
let createShareLinkParam:
|
|
104
|
+
let createShareLinkParam: ISharingLinkKind | undefined;
|
|
106
105
|
if (odspResolvedUrl.itemId) {
|
|
107
106
|
fileInfo = {
|
|
108
107
|
type: "Existing",
|
|
@@ -161,7 +160,6 @@ export class OdspDocumentServiceFactoryCore
|
|
|
161
160
|
createShareLinkParam: createShareLinkParam
|
|
162
161
|
? JSON.stringify(createShareLinkParam)
|
|
163
162
|
: undefined,
|
|
164
|
-
enableShareLinkWithCreate: this.hostPolicy.enableShareLinkWithCreate,
|
|
165
163
|
enableSingleRequestForShareLinkWithCreate:
|
|
166
164
|
this.hostPolicy.enableSingleRequestForShareLinkWithCreate,
|
|
167
165
|
},
|
|
@@ -202,7 +200,6 @@ export class OdspDocumentServiceFactoryCore
|
|
|
202
200
|
?.forceAccessTokenViaAuthorizationHeader,
|
|
203
201
|
odspResolvedUrl.isClpCompliantApp,
|
|
204
202
|
this.hostPolicy.enableSingleRequestForShareLinkWithCreate,
|
|
205
|
-
this.hostPolicy.enableShareLinkWithCreate,
|
|
206
203
|
)
|
|
207
204
|
: await module.createNewContainerOnExistingFile(
|
|
208
205
|
getStorageToken,
|
|
@@ -330,9 +327,9 @@ export class OdspDocumentServiceFactoryCore
|
|
|
330
327
|
function getSharingLinkParams(
|
|
331
328
|
hostPolicy: HostStoragePolicy,
|
|
332
329
|
searchParams: URLSearchParams,
|
|
333
|
-
):
|
|
330
|
+
): ISharingLinkKind | undefined {
|
|
334
331
|
// extract request parameters for creation of sharing link (if provided) if the feature is enabled
|
|
335
|
-
let createShareLinkParam:
|
|
332
|
+
let createShareLinkParam: ISharingLinkKind | undefined;
|
|
336
333
|
if (hostPolicy.enableSingleRequestForShareLinkWithCreate) {
|
|
337
334
|
const createLinkScope = searchParams.get("createLinkScope");
|
|
338
335
|
const createLinkRole = searchParams.get("createLinkRole");
|
|
@@ -344,11 +341,6 @@ function getSharingLinkParams(
|
|
|
344
341
|
: {}),
|
|
345
342
|
};
|
|
346
343
|
}
|
|
347
|
-
} else if (hostPolicy.enableShareLinkWithCreate) {
|
|
348
|
-
const createLinkType = searchParams.get("createLinkType");
|
|
349
|
-
if (createLinkType && ShareLinkTypes[createLinkType]) {
|
|
350
|
-
createShareLinkParam = ShareLinkTypes[createLinkType || ""];
|
|
351
|
-
}
|
|
352
344
|
}
|
|
353
345
|
return createShareLinkParam;
|
|
354
346
|
}
|
|
@@ -16,12 +16,17 @@ import { assert, delay } from "@fluidframework/core-utils";
|
|
|
16
16
|
import { LogLevel } from "@fluidframework/core-interfaces";
|
|
17
17
|
import * as api from "@fluidframework/protocol-definitions";
|
|
18
18
|
import { promiseRaceWithWinner } from "@fluidframework/driver-base";
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
ISummaryContext,
|
|
21
|
+
FetchSource,
|
|
22
|
+
ISnapshot,
|
|
23
|
+
ISnapshotFetchOptions,
|
|
24
|
+
} from "@fluidframework/driver-definitions";
|
|
20
25
|
import { RateLimiter, NonRetryableError } from "@fluidframework/driver-utils";
|
|
21
26
|
import {
|
|
22
27
|
IOdspResolvedUrl,
|
|
23
28
|
ISnapshotOptions,
|
|
24
|
-
|
|
29
|
+
OdspErrorTypes,
|
|
25
30
|
InstrumentedStorageTokenFetcher,
|
|
26
31
|
getKeyForCacheEntry,
|
|
27
32
|
} from "@fluidframework/odsp-driver-definitions";
|
|
@@ -30,6 +35,7 @@ import {
|
|
|
30
35
|
HostStoragePolicyInternal,
|
|
31
36
|
IVersionedValueWithEpoch,
|
|
32
37
|
ISnapshotCachedEntry,
|
|
38
|
+
ISnapshotCachedEntry2,
|
|
33
39
|
} from "./contracts";
|
|
34
40
|
import {
|
|
35
41
|
downloadSnapshot,
|
|
@@ -40,8 +46,11 @@ import {
|
|
|
40
46
|
} from "./fetchSnapshot";
|
|
41
47
|
import { getUrlAndHeadersWithAuth } from "./getUrlAndHeadersWithAuth";
|
|
42
48
|
import { IOdspCache, IPrefetchSnapshotContents } from "./odspCache";
|
|
43
|
-
import {
|
|
44
|
-
|
|
49
|
+
import {
|
|
50
|
+
createCacheSnapshotKey,
|
|
51
|
+
getWithRetryForTokenRefresh,
|
|
52
|
+
isInstanceOfISnapshot,
|
|
53
|
+
} from "./odspUtils";
|
|
45
54
|
import { EpochTracker } from "./epochTracker";
|
|
46
55
|
import type { OdspSummaryUploadManager } from "./odspSummaryUploadManager";
|
|
47
56
|
import { FlushResult } from "./odspDocumentDeltaConnection";
|
|
@@ -204,6 +213,15 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
204
213
|
return super.getSnapshotTree(version, scenarioName);
|
|
205
214
|
}
|
|
206
215
|
|
|
216
|
+
public async getSnapshot(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot> {
|
|
217
|
+
assert(this.hostPolicy.supportGetSnapshotApi !== true, "api should not be called yet");
|
|
218
|
+
// This is just temporary as this api is not yet enabled in service policies.
|
|
219
|
+
return this.fetchSnapshot(
|
|
220
|
+
this.hostPolicy.snapshotOptions,
|
|
221
|
+
snapshotFetchOptions?.scenarioName,
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
207
225
|
public async getVersions(
|
|
208
226
|
// eslint-disable-next-line @rushstack/no-new-null
|
|
209
227
|
blobid: string | null,
|
|
@@ -233,16 +251,13 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
233
251
|
// If count is one, we can use the trees/latest API, which returns the latest version and trees in a single request for better performance
|
|
234
252
|
if (count === 1 && (blobid === null || blobid === this.documentId)) {
|
|
235
253
|
const hostSnapshotOptions = this.hostPolicy.snapshotOptions;
|
|
236
|
-
const odspSnapshotCacheValue:
|
|
254
|
+
const odspSnapshotCacheValue: ISnapshot = await PerformanceEvent.timedExecAsync(
|
|
237
255
|
this.logger,
|
|
238
256
|
{ eventName: "ObtainSnapshot", fetchSource },
|
|
239
257
|
async (event: PerformanceEvent) => {
|
|
240
258
|
const props: GetVersionsTelemetryProps = {};
|
|
241
259
|
let cacheLookupTimeInSerialFetch = 0;
|
|
242
|
-
let retrievedSnapshot:
|
|
243
|
-
| ISnapshotContents
|
|
244
|
-
| IPrefetchSnapshotContents
|
|
245
|
-
| undefined;
|
|
260
|
+
let retrievedSnapshot: ISnapshot | IPrefetchSnapshotContents | undefined;
|
|
246
261
|
|
|
247
262
|
let method: string;
|
|
248
263
|
let prefetchWaitStartTime: number = performance.now();
|
|
@@ -255,10 +270,14 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
255
270
|
} else {
|
|
256
271
|
// Here's the logic to grab the persistent cache snapshot implemented by the host
|
|
257
272
|
// Epoch tracker is responsible for communicating with the persistent cache, handling epochs and cache versions
|
|
258
|
-
const cachedSnapshotP: Promise<
|
|
259
|
-
this.
|
|
260
|
-
|
|
261
|
-
|
|
273
|
+
const cachedSnapshotP: Promise<ISnapshot | undefined> = this.epochTracker
|
|
274
|
+
.get(createCacheSnapshotKey(this.odspResolvedUrl))
|
|
275
|
+
.then(
|
|
276
|
+
async (
|
|
277
|
+
snapshotCachedEntry:
|
|
278
|
+
| ISnapshotCachedEntry
|
|
279
|
+
| ISnapshotCachedEntry2,
|
|
280
|
+
) => {
|
|
262
281
|
if (snapshotCachedEntry !== undefined) {
|
|
263
282
|
// If the cached entry does not contain the entry time, then assign it a default of 30 days old.
|
|
264
283
|
const age =
|
|
@@ -281,10 +300,24 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
281
300
|
|
|
282
301
|
// Record the cache age
|
|
283
302
|
props.cacheEntryAge = age;
|
|
303
|
+
// Snapshot from cache could be in older format, so transform that before returning.
|
|
304
|
+
if (isInstanceOfISnapshot(snapshotCachedEntry)) {
|
|
305
|
+
return snapshotCachedEntry;
|
|
306
|
+
} else {
|
|
307
|
+
const snapshot: ISnapshot = {
|
|
308
|
+
snapshotTree: snapshotCachedEntry.snapshotTree,
|
|
309
|
+
blobContents: snapshotCachedEntry.blobs,
|
|
310
|
+
ops: snapshotCachedEntry.ops,
|
|
311
|
+
latestSequenceNumber:
|
|
312
|
+
snapshotCachedEntry.latestSequenceNumber,
|
|
313
|
+
sequenceNumber: snapshotCachedEntry.sequenceNumber,
|
|
314
|
+
snapshotFormatV: 1,
|
|
315
|
+
};
|
|
316
|
+
return snapshot;
|
|
317
|
+
}
|
|
284
318
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
});
|
|
319
|
+
},
|
|
320
|
+
);
|
|
288
321
|
// Based on the concurrentSnapshotFetch policy:
|
|
289
322
|
// Either retrieve both the network and cache snapshots concurrently and pick the first to return,
|
|
290
323
|
// or grab the cache value and then the network value if the cache value returns undefined.
|
|
@@ -427,14 +460,14 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
427
460
|
if (!versionsResponse) {
|
|
428
461
|
throw new NonRetryableError(
|
|
429
462
|
"No response from /versions endpoint",
|
|
430
|
-
|
|
463
|
+
OdspErrorTypes.genericNetworkError,
|
|
431
464
|
{ driverVersion },
|
|
432
465
|
);
|
|
433
466
|
}
|
|
434
467
|
if (!Array.isArray(versionsResponse.value)) {
|
|
435
468
|
throw new NonRetryableError(
|
|
436
469
|
"Incorrect response from /versions endpoint, expected an array",
|
|
437
|
-
|
|
470
|
+
OdspErrorTypes.genericNetworkError,
|
|
438
471
|
{ driverVersion },
|
|
439
472
|
);
|
|
440
473
|
}
|
|
@@ -467,7 +500,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
467
500
|
private async fetchSnapshotCore(
|
|
468
501
|
hostSnapshotOptions: ISnapshotOptions | undefined,
|
|
469
502
|
scenarioName?: string,
|
|
470
|
-
): Promise<
|
|
503
|
+
): Promise<ISnapshot | IPrefetchSnapshotContents> {
|
|
471
504
|
// Don't look into cache, if the host specifically tells us so.
|
|
472
505
|
if (!this.hostPolicy.avoidPrefetchSnapshotCache) {
|
|
473
506
|
const prefetchCacheKey = getKeyForCacheEntry(
|
|
@@ -554,7 +587,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
554
587
|
const errorType = error.errorType;
|
|
555
588
|
// If the snapshot size is too big and the host specified the size limitation(specified in hostSnapshotOptions), then don't try to fetch the snapshot again.
|
|
556
589
|
if (
|
|
557
|
-
errorType ===
|
|
590
|
+
errorType === OdspErrorTypes.snapshotTooBig &&
|
|
558
591
|
hostSnapshotOptions?.mds !== undefined &&
|
|
559
592
|
this.hostPolicy.summarizerClient !== true
|
|
560
593
|
) {
|
|
@@ -562,8 +595,8 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
562
595
|
}
|
|
563
596
|
// If the first snapshot request was with blobs and we either timed out or the size was too big, then try to fetch without blobs.
|
|
564
597
|
if (
|
|
565
|
-
(errorType ===
|
|
566
|
-
errorType ===
|
|
598
|
+
(errorType === OdspErrorTypes.snapshotTooBig ||
|
|
599
|
+
errorType === OdspErrorTypes.fetchTimeout) &&
|
|
567
600
|
snapshotOptions.blobs
|
|
568
601
|
) {
|
|
569
602
|
this.logger.sendErrorEvent({
|
|
@@ -684,7 +717,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
684
717
|
if (!this.snapshotUrl) {
|
|
685
718
|
throw new NonRetryableError(
|
|
686
719
|
"Method failed because no snapshot url was available",
|
|
687
|
-
|
|
720
|
+
OdspErrorTypes.genericError,
|
|
688
721
|
{ driverVersion },
|
|
689
722
|
);
|
|
690
723
|
}
|
|
@@ -694,7 +727,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
694
727
|
if (!this.attachmentPOSTUrl) {
|
|
695
728
|
throw new NonRetryableError(
|
|
696
729
|
"Method failed because no attachment POST url was available",
|
|
697
|
-
|
|
730
|
+
OdspErrorTypes.genericError,
|
|
698
731
|
{ driverVersion },
|
|
699
732
|
);
|
|
700
733
|
}
|
|
@@ -704,7 +737,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
704
737
|
if (!this.attachmentGETUrl) {
|
|
705
738
|
throw new NonRetryableError(
|
|
706
739
|
"Method failed because no attachment GET url was available",
|
|
707
|
-
|
|
740
|
+
OdspErrorTypes.genericError,
|
|
708
741
|
{ driverVersion },
|
|
709
742
|
);
|
|
710
743
|
}
|
|
@@ -746,8 +779,8 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
|
|
|
746
779
|
treeId = snapshot.snapshotTree.id;
|
|
747
780
|
this.setRootTree(treeId, snapshot.snapshotTree);
|
|
748
781
|
}
|
|
749
|
-
if (snapshot.
|
|
750
|
-
this.initBlobsCache(snapshot.
|
|
782
|
+
if (snapshot.blobContents) {
|
|
783
|
+
this.initBlobsCache(snapshot.blobContents);
|
|
751
784
|
}
|
|
752
785
|
// If the version id doesn't match with the id of the tree, then use the id of first tree which in that case
|
|
753
786
|
// will be the actual id of tree to be fetched.
|
|
@@ -11,10 +11,11 @@ import {
|
|
|
11
11
|
LoaderCachingPolicy,
|
|
12
12
|
FiveDaysMs,
|
|
13
13
|
FetchSource,
|
|
14
|
+
ISnapshot,
|
|
15
|
+
ISnapshotFetchOptions,
|
|
14
16
|
} from "@fluidframework/driver-definitions";
|
|
15
17
|
import * as api from "@fluidframework/protocol-definitions";
|
|
16
18
|
import { IConfigProvider } from "@fluidframework/telemetry-utils";
|
|
17
|
-
import { ISnapshotContents } from "./odspPublicUtils";
|
|
18
19
|
|
|
19
20
|
const maximumCacheDurationMs: FiveDaysMs = 432000000; // 5 * 24 * 60 * 60 * 1000 = 5 days in ms
|
|
20
21
|
|
|
@@ -208,6 +209,8 @@ export abstract class OdspDocumentStorageServiceBase implements IDocumentStorage
|
|
|
208
209
|
return this.combineProtocolAndAppSnapshotTree(appTree, protocolTree);
|
|
209
210
|
}
|
|
210
211
|
|
|
212
|
+
public abstract getSnapshot(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot>;
|
|
213
|
+
|
|
211
214
|
public abstract getVersions(
|
|
212
215
|
// eslint-disable-next-line @rushstack/no-new-null
|
|
213
216
|
blobid: string | null,
|
|
@@ -267,11 +270,11 @@ export abstract class OdspDocumentStorageServiceBase implements IDocumentStorage
|
|
|
267
270
|
}
|
|
268
271
|
|
|
269
272
|
protected initializeFromSnapshot(
|
|
270
|
-
odspSnapshotCacheValue:
|
|
273
|
+
odspSnapshotCacheValue: ISnapshot,
|
|
271
274
|
cacheOps: boolean = true,
|
|
272
275
|
): string | undefined {
|
|
273
276
|
this._snapshotSequenceNumber = odspSnapshotCacheValue.sequenceNumber;
|
|
274
|
-
const { snapshotTree,
|
|
277
|
+
const { snapshotTree, blobContents, ops } = odspSnapshotCacheValue;
|
|
275
278
|
|
|
276
279
|
// id should be undefined in case of just ops in snapshot.
|
|
277
280
|
let id: string | undefined;
|
|
@@ -281,8 +284,8 @@ export abstract class OdspDocumentStorageServiceBase implements IDocumentStorage
|
|
|
281
284
|
this.setRootTree(id, snapshotTree);
|
|
282
285
|
}
|
|
283
286
|
|
|
284
|
-
if (
|
|
285
|
-
this.initBlobsCache(
|
|
287
|
+
if (blobContents) {
|
|
288
|
+
this.initBlobsCache(blobContents);
|
|
286
289
|
}
|
|
287
290
|
|
|
288
291
|
if (cacheOps) {
|
|
@@ -5,17 +5,12 @@
|
|
|
5
5
|
import { assert } from "@fluidframework/core-utils";
|
|
6
6
|
import { IRequest } from "@fluidframework/core-interfaces";
|
|
7
7
|
import {
|
|
8
|
-
DriverErrorType,
|
|
9
8
|
DriverHeader,
|
|
10
9
|
IContainerPackageInfo,
|
|
11
10
|
IResolvedUrl,
|
|
12
11
|
IUrlResolver,
|
|
13
12
|
} from "@fluidframework/driver-definitions";
|
|
14
|
-
import {
|
|
15
|
-
IOdspResolvedUrl,
|
|
16
|
-
ShareLinkTypes,
|
|
17
|
-
ShareLinkInfoType,
|
|
18
|
-
} from "@fluidframework/odsp-driver-definitions";
|
|
13
|
+
import { IOdspResolvedUrl, OdspErrorTypes } from "@fluidframework/odsp-driver-definitions";
|
|
19
14
|
import { NonRetryableError } from "@fluidframework/driver-utils";
|
|
20
15
|
import { createOdspUrl } from "./createOdspUrl";
|
|
21
16
|
import { getApiRoot } from "./odspUrlHelper";
|
|
@@ -97,23 +92,14 @@ export class OdspDriverUrlResolver implements IUrlResolver {
|
|
|
97
92
|
const driveID = searchParams.get("driveId");
|
|
98
93
|
const filePath = searchParams.get("path");
|
|
99
94
|
const packageName = searchParams.get("containerPackageName");
|
|
100
|
-
const createLinkType = searchParams.get("createLinkType");
|
|
101
95
|
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain -- false positive
|
|
102
96
|
if (!(fileName && siteURL && driveID && filePath !== null && filePath !== undefined)) {
|
|
103
97
|
throw new NonRetryableError(
|
|
104
98
|
"Proper new file params should be there!!",
|
|
105
|
-
|
|
99
|
+
OdspErrorTypes.genericError,
|
|
106
100
|
{ driverVersion: pkgVersion },
|
|
107
101
|
);
|
|
108
102
|
}
|
|
109
|
-
let shareLinkInfo: ShareLinkInfoType | undefined;
|
|
110
|
-
if (createLinkType && createLinkType in ShareLinkTypes) {
|
|
111
|
-
shareLinkInfo = {
|
|
112
|
-
createLink: {
|
|
113
|
-
type: ShareLinkTypes[createLinkType],
|
|
114
|
-
},
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
103
|
return {
|
|
118
104
|
endpoints: {
|
|
119
105
|
snapshotStorageUrl: "",
|
|
@@ -136,7 +122,7 @@ export class OdspDriverUrlResolver implements IUrlResolver {
|
|
|
136
122
|
containerPackageName: packageName ?? undefined,
|
|
137
123
|
},
|
|
138
124
|
fileVersion: undefined,
|
|
139
|
-
shareLinkInfo,
|
|
125
|
+
shareLinkInfo: undefined,
|
|
140
126
|
isClpCompliantApp: request.headers?.[ClpCompliantAppHeader.isClpCompliantApp],
|
|
141
127
|
};
|
|
142
128
|
}
|
package/src/odspError.ts
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { createOdspNetworkError } from "@fluidframework/odsp-doclib-utils";
|
|
7
|
-
import { DriverErrorType } from "@fluidframework/driver-definitions";
|
|
8
7
|
import { NonRetryableError } from "@fluidframework/driver-utils";
|
|
9
|
-
import { OdspError } from "@fluidframework/odsp-driver-definitions";
|
|
8
|
+
import { OdspError, OdspErrorTypes } from "@fluidframework/odsp-driver-definitions";
|
|
10
9
|
import { getCircularReplacer, IFluidErrorBase } from "@fluidframework/telemetry-utils";
|
|
11
10
|
import { IOdspSocketError } from "./contracts";
|
|
12
11
|
import { pkgVersion as driverVersion } from "./packageVersion";
|
|
@@ -37,7 +36,7 @@ export function errorObjectFromSocketError(
|
|
|
37
36
|
} catch (error) {
|
|
38
37
|
return new NonRetryableError(
|
|
39
38
|
"Internal error: errorObjectFromSocketError",
|
|
40
|
-
|
|
39
|
+
OdspErrorTypes.fileNotFoundOrAccessDeniedError,
|
|
41
40
|
{ driverVersion },
|
|
42
41
|
);
|
|
43
42
|
}
|
package/src/odspPublicUtils.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
import { stringToBuffer } from "@fluid-internal/client-utils";
|
|
7
7
|
import { assert } from "@fluidframework/core-utils";
|
|
8
8
|
import * as api from "@fluidframework/protocol-definitions";
|
|
9
|
+
import { ISnapshot } from "@fluidframework/driver-definitions";
|
|
9
10
|
import { IOdspSnapshot, IOdspSnapshotCommit } from "./contracts";
|
|
10
|
-
import { ISnapshotContents } from "./odspPublicUtils";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Build a tree hierarchy base on a flat tree
|
|
@@ -51,9 +51,7 @@ function buildHierarchy(flatTree: IOdspSnapshotCommit): api.ISnapshotTree {
|
|
|
51
51
|
* Converts existing IOdspSnapshot to snapshot tree, blob array and ops
|
|
52
52
|
* @param odspSnapshot - snapshot
|
|
53
53
|
*/
|
|
54
|
-
export function convertOdspSnapshotToSnapshotTreeAndBlobs(
|
|
55
|
-
odspSnapshot: IOdspSnapshot,
|
|
56
|
-
): ISnapshotContents {
|
|
54
|
+
export function convertOdspSnapshotToSnapshotTreeAndBlobs(odspSnapshot: IOdspSnapshot): ISnapshot {
|
|
57
55
|
const blobsWithBufferContent = new Map<string, ArrayBuffer>();
|
|
58
56
|
if (odspSnapshot.blobs) {
|
|
59
57
|
odspSnapshot.blobs.forEach((blob) => {
|
|
@@ -70,8 +68,8 @@ export function convertOdspSnapshotToSnapshotTreeAndBlobs(
|
|
|
70
68
|
|
|
71
69
|
const sequenceNumber = odspSnapshot?.trees[0].sequenceNumber;
|
|
72
70
|
|
|
73
|
-
const val:
|
|
74
|
-
|
|
71
|
+
const val: ISnapshot = {
|
|
72
|
+
blobContents: blobsWithBufferContent,
|
|
75
73
|
ops: odspSnapshot.ops?.map((op) => op.op) ?? [],
|
|
76
74
|
sequenceNumber,
|
|
77
75
|
snapshotTree: buildHierarchy(odspSnapshot.trees[0]),
|
|
@@ -79,6 +77,7 @@ export function convertOdspSnapshotToSnapshotTreeAndBlobs(
|
|
|
79
77
|
odspSnapshot.ops && odspSnapshot.ops.length > 0
|
|
80
78
|
? odspSnapshot.ops[odspSnapshot.ops.length - 1].sequenceNumber
|
|
81
79
|
: sequenceNumber,
|
|
80
|
+
snapshotFormatV: 1,
|
|
82
81
|
};
|
|
83
82
|
return val;
|
|
84
83
|
}
|