@fluidframework/odsp-driver 2.13.0 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/WriteBufferUtils.js.map +1 -1
  3. package/dist/compactSnapshotParser.js +5 -5
  4. package/dist/compactSnapshotParser.js.map +1 -1
  5. package/dist/fetchSnapshot.d.ts.map +1 -1
  6. package/dist/fetchSnapshot.js +8 -3
  7. package/dist/fetchSnapshot.js.map +1 -1
  8. package/dist/getFileLink.js +3 -3
  9. package/dist/getFileLink.js.map +1 -1
  10. package/dist/index.d.ts +0 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1 -3
  13. package/dist/index.js.map +1 -1
  14. package/dist/odspDelayLoadedDeltaStream.d.ts +2 -1
  15. package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -1
  16. package/dist/odspDelayLoadedDeltaStream.js +12 -11
  17. package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
  18. package/dist/odspDocumentDeltaConnection.js +3 -3
  19. package/dist/odspDocumentDeltaConnection.js.map +1 -1
  20. package/dist/odspDocumentStorageManager.js +6 -6
  21. package/dist/odspDocumentStorageManager.js.map +1 -1
  22. package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
  23. package/dist/odspDocumentStorageServiceBase.js.map +1 -1
  24. package/dist/odspDriverUrlResolver.js +1 -1
  25. package/dist/odspDriverUrlResolver.js.map +1 -1
  26. package/dist/odspUtils.js +6 -6
  27. package/dist/odspUtils.js.map +1 -1
  28. package/dist/opsCaching.js +2 -2
  29. package/dist/opsCaching.js.map +1 -1
  30. package/dist/package.json +2 -1
  31. package/dist/packageVersion.d.ts +1 -1
  32. package/dist/packageVersion.js +1 -1
  33. package/dist/packageVersion.js.map +1 -1
  34. package/dist/prefetchLatestSnapshot.js +1 -1
  35. package/dist/prefetchLatestSnapshot.js.map +1 -1
  36. package/dist/retryUtils.js +4 -4
  37. package/dist/retryUtils.js.map +1 -1
  38. package/dist/vroom.d.ts +4 -3
  39. package/dist/vroom.d.ts.map +1 -1
  40. package/dist/vroom.js +12 -7
  41. package/dist/vroom.js.map +1 -1
  42. package/lib/WriteBufferUtils.js.map +1 -1
  43. package/lib/compactSnapshotParser.js +5 -5
  44. package/lib/compactSnapshotParser.js.map +1 -1
  45. package/lib/fetchSnapshot.d.ts.map +1 -1
  46. package/lib/fetchSnapshot.js +8 -3
  47. package/lib/fetchSnapshot.js.map +1 -1
  48. package/lib/getFileLink.js +3 -3
  49. package/lib/getFileLink.js.map +1 -1
  50. package/lib/index.d.ts +0 -1
  51. package/lib/index.d.ts.map +1 -1
  52. package/lib/index.js +0 -1
  53. package/lib/index.js.map +1 -1
  54. package/lib/odspDelayLoadedDeltaStream.d.ts +2 -1
  55. package/lib/odspDelayLoadedDeltaStream.d.ts.map +1 -1
  56. package/lib/odspDelayLoadedDeltaStream.js +13 -12
  57. package/lib/odspDelayLoadedDeltaStream.js.map +1 -1
  58. package/lib/odspDocumentDeltaConnection.js +4 -4
  59. package/lib/odspDocumentDeltaConnection.js.map +1 -1
  60. package/lib/odspDocumentStorageManager.js +7 -7
  61. package/lib/odspDocumentStorageManager.js.map +1 -1
  62. package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -1
  63. package/lib/odspDocumentStorageServiceBase.js.map +1 -1
  64. package/lib/odspDriverUrlResolver.js +1 -1
  65. package/lib/odspDriverUrlResolver.js.map +1 -1
  66. package/lib/odspUtils.js +7 -7
  67. package/lib/odspUtils.js.map +1 -1
  68. package/lib/opsCaching.js +3 -3
  69. package/lib/opsCaching.js.map +1 -1
  70. package/lib/packageVersion.d.ts +1 -1
  71. package/lib/packageVersion.js +1 -1
  72. package/lib/packageVersion.js.map +1 -1
  73. package/lib/prefetchLatestSnapshot.js +2 -2
  74. package/lib/prefetchLatestSnapshot.js.map +1 -1
  75. package/lib/retryUtils.js +5 -5
  76. package/lib/retryUtils.js.map +1 -1
  77. package/lib/vroom.d.ts +4 -3
  78. package/lib/vroom.d.ts.map +1 -1
  79. package/lib/vroom.js +12 -7
  80. package/lib/vroom.js.map +1 -1
  81. package/package.json +14 -14
  82. package/src/WriteBufferUtils.ts +2 -2
  83. package/src/compactSnapshotParser.ts +5 -5
  84. package/src/fetchSnapshot.ts +7 -8
  85. package/src/getFileLink.ts +2 -3
  86. package/src/index.ts +0 -1
  87. package/src/odspDelayLoadedDeltaStream.ts +14 -5
  88. package/src/odspDocumentDeltaConnection.ts +4 -4
  89. package/src/odspDocumentStorageManager.ts +7 -7
  90. package/src/odspDocumentStorageServiceBase.ts +2 -3
  91. package/src/odspDriverUrlResolver.ts +1 -1
  92. package/src/odspUtils.ts +7 -7
  93. package/src/opsCaching.ts +3 -3
  94. package/src/packageVersion.ts +1 -1
  95. package/src/prefetchLatestSnapshot.ts +2 -2
  96. package/src/retryUtils.ts +5 -5
  97. package/src/vroom.ts +14 -8
  98. package/dist/odspDocumentServiceFactoryWithCodeSplit.d.ts +0 -16
  99. package/dist/odspDocumentServiceFactoryWithCodeSplit.d.ts.map +0 -1
  100. package/dist/odspDocumentServiceFactoryWithCodeSplit.js +0 -20
  101. package/dist/odspDocumentServiceFactoryWithCodeSplit.js.map +0 -1
  102. package/lib/odspDocumentServiceFactoryWithCodeSplit.d.ts +0 -16
  103. package/lib/odspDocumentServiceFactoryWithCodeSplit.d.ts.map +0 -1
  104. package/lib/odspDocumentServiceFactoryWithCodeSplit.js +0 -16
  105. package/lib/odspDocumentServiceFactoryWithCodeSplit.js.map +0 -1
  106. package/src/odspDocumentServiceFactoryWithCodeSplit.ts +0 -33
@@ -72,7 +72,7 @@ function readBlobSection(node: NodeTypes): {
72
72
  const records = getNodeProps(blob);
73
73
  assertBlobCoreInstance(records.data, "data should be of BlobCore type");
74
74
  const id = getStringInstance(records.id, "blob id should be string");
75
- blobContents.set(id, records.data?.arrayBuffer);
75
+ blobContents.set(id, records.data.arrayBuffer);
76
76
  }
77
77
  }
78
78
  return { blobContents, slowBlobStructureCount };
@@ -88,15 +88,15 @@ function readOpsSection(node: NodeTypes): ISequencedDocumentMessage[] {
88
88
  const records = getNodeProps(node);
89
89
  assertNumberInstance(records.firstSequenceNumber, "Seq number should be a number");
90
90
  assertNodeCoreInstance(records.deltas, "Deltas should be a Node");
91
- for (let i = 0; i < records.deltas?.length; ++i) {
91
+ for (let i = 0; i < records.deltas.length; ++i) {
92
92
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
93
- ops.push(JSON.parse(records.deltas?.getString(i)));
93
+ ops.push(JSON.parse(records.deltas.getString(i)));
94
94
  }
95
95
  // Due to a bug at service side, in an edge case service was serializing deltas even
96
96
  // when there are no ops. So just make the code resilient to that bug. Service has also
97
97
  // fixed that bug.
98
98
  assert(
99
- ops.length === 0 || records.firstSequenceNumber?.valueOf() === ops[0].sequenceNumber,
99
+ ops.length === 0 || records.firstSequenceNumber.valueOf() === ops[0].sequenceNumber,
100
100
  0x280 /* "Validate first op seq number" */,
101
101
  );
102
102
  return ops;
@@ -244,7 +244,7 @@ function readSnapshotSection(node: NodeTypes): {
244
244
  const { snapshotTree, slowTreeStructureCount, treeStructureCountWithGroupId } =
245
245
  readTreeSection(records.treeNodes);
246
246
  snapshotTree.id = getStringInstance(records.id, "snapshotId should be string");
247
- const sequenceNumber = records.sequenceNumber?.valueOf();
247
+ const sequenceNumber = records.sequenceNumber.valueOf();
248
248
  return {
249
249
  sequenceNumber,
250
250
  snapshotTree,
@@ -150,13 +150,8 @@ export async function fetchSnapshotWithRedeem(
150
150
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
151
151
  if (enableRedeemFallback && isRedeemSharingLinkError(odspResolvedUrl, error)) {
152
152
  // Execute the redeem fallback
153
+ await redeemSharingLink(odspResolvedUrl, storageTokenFetcher, logger);
153
154
 
154
- await redeemSharingLink(
155
- odspResolvedUrl,
156
- storageTokenFetcher,
157
- logger,
158
- forceAccessTokenViaAuthorizationHeader,
159
- );
160
155
  const odspResolvedUrlWithoutShareLink: IOdspResolvedUrl = {
161
156
  ...odspResolvedUrl,
162
157
  shareLinkInfo: {
@@ -213,7 +208,6 @@ async function redeemSharingLink(
213
208
  odspResolvedUrl: IOdspResolvedUrl,
214
209
  getAuthHeader: InstrumentedStorageTokenFetcher,
215
210
  logger: ITelemetryLoggerExt,
216
- forceAccessTokenViaAuthorizationHeader: boolean,
217
211
  ): Promise<void> {
218
212
  await PerformanceEvent.timedExecAsync(
219
213
  logger,
@@ -233,7 +227,12 @@ async function redeemSharingLink(
233
227
  let redeemUrl: string | undefined;
234
228
  async function callSharesAPI(baseUrl: string): Promise<void> {
235
229
  await getWithRetryForTokenRefresh(async (tokenFetchOptions) => {
236
- redeemUrl = `${baseUrl}/_api/v2.0/shares/${encodedShareUrl}`;
230
+ // IMPORTANT: Note that redeemUrl has '/driveItem' in it. Technically it is not required for executing redeem operation.
231
+ // However, we have other cases that use '/shares' API and do require to specify '/driveItem' in order to get specific
232
+ // drive item properties. The reason this matters is when caller of this API must possess logical permissions to call
233
+ // this API (for instance, this will be the case when call is made with app-only token) then two separate logical
234
+ // permissions are needed for the '/shares' call with and without '/driveItem'.
235
+ redeemUrl = `${baseUrl}/_api/v2.0/shares/${encodedShareUrl}/driveItem`;
237
236
  const url = redeemUrl;
238
237
  const method = "GET";
239
238
  const authHeader = await getAuthHeader(
@@ -102,7 +102,7 @@ export async function getFileLink(
102
102
  }
103
103
 
104
104
  /**
105
- * Handles location redirection while fulfilling the getFilelink call. We don't want browser to handle
105
+ * Handles location redirection while fulfilling the getFileLink call. We don't want browser to handle
106
106
  * the redirection as the browser will retry with same auth token which will not work as we need app
107
107
  * to regenerate tokens for the new site domain. So when we will make the network calls below we will set
108
108
  * the redirect:manual header to manually handle these redirects.
@@ -125,7 +125,7 @@ async function getFileLinkWithLocationRedirectionHandling(
125
125
  let locationRedirected = false;
126
126
  for (let count = 1; count <= 5; count++) {
127
127
  try {
128
- const fileItem = await getFileItemLite(getToken, resolvedUrl, logger, true);
128
+ const fileItem = await getFileItemLite(getToken, resolvedUrl, logger);
129
129
  // Sometimes the siteUrl in the actual file is different from the siteUrl in the resolvedUrl due to location
130
130
  // redirection. This creates issues in the getSharingInformation call. So we need to update the siteUrl in the
131
131
  // resolvedUrl to the siteUrl in the fileItem which is the updated siteUrl.
@@ -260,7 +260,6 @@ async function getFileItemLite(
260
260
  getToken: TokenFetcher<OdspResourceTokenFetchOptions>,
261
261
  odspUrlParts: IOdspUrlParts,
262
262
  logger: ITelemetryLoggerExt,
263
- forceAccessTokenViaAuthorizationHeader: boolean,
264
263
  ): Promise<FileItemLite> {
265
264
  return PerformanceEvent.timedExecAsync(
266
265
  logger,
package/src/index.ts CHANGED
@@ -29,7 +29,6 @@ export {
29
29
  OdspDocumentServiceFactory,
30
30
  } from "./odspDocumentServiceFactory.js";
31
31
  export { OdspDocumentServiceFactoryCore } from "./odspDocumentServiceFactoryCore.js";
32
- export { OdspDocumentServiceFactoryWithCodeSplit } from "./odspDocumentServiceFactoryWithCodeSplit.js";
33
32
 
34
33
  // File creation
35
34
  export { createOdspCreateContainerRequest } from "./createOdspCreateContainerRequest.js";
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { performance } from "@fluid-internal/client-utils";
6
+ import { performanceNow } from "@fluid-internal/client-utils";
7
7
  import { ISignalEnvelope } from "@fluidframework/core-interfaces/internal";
8
8
  import { assert } from "@fluidframework/core-utils/internal";
9
9
  import { IClient } from "@fluidframework/driver-definitions";
@@ -91,7 +91,7 @@ export class OdspDelayLoadedDeltaStream {
91
91
  | undefined,
92
92
  private readonly mc: MonitoringContext,
93
93
  private readonly cache: IOdspCache,
94
- _hostPolicy: HostStoragePolicy,
94
+ private readonly hostPolicy: HostStoragePolicy,
95
95
  private readonly epochTracker: EpochTracker,
96
96
  private readonly opsReceived: (ops: ISequencedDocumentMessage[]) => void,
97
97
  private readonly metadataUpdateHandler: (metadata: Record<string, string>) => void,
@@ -156,6 +156,8 @@ export class OdspDelayLoadedDeltaStream {
156
156
  requestWebsocketTokenFromJoinSession,
157
157
  options,
158
158
  false /* isRefreshingJoinSession */,
159
+ undefined /* clientId */,
160
+ this.hostPolicy.sessionOptions?.displayName,
159
161
  );
160
162
  const [websocketEndpoint, websocketToken] = await Promise.all([
161
163
  joinSessionPromise.catch(annotateAndRethrowConnectionError("joinSession")),
@@ -273,6 +275,7 @@ export class OdspDelayLoadedDeltaStream {
273
275
  delta: number,
274
276
  requestSocketToken: boolean,
275
277
  clientId: string | undefined,
278
+ displayName: string | undefined,
276
279
  ): Promise<void> {
277
280
  if (this.joinSessionRefreshTimer !== undefined) {
278
281
  this.clearJoinSessionTimer();
@@ -301,6 +304,7 @@ export class OdspDelayLoadedDeltaStream {
301
304
  options,
302
305
  true /* isRefreshingJoinSession */,
303
306
  clientId,
307
+ displayName,
304
308
  );
305
309
  resolve();
306
310
  }).catch((error) => {
@@ -314,7 +318,8 @@ export class OdspDelayLoadedDeltaStream {
314
318
  requestSocketToken: boolean,
315
319
  options: TokenFetchOptionsEx,
316
320
  isRefreshingJoinSession: boolean,
317
- clientId?: string,
321
+ clientId: string | undefined,
322
+ displayName: string | undefined,
318
323
  ): Promise<ISocketStorageDiscovery> {
319
324
  // If this call is to refresh the join session for the current connection but we are already disconnected in
320
325
  // the meantime or disconnected and then reconnected then do not make the call. However, we should not have
@@ -342,6 +347,7 @@ export class OdspDelayLoadedDeltaStream {
342
347
  requestSocketToken,
343
348
  options,
344
349
  isRefreshingJoinSession,
350
+ displayName,
345
351
  ).catch((error) => {
346
352
  if (hasFacetCodes(error) && error.facetCodes !== undefined) {
347
353
  for (const code of error.facetCodes) {
@@ -378,6 +384,7 @@ export class OdspDelayLoadedDeltaStream {
378
384
  requestSocketToken: boolean,
379
385
  options: TokenFetchOptionsEx,
380
386
  isRefreshingJoinSession: boolean,
387
+ displayName: string | undefined,
381
388
  ): Promise<ISocketStorageDiscovery> {
382
389
  const disableJoinSessionRefresh = this.mc.config.getBoolean(
383
390
  "Fluid.Driver.Odsp.disableJoinSessionRefresh",
@@ -397,6 +404,7 @@ export class OdspDelayLoadedDeltaStream {
397
404
  options,
398
405
  disableJoinSessionRefresh,
399
406
  isRefreshingJoinSession,
407
+ displayName,
400
408
  );
401
409
  // Emit event only in case it is fetched from the network.
402
410
  if (joinSessionResponse.sensitivityLabelsInfo !== undefined) {
@@ -450,6 +458,7 @@ export class OdspDelayLoadedDeltaStream {
450
458
  response.refreshAfterDeltaMs,
451
459
  requestSocketToken,
452
460
  this.currentConnection?.clientId,
461
+ displayName,
453
462
  ).catch((error) => {
454
463
  // Log the error and do nothing as the reconnection would fetch the join session.
455
464
  this.mc.logger.sendTelemetryEvent(
@@ -510,7 +519,7 @@ export class OdspDelayLoadedDeltaStream {
510
519
  client: IClient,
511
520
  webSocketUrl: string,
512
521
  ): Promise<OdspDocumentDeltaConnection> {
513
- const startTime = performance.now();
522
+ const startTime = performanceNow();
514
523
  const connection = await OdspDocumentDeltaConnection.create(
515
524
  tenantId,
516
525
  documentId,
@@ -522,7 +531,7 @@ export class OdspDelayLoadedDeltaStream {
522
531
  this.epochTracker,
523
532
  this.socketReferenceKeyPrefix,
524
533
  );
525
- const duration = performance.now() - startTime;
534
+ const duration = performanceNow() - startTime;
526
535
  // This event happens rather often, so it adds up to cost of telemetry.
527
536
  // Given that most reconnects result in reusing socket and happen very quickly,
528
537
  // report event only if it took longer than threshold.
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { TypedEventEmitter, performance } from "@fluid-internal/client-utils";
6
+ import { TypedEventEmitter, performanceNow } from "@fluid-internal/client-utils";
7
7
  import { IEvent } from "@fluidframework/core-interfaces";
8
8
  import { assert, Deferred } from "@fluidframework/core-utils/internal";
9
9
  import { DocumentDeltaConnection } from "@fluidframework/driver-base/internal";
@@ -450,7 +450,7 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
450
450
 
451
451
  this.pushCallCounter++;
452
452
  const nonce = `${this.requestOpsNoncePrefix}${this.pushCallCounter}`;
453
- const start = performance.now();
453
+ const start = performanceNow();
454
454
 
455
455
  // We may keep keep accumulating memory for nothing, if we are not getting responses.
456
456
  // Note that we should not have overlapping requests, as DeltaManager allows only one
@@ -475,7 +475,7 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
475
475
  from: payloadToDelete.from,
476
476
  to: payloadToDelete.to,
477
477
  length: payloadToDelete.to - payloadToDelete.from,
478
- duration: performance.now() - payloadToDelete.start,
478
+ duration: performanceNow() - payloadToDelete.start,
479
479
  });
480
480
  this.getOpsMap.delete(key!);
481
481
  }
@@ -591,7 +591,7 @@ export class OdspDocumentDeltaConnection extends DocumentDeltaConnection {
591
591
  code: result.code,
592
592
  from: data?.from,
593
593
  to: data?.to,
594
- duration: data === undefined ? undefined : performance.now() - data.start,
594
+ duration: data === undefined ? undefined : performanceNow() - data.start,
595
595
  };
596
596
  if (messages !== undefined && messages.length > 0) {
597
597
  this.logger.sendPerformanceEvent({
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { performance } from "@fluid-internal/client-utils";
6
+ import { performanceNow } from "@fluid-internal/client-utils";
7
7
  import { LogLevel } from "@fluidframework/core-interfaces";
8
8
  import { assert, delay } from "@fluidframework/core-utils/internal";
9
9
  import { promiseRaceWithWinner } from "@fluidframework/driver-base/internal";
@@ -271,7 +271,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
271
271
  let retrievedSnapshot: ISnapshot | IPrefetchSnapshotContents | undefined;
272
272
 
273
273
  let method: string;
274
- let prefetchWaitStartTime: number = performance.now();
274
+ let prefetchWaitStartTime: number = performanceNow();
275
275
  if (snapshotFetchOptions.fetchSource === FetchSource.noCache) {
276
276
  retrievedSnapshot = await this.fetchSnapshotFromNetwork(
277
277
  hostSnapshotOptions,
@@ -394,13 +394,13 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
394
394
  } else {
395
395
  // Note: There's a race condition here - another caller may come past the undefined check
396
396
  // while the first caller is awaiting later async code in this block.
397
- const startTime = performance.now();
397
+ const startTime = performanceNow();
398
398
  retrievedSnapshot = await cachedSnapshotP;
399
- cacheLookupTimeInSerialFetch = performance.now() - startTime;
399
+ cacheLookupTimeInSerialFetch = performanceNow() - startTime;
400
400
  method = retrievedSnapshot === undefined ? "network" : "cache";
401
401
 
402
402
  if (retrievedSnapshot === undefined) {
403
- prefetchWaitStartTime = performance.now();
403
+ prefetchWaitStartTime = performanceNow();
404
404
  retrievedSnapshot = await this.fetchSnapshotFromNetwork(
405
405
  hostSnapshotOptions,
406
406
  snapshotFetchOptions.loadingGroupIds,
@@ -437,7 +437,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
437
437
  },
438
438
  );
439
439
 
440
- const stTime = performance.now();
440
+ const stTime = performanceNow();
441
441
  // Don't override ops which were fetched during initial load, since we could still need them.
442
442
  const id = this.initializeFromSnapshot(
443
443
  odspSnapshotCacheValue,
@@ -447,7 +447,7 @@ export class OdspDocumentStorageService extends OdspDocumentStorageServiceBase {
447
447
  this.logger.sendTelemetryEvent(
448
448
  {
449
449
  eventName: "SnapshotInitializeTime",
450
- duration: performance.now() - stTime,
450
+ duration: performanceNow() - stTime,
451
451
  },
452
452
  undefined,
453
453
  LogLevel.verbose,
@@ -257,9 +257,8 @@ export abstract class OdspDocumentStorageServiceBase implements IDocumentStorage
257
257
  protected combineProtocolAndAppSnapshotTree(snapshotTree: ISnapshotTree): ISnapshotTree {
258
258
  // When we upload the container snapshot, we upload appTree in ".app" and protocol tree in ".protocol"
259
259
  // So when we request the snapshot we get ".app" as tree and not as commit node as in the case just above.
260
- const hierarchicalAppTree: ISnapshotTree | undefined = snapshotTree.trees[".app"];
261
- const hierarchicalProtocolTree: ISnapshotTree | undefined =
262
- snapshotTree.trees[".protocol"];
260
+ const hierarchicalAppTree = snapshotTree.trees[".app"];
261
+ const hierarchicalProtocolTree = snapshotTree.trees[".protocol"];
263
262
  const summarySnapshotTree: ISnapshotTree = {
264
263
  blobs: {
265
264
  ...hierarchicalAppTree.blobs,
@@ -108,7 +108,7 @@ export class OdspDriverUrlResolver implements IUrlResolver {
108
108
 
109
109
  const searchParams = new URLSearchParams(queryString);
110
110
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
111
- const fileName: string = request.headers[DriverHeader.createNew]?.fileName;
111
+ const fileName: string = request.headers[DriverHeader.createNew].fileName;
112
112
  const driveID = searchParams.get("driveId");
113
113
  const filePath = searchParams.get("path");
114
114
  const packageName = searchParams.get("containerPackageName");
package/src/odspUtils.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { performance } from "@fluid-internal/client-utils";
6
+ import { performanceNow } from "@fluid-internal/client-utils";
7
7
  import {
8
8
  ITelemetryBaseLogger,
9
9
  ITelemetryBaseProperties,
@@ -135,7 +135,7 @@ export async function fetchHelper(
135
135
  requestInfo: RequestInfo,
136
136
  requestInit: RequestInit | undefined,
137
137
  ): Promise<IOdspResponse<Response>> {
138
- const start = performance.now();
138
+ const start = performanceNow();
139
139
 
140
140
  // Node-fetch and dom have conflicting typing, force them to work by casting for now
141
141
  return fetch(requestInfo, requestInit).then(
@@ -165,7 +165,7 @@ export async function fetchHelper(
165
165
  content: response,
166
166
  headers,
167
167
  propsToLog: getSPOAndGraphRequestIdsFromResponse(headers),
168
- duration: performance.now() - start,
168
+ duration: performanceNow() - start,
169
169
  };
170
170
  },
171
171
  (error) => {
@@ -508,16 +508,16 @@ export function buildOdspShareLinkReqParams(
508
508
  }
509
509
 
510
510
  export function measure<T>(callback: () => T): [T, number] {
511
- const start = performance.now();
511
+ const start = performanceNow();
512
512
  const result = callback();
513
- const time = performance.now() - start;
513
+ const time = performanceNow() - start;
514
514
  return [result, time];
515
515
  }
516
516
 
517
517
  export async function measureP<T>(callback: () => Promise<T>): Promise<[T, number]> {
518
- const start = performance.now();
518
+ const start = performanceNow();
519
519
  const result = await callback();
520
- const time = performance.now() - start;
520
+ const time = performanceNow() - start;
521
521
  return [result, time];
522
522
  }
523
523
 
package/src/opsCaching.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { performance } from "@fluid-internal/client-utils";
6
+ import { performanceNow } from "@fluid-internal/client-utils";
7
7
  import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
8
8
 
9
9
  // ISequencedDocumentMessage
@@ -183,11 +183,11 @@ export class OpsCache {
183
183
  * @returns ops retrieved
184
184
  */
185
185
  public async get(from: number, to?: number): Promise<IMessage[]> {
186
- const start = performance.now();
186
+ const start = performanceNow();
187
187
 
188
188
  const messages = await this.getCore(from, to);
189
189
 
190
- const duration = performance.now() - start;
190
+ const duration = performanceNow() - start;
191
191
  if (messages.length > 0 || duration > 1000) {
192
192
  this.logger.sendPerformanceEvent({
193
193
  eventName: "CacheOpsUsed",
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/odsp-driver";
9
- export const pkgVersion = "2.13.0";
9
+ export const pkgVersion = "2.21.0";
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { performance } from "@fluid-internal/client-utils";
6
+ import { performanceNow } from "@fluid-internal/client-utils";
7
7
  import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
8
8
  import { assert, Deferred } from "@fluidframework/core-utils/internal";
9
9
  import { IResolvedUrl } from "@fluidframework/driver-definitions/internal";
@@ -127,7 +127,7 @@ export async function prefetchLatestSnapshot(
127
127
  odspLogger,
128
128
  { eventName: "PrefetchLatestSnapshot" },
129
129
  async () => {
130
- const prefetchStartTime = performance.now();
130
+ const prefetchStartTime = performanceNow();
131
131
  // Add the deferred promise to the cache, so that it can be leveraged while loading the container.
132
132
  const snapshotContentsWithEpochP = new Deferred<IPrefetchSnapshotContents>();
133
133
  const nonPersistentCacheKey = getKeyForCacheEntry(snapshotKey);
package/src/retryUtils.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { performance } from "@fluid-internal/client-utils";
6
+ import { performanceNow } from "@fluid-internal/client-utils";
7
7
  import { delay } from "@fluidframework/core-utils/internal";
8
8
  import {
9
9
  canRetryOnError,
@@ -24,7 +24,7 @@ export async function runWithRetry<T>(
24
24
  checkDisposed?: () => void,
25
25
  ): Promise<T> {
26
26
  let retryAfter = 1000;
27
- const start = performance.now();
27
+ const start = performanceNow();
28
28
  let lastError: unknown;
29
29
  for (let attempts = 1; ; attempts++) {
30
30
  if (checkDisposed !== undefined) {
@@ -38,7 +38,7 @@ export async function runWithRetry<T>(
38
38
  eventName: "MultipleRetries",
39
39
  callName,
40
40
  attempts,
41
- duration: performance.now() - start,
41
+ duration: performanceNow() - start,
42
42
  },
43
43
  lastError,
44
44
  );
@@ -62,7 +62,7 @@ export async function runWithRetry<T>(
62
62
  eventName: `${callName}_firstFailed`,
63
63
  callName,
64
64
  attempts,
65
- duration: performance.now() - start, // record total wait time.
65
+ duration: performanceNow() - start, // record total wait time.
66
66
  },
67
67
  error,
68
68
  );
@@ -86,7 +86,7 @@ export async function runWithRetry<T>(
86
86
  : "ServiceReadonlyErrorTooManyRetries",
87
87
  callName,
88
88
  attempts,
89
- duration: performance.now() - start, // record total wait time.
89
+ duration: performanceNow() - start, // record total wait time.
90
90
  },
91
91
  error,
92
92
  );
package/src/vroom.ts CHANGED
@@ -21,8 +21,8 @@ import { TokenFetchOptionsEx } from "./odspUtils.js";
21
21
  import { runWithRetry } from "./retryUtils.js";
22
22
 
23
23
  interface IJoinSessionBody {
24
- requestSocketToken: boolean;
25
- guestDisplayName?: string;
24
+ requestSocketToken?: boolean;
25
+ displayName?: string;
26
26
  }
27
27
 
28
28
  /**
@@ -38,8 +38,9 @@ interface IJoinSessionBody {
38
38
  * @param options - Options to fetch the token.
39
39
  * @param disableJoinSessionRefresh - Whether the caller wants to disable refreshing join session periodically.
40
40
  * @param isRefreshingJoinSession - whether call is to refresh the session before expiry.
41
- * @param guestDisplayName - display name used to identify guest user joining a session.
42
- * This is optional and used only when collab session is being joined via invite.
41
+ * @param displayName - display name used to identify client joining a session.
42
+ * This is optional and used only when collab session is being joined by client acting in app-only mode (i.e. without user context).
43
+ * If not specified client display name is extracted from the access token that is used to join session.
43
44
  */
44
45
  export async function fetchJoinSession(
45
46
  urlParts: IOdspUrlParts,
@@ -52,6 +53,7 @@ export async function fetchJoinSession(
52
53
  options: TokenFetchOptionsEx,
53
54
  disableJoinSessionRefresh: boolean | undefined,
54
55
  isRefreshingJoinSession: boolean,
56
+ displayName: string | undefined,
55
57
  ): Promise<ISocketStorageDiscovery> {
56
58
  const apiRoot = getApiRoot(new URL(urlParts.siteUrl));
57
59
  const url = `${apiRoot}/drives/${urlParts.driveId}/items/${urlParts.itemId}/${path}?ump=1`;
@@ -89,11 +91,15 @@ export async function fetchJoinSession(
89
91
  }
90
92
  postBody += `_post: 1\r\n`;
91
93
 
94
+ let requestBody: IJoinSessionBody | undefined;
92
95
  if (requestSocketToken) {
93
- const body: IJoinSessionBody = {
94
- requestSocketToken: true,
95
- };
96
- postBody += `\r\n${JSON.stringify(body)}\r\n`;
96
+ requestBody = { ...requestBody, requestSocketToken: true };
97
+ }
98
+ if (displayName) {
99
+ requestBody = { ...requestBody, displayName };
100
+ }
101
+ if (requestBody) {
102
+ postBody += `\r\n${JSON.stringify(requestBody)}\r\n`;
97
103
  }
98
104
  postBody += `\r\n--${formBoundary}--`;
99
105
  const headers: { [index: string]: string } = {
@@ -1,16 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { IDocumentServiceFactory } from "@fluidframework/driver-definitions/internal";
6
- import { HostStoragePolicy, IPersistedCache, OdspResourceTokenFetchOptions, TokenFetcher } from "@fluidframework/odsp-driver-definitions/internal";
7
- import { OdspDocumentServiceFactoryCore } from "./odspDocumentServiceFactoryCore.js";
8
- /**
9
- * @deprecated This is deprecated in favour of OdspDocumentServiceFactory as the socket io is now loaded inside the
10
- * other dynamically imported module.
11
- * @internal
12
- */
13
- export declare class OdspDocumentServiceFactoryWithCodeSplit extends OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
14
- constructor(getStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>, getWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined, persistedCache?: IPersistedCache, hostPolicy?: HostStoragePolicy);
15
- }
16
- //# sourceMappingURL=odspDocumentServiceFactoryWithCodeSplit.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"odspDocumentServiceFactoryWithCodeSplit.d.ts","sourceRoot":"","sources":["../src/odspDocumentServiceFactoryWithCodeSplit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AACtF,OAAO,EACN,iBAAiB,EACjB,eAAe,EACf,6BAA6B,EAC7B,YAAY,EACZ,MAAM,kDAAkD,CAAC;AAE1D,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF;;;;GAIG;AACH,qBAAa,uCACZ,SAAQ,8BACR,YAAW,uBAAuB;gBAGjC,eAAe,EAAE,YAAY,CAAC,6BAA6B,CAAC,EAC5D,iBAAiB,EAAE,YAAY,CAAC,6BAA6B,CAAC,GAAG,SAAS,EAC1E,cAAc,CAAC,EAAE,eAAe,EAChC,UAAU,CAAC,EAAE,iBAAiB;CAI/B"}
@@ -1,20 +0,0 @@
1
- "use strict";
2
- /*!
3
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
- * Licensed under the MIT License.
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.OdspDocumentServiceFactoryWithCodeSplit = void 0;
8
- const odspDocumentServiceFactoryCore_js_1 = require("./odspDocumentServiceFactoryCore.js");
9
- /**
10
- * @deprecated This is deprecated in favour of OdspDocumentServiceFactory as the socket io is now loaded inside the
11
- * other dynamically imported module.
12
- * @internal
13
- */
14
- class OdspDocumentServiceFactoryWithCodeSplit extends odspDocumentServiceFactoryCore_js_1.OdspDocumentServiceFactoryCore {
15
- constructor(getStorageToken, getWebsocketToken, persistedCache, hostPolicy) {
16
- super(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);
17
- }
18
- }
19
- exports.OdspDocumentServiceFactoryWithCodeSplit = OdspDocumentServiceFactoryWithCodeSplit;
20
- //# sourceMappingURL=odspDocumentServiceFactoryWithCodeSplit.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"odspDocumentServiceFactoryWithCodeSplit.js","sourceRoot":"","sources":["../src/odspDocumentServiceFactoryWithCodeSplit.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAUH,2FAAqF;AAErF;;;;GAIG;AACH,MAAa,uCACZ,SAAQ,kEAA8B;IAGtC,YACC,eAA4D,EAC5D,iBAA0E,EAC1E,cAAgC,EAChC,UAA8B;QAE9B,KAAK,CAAC,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IACvE,CAAC;CACD;AAZD,0FAYC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDocumentServiceFactory } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tHostStoragePolicy,\n\tIPersistedCache,\n\tOdspResourceTokenFetchOptions,\n\tTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\n\nimport { OdspDocumentServiceFactoryCore } from \"./odspDocumentServiceFactoryCore.js\";\n\n/**\n * @deprecated This is deprecated in favour of OdspDocumentServiceFactory as the socket io is now loaded inside the\n * other dynamically imported module.\n * @internal\n */\nexport class OdspDocumentServiceFactoryWithCodeSplit\n\textends OdspDocumentServiceFactoryCore\n\timplements IDocumentServiceFactory\n{\n\tconstructor(\n\t\tgetStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\t\tgetWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined,\n\t\tpersistedCache?: IPersistedCache,\n\t\thostPolicy?: HostStoragePolicy,\n\t) {\n\t\tsuper(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);\n\t}\n}\n"]}
@@ -1,16 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { IDocumentServiceFactory } from "@fluidframework/driver-definitions/internal";
6
- import { HostStoragePolicy, IPersistedCache, OdspResourceTokenFetchOptions, TokenFetcher } from "@fluidframework/odsp-driver-definitions/internal";
7
- import { OdspDocumentServiceFactoryCore } from "./odspDocumentServiceFactoryCore.js";
8
- /**
9
- * @deprecated This is deprecated in favour of OdspDocumentServiceFactory as the socket io is now loaded inside the
10
- * other dynamically imported module.
11
- * @internal
12
- */
13
- export declare class OdspDocumentServiceFactoryWithCodeSplit extends OdspDocumentServiceFactoryCore implements IDocumentServiceFactory {
14
- constructor(getStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>, getWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined, persistedCache?: IPersistedCache, hostPolicy?: HostStoragePolicy);
15
- }
16
- //# sourceMappingURL=odspDocumentServiceFactoryWithCodeSplit.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"odspDocumentServiceFactoryWithCodeSplit.d.ts","sourceRoot":"","sources":["../src/odspDocumentServiceFactoryWithCodeSplit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AACtF,OAAO,EACN,iBAAiB,EACjB,eAAe,EACf,6BAA6B,EAC7B,YAAY,EACZ,MAAM,kDAAkD,CAAC;AAE1D,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF;;;;GAIG;AACH,qBAAa,uCACZ,SAAQ,8BACR,YAAW,uBAAuB;gBAGjC,eAAe,EAAE,YAAY,CAAC,6BAA6B,CAAC,EAC5D,iBAAiB,EAAE,YAAY,CAAC,6BAA6B,CAAC,GAAG,SAAS,EAC1E,cAAc,CAAC,EAAE,eAAe,EAChC,UAAU,CAAC,EAAE,iBAAiB;CAI/B"}
@@ -1,16 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { OdspDocumentServiceFactoryCore } from "./odspDocumentServiceFactoryCore.js";
6
- /**
7
- * @deprecated This is deprecated in favour of OdspDocumentServiceFactory as the socket io is now loaded inside the
8
- * other dynamically imported module.
9
- * @internal
10
- */
11
- export class OdspDocumentServiceFactoryWithCodeSplit extends OdspDocumentServiceFactoryCore {
12
- constructor(getStorageToken, getWebsocketToken, persistedCache, hostPolicy) {
13
- super(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);
14
- }
15
- }
16
- //# sourceMappingURL=odspDocumentServiceFactoryWithCodeSplit.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"odspDocumentServiceFactoryWithCodeSplit.js","sourceRoot":"","sources":["../src/odspDocumentServiceFactoryWithCodeSplit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF;;;;GAIG;AACH,MAAM,OAAO,uCACZ,SAAQ,8BAA8B;IAGtC,YACC,eAA4D,EAC5D,iBAA0E,EAC1E,cAAgC,EAChC,UAA8B;QAE9B,KAAK,CAAC,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IACvE,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDocumentServiceFactory } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tHostStoragePolicy,\n\tIPersistedCache,\n\tOdspResourceTokenFetchOptions,\n\tTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions/internal\";\n\nimport { OdspDocumentServiceFactoryCore } from \"./odspDocumentServiceFactoryCore.js\";\n\n/**\n * @deprecated This is deprecated in favour of OdspDocumentServiceFactory as the socket io is now loaded inside the\n * other dynamically imported module.\n * @internal\n */\nexport class OdspDocumentServiceFactoryWithCodeSplit\n\textends OdspDocumentServiceFactoryCore\n\timplements IDocumentServiceFactory\n{\n\tconstructor(\n\t\tgetStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,\n\t\tgetWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined,\n\t\tpersistedCache?: IPersistedCache,\n\t\thostPolicy?: HostStoragePolicy,\n\t) {\n\t\tsuper(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);\n\t}\n}\n"]}
@@ -1,33 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- import { IDocumentServiceFactory } from "@fluidframework/driver-definitions/internal";
7
- import {
8
- HostStoragePolicy,
9
- IPersistedCache,
10
- OdspResourceTokenFetchOptions,
11
- TokenFetcher,
12
- } from "@fluidframework/odsp-driver-definitions/internal";
13
-
14
- import { OdspDocumentServiceFactoryCore } from "./odspDocumentServiceFactoryCore.js";
15
-
16
- /**
17
- * @deprecated This is deprecated in favour of OdspDocumentServiceFactory as the socket io is now loaded inside the
18
- * other dynamically imported module.
19
- * @internal
20
- */
21
- export class OdspDocumentServiceFactoryWithCodeSplit
22
- extends OdspDocumentServiceFactoryCore
23
- implements IDocumentServiceFactory
24
- {
25
- constructor(
26
- getStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>,
27
- getWebsocketToken: TokenFetcher<OdspResourceTokenFetchOptions> | undefined,
28
- persistedCache?: IPersistedCache,
29
- hostPolicy?: HostStoragePolicy,
30
- ) {
31
- super(getStorageToken, getWebsocketToken, persistedCache, hostPolicy);
32
- }
33
- }