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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.mocharc.js +12 -0
  2. package/dist/cache.d.ts +4 -0
  3. package/dist/cache.d.ts.map +1 -1
  4. package/dist/cache.js +9 -1
  5. package/dist/cache.js.map +1 -1
  6. package/dist/documentDeltaConnection.d.ts.map +1 -1
  7. package/dist/documentDeltaConnection.js +3 -6
  8. package/dist/documentDeltaConnection.js.map +1 -1
  9. package/dist/documentService.d.ts +2 -1
  10. package/dist/documentService.d.ts.map +1 -1
  11. package/dist/documentService.js +4 -2
  12. package/dist/documentService.js.map +1 -1
  13. package/dist/documentServiceFactory.d.ts.map +1 -1
  14. package/dist/documentServiceFactory.js +7 -3
  15. package/dist/documentServiceFactory.js.map +1 -1
  16. package/dist/packageVersion.d.ts +1 -1
  17. package/dist/packageVersion.d.ts.map +1 -1
  18. package/dist/packageVersion.js +1 -1
  19. package/dist/packageVersion.js.map +1 -1
  20. package/dist/policies.d.ts +6 -0
  21. package/dist/policies.d.ts.map +1 -1
  22. package/dist/policies.js.map +1 -1
  23. package/dist/restWrapper.js +2 -1
  24. package/dist/restWrapper.js.map +1 -1
  25. package/dist/shreddedSummaryDocumentStorageService.d.ts +1 -0
  26. package/dist/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
  27. package/dist/shreddedSummaryDocumentStorageService.js +10 -4
  28. package/dist/shreddedSummaryDocumentStorageService.js.map +1 -1
  29. package/dist/tokens.d.ts +7 -0
  30. package/dist/tokens.d.ts.map +1 -1
  31. package/dist/tokens.js.map +1 -1
  32. package/dist/wholeSummaryDocumentStorageService.d.ts +1 -0
  33. package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  34. package/dist/wholeSummaryDocumentStorageService.js +13 -6
  35. package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
  36. package/lib/cache.d.ts +4 -0
  37. package/lib/cache.d.ts.map +1 -1
  38. package/lib/cache.js +7 -0
  39. package/lib/cache.js.map +1 -1
  40. package/lib/documentDeltaConnection.d.ts.map +1 -1
  41. package/lib/documentDeltaConnection.js +3 -6
  42. package/lib/documentDeltaConnection.js.map +1 -1
  43. package/lib/documentService.d.ts +2 -1
  44. package/lib/documentService.d.ts.map +1 -1
  45. package/lib/documentService.js +4 -2
  46. package/lib/documentService.js.map +1 -1
  47. package/lib/documentServiceFactory.d.ts.map +1 -1
  48. package/lib/documentServiceFactory.js +8 -4
  49. package/lib/documentServiceFactory.js.map +1 -1
  50. package/lib/packageVersion.d.ts +1 -1
  51. package/lib/packageVersion.d.ts.map +1 -1
  52. package/lib/packageVersion.js +1 -1
  53. package/lib/packageVersion.js.map +1 -1
  54. package/lib/policies.d.ts +6 -0
  55. package/lib/policies.d.ts.map +1 -1
  56. package/lib/policies.js.map +1 -1
  57. package/lib/restWrapper.js +2 -1
  58. package/lib/restWrapper.js.map +1 -1
  59. package/lib/shreddedSummaryDocumentStorageService.d.ts +1 -0
  60. package/lib/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
  61. package/lib/shreddedSummaryDocumentStorageService.js +10 -4
  62. package/lib/shreddedSummaryDocumentStorageService.js.map +1 -1
  63. package/lib/tokens.d.ts +7 -0
  64. package/lib/tokens.d.ts.map +1 -1
  65. package/lib/tokens.js.map +1 -1
  66. package/lib/wholeSummaryDocumentStorageService.d.ts +1 -0
  67. package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  68. package/lib/wholeSummaryDocumentStorageService.js +13 -6
  69. package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
  70. package/package.json +22 -18
  71. package/src/cache.ts +9 -0
  72. package/src/documentDeltaConnection.ts +3 -5
  73. package/src/documentService.ts +4 -1
  74. package/src/documentServiceFactory.ts +10 -3
  75. package/src/packageVersion.ts +1 -1
  76. package/src/policies.ts +6 -0
  77. package/src/restWrapper.ts +1 -1
  78. package/src/shreddedSummaryDocumentStorageService.ts +14 -4
  79. package/src/tokens.ts +7 -2
  80. package/src/wholeSummaryDocumentStorageService.ts +14 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/routerlicious-driver",
3
- "version": "1.2.7",
3
+ "version": "2.0.0-dev.1.3.0.96595",
4
4
  "description": "Socket.IO + Git implementation of Fluid service API",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -61,15 +61,15 @@
61
61
  },
62
62
  "dependencies": {
63
63
  "@fluidframework/common-definitions": "^0.20.1",
64
- "@fluidframework/common-utils": "^0.32.1",
65
- "@fluidframework/driver-base": "^1.2.7",
66
- "@fluidframework/driver-definitions": "^1.2.7",
67
- "@fluidframework/driver-utils": "^1.2.7",
68
- "@fluidframework/gitresources": "^0.1036.5000",
69
- "@fluidframework/protocol-base": "^0.1036.5000",
70
- "@fluidframework/protocol-definitions": "^0.1028.2000",
71
- "@fluidframework/server-services-client": "^0.1036.5000",
72
- "@fluidframework/telemetry-utils": "^1.2.7",
64
+ "@fluidframework/common-utils": "^1.0.0",
65
+ "@fluidframework/driver-base": "2.0.0-dev.1.3.0.96595",
66
+ "@fluidframework/driver-definitions": "2.0.0-dev.1.3.0.96595",
67
+ "@fluidframework/driver-utils": "2.0.0-dev.1.3.0.96595",
68
+ "@fluidframework/gitresources": "^0.1037.2001",
69
+ "@fluidframework/protocol-base": "^0.1037.2001",
70
+ "@fluidframework/protocol-definitions": "^1.0.0",
71
+ "@fluidframework/server-services-client": "^0.1037.2001",
72
+ "@fluidframework/telemetry-utils": "2.0.0-dev.1.3.0.96595",
73
73
  "cross-fetch": "^3.1.5",
74
74
  "json-stringify-safe": "5.0.1",
75
75
  "querystring": "^0.2.0",
@@ -78,11 +78,11 @@
78
78
  "uuid": "^8.3.1"
79
79
  },
80
80
  "devDependencies": {
81
- "@fluidframework/build-common": "^0.24.0",
82
- "@fluidframework/build-tools": "^0.2.74327",
83
- "@fluidframework/eslint-config-fluid": "^0.28.2000",
84
- "@fluidframework/mocha-test-setup": "^1.2.7",
85
- "@fluidframework/routerlicious-driver-previous": "npm:@fluidframework/routerlicious-driver@1.2.1",
81
+ "@fluidframework/build-common": "^1.0.0",
82
+ "@fluidframework/build-tools": "^0.4.6000",
83
+ "@fluidframework/eslint-config-fluid": "^1.0.0",
84
+ "@fluidframework/mocha-test-setup": "2.0.0-dev.1.3.0.96595",
85
+ "@fluidframework/routerlicious-driver-previous": "npm:@fluidframework/routerlicious-driver@^1.0.0",
86
86
  "@microsoft/api-extractor": "^7.22.2",
87
87
  "@rushstack/eslint-config": "^2.5.1",
88
88
  "@types/mocha": "^9.1.1",
@@ -91,7 +91,7 @@
91
91
  "@types/uuid": "^8.3.0",
92
92
  "axios": "^0.26.0",
93
93
  "concurrently": "^6.2.0",
94
- "copyfiles": "^2.1.0",
94
+ "copyfiles": "^2.4.1",
95
95
  "cross-env": "^7.0.2",
96
96
  "eslint": "~8.6.0",
97
97
  "mocha": "^10.0.0",
@@ -102,7 +102,11 @@
102
102
  "typescript-formatter": "7.1.0"
103
103
  },
104
104
  "typeValidation": {
105
- "version": "1.2.2",
106
- "broken": {}
105
+ "version": "2.0.0",
106
+ "broken": {
107
+ "InterfaceDeclaration_IRouterliciousDriverPolicies": {
108
+ "forwardCompat": false
109
+ }
110
+ }
107
111
  }
108
112
  }
package/src/cache.ts CHANGED
@@ -19,3 +19,12 @@ export class InMemoryCache<T> implements ICache<T> {
19
19
  this.cache.set(key, value);
20
20
  }
21
21
  }
22
+
23
+ export class NullCache<T> implements ICache<T> {
24
+ public async get(key: string): Promise<T | undefined> {
25
+ return undefined;
26
+ }
27
+
28
+ public async put(key: string, value: T): Promise<void> {
29
+ }
30
+ }
@@ -65,10 +65,8 @@ export class R11sDocumentDeltaConnection extends DocumentDeltaConnection {
65
65
  // Note: we suspect the incoming error object is either:
66
66
  // - a socketError: add it to the R11sError object for driver to be able to parse it and reason over it.
67
67
  // - anything else: let base class handle it
68
- if (canRetry && Number.isInteger(error?.code) && typeof error?.message === "string") {
69
- return errorObjectFromSocketError(error as IR11sSocketError, handler);
70
- } else {
71
- return super.createErrorObject(handler, error, canRetry);
72
- }
68
+ return canRetry && Number.isInteger(error?.code) && typeof error?.message === "string"
69
+ ? errorObjectFromSocketError(error as IR11sSocketError, handler)
70
+ : super.createErrorObject(handler, error, canRetry);
73
71
  }
74
72
  }
@@ -49,6 +49,7 @@ export class DocumentService implements api.IDocumentService {
49
49
  private _resolvedUrl: api.IResolvedUrl,
50
50
  protected ordererUrl: string,
51
51
  private deltaStorageUrl: string,
52
+ private deltaStreamUrl: string,
52
53
  private storageUrl: string,
53
54
  private readonly logger: ITelemetryLogger,
54
55
  protected tokenProvider: ITokenProvider,
@@ -192,13 +193,14 @@ export class DocumentService implements api.IDocumentService {
192
193
  this.documentId,
193
194
  refreshToken,
194
195
  );
196
+
195
197
  return R11sDocumentDeltaConnection.create(
196
198
  this.tenantId,
197
199
  this.documentId,
198
200
  ordererToken.jwt,
199
201
  io,
200
202
  client,
201
- this.ordererUrl,
203
+ this.deltaStreamUrl,
202
204
  this.logger,
203
205
  );
204
206
  };
@@ -240,6 +242,7 @@ export class DocumentService implements api.IDocumentService {
240
242
  this.storageUrl = fluidResolvedUrl.endpoints.storageUrl;
241
243
  this.ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;
242
244
  this.deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;
245
+ this.deltaStreamUrl = fluidResolvedUrl.endpoints.deltaStreamUrl || this.ordererUrl;
243
246
  this.lastDiscoveredAt = Date.now();
244
247
  }
245
248
 
@@ -26,7 +26,7 @@ import { ITokenProvider } from "./tokens";
26
26
  import { RouterliciousOrdererRestWrapper } from "./restWrapper";
27
27
  import { convertSummaryToCreateNewSummary } from "./createNewUtils";
28
28
  import { parseFluidUrl, replaceDocumentIdInPath, getDiscoveredFluidResolvedUrl } from "./urlUtils";
29
- import { InMemoryCache } from "./cache";
29
+ import { ICache, InMemoryCache, NullCache } from "./cache";
30
30
  import { pkgVersion as driverVersion } from "./packageVersion";
31
31
  import { ISnapshotTreeVersion } from "./definitions";
32
32
 
@@ -38,6 +38,7 @@ const defaultRouterliciousDriverPolicies: IRouterliciousDriverPolicies = {
38
38
  enableDiscovery: false,
39
39
  enableWholeSummaryUpload: false,
40
40
  enableRestLess: true,
41
+ enableInternalSummaryCaching: true,
41
42
  };
42
43
 
43
44
  /**
@@ -47,8 +48,8 @@ const defaultRouterliciousDriverPolicies: IRouterliciousDriverPolicies = {
47
48
  export class RouterliciousDocumentServiceFactory implements IDocumentServiceFactory {
48
49
  public readonly protocolName = "fluid:";
49
50
  private readonly driverPolicies: IRouterliciousDriverPolicies;
50
- private readonly blobCache = new InMemoryCache<ArrayBufferLike>();
51
- private readonly snapshotTreeCache = new InMemoryCache<ISnapshotTreeVersion>();
51
+ private readonly blobCache: ICache<ArrayBufferLike>;
52
+ private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion>;
52
53
 
53
54
  constructor(
54
55
  private readonly tokenProvider: ITokenProvider,
@@ -58,6 +59,10 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
58
59
  ...defaultRouterliciousDriverPolicies,
59
60
  ...driverPolicies,
60
61
  };
62
+ this.blobCache = new InMemoryCache<ArrayBufferLike>();
63
+ this.snapshotTreeCache = this.driverPolicies.enableInternalSummaryCaching
64
+ ? new InMemoryCache<ISnapshotTreeVersion>()
65
+ : new NullCache<ISnapshotTreeVersion>();
61
66
  }
62
67
 
63
68
  /**
@@ -214,6 +219,7 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
214
219
  const storageUrl = fluidResolvedUrl.endpoints.storageUrl;
215
220
  const ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;
216
221
  const deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;
222
+ const deltaStreamUrl = fluidResolvedUrl.endpoints.deltaStreamUrl || ordererUrl; // backward compatibility
217
223
  if (!ordererUrl || !deltaStorageUrl) {
218
224
  throw new Error(
219
225
  `All endpoints urls must be provided. [ordererUrl:${ordererUrl}][deltaStorageUrl:${deltaStorageUrl}]`);
@@ -223,6 +229,7 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
223
229
  fluidResolvedUrl,
224
230
  ordererUrl,
225
231
  deltaStorageUrl,
232
+ deltaStreamUrl,
226
233
  storageUrl,
227
234
  logger2,
228
235
  this.tokenProvider,
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/routerlicious-driver";
9
- export const pkgVersion = "1.2.7";
9
+ export const pkgVersion = "2.0.0-dev.1.3.0.96595";
package/src/policies.ts CHANGED
@@ -42,4 +42,10 @@ export interface IRouterliciousDriverPolicies {
42
42
  * Default: true
43
43
  */
44
44
  enableRestLess: boolean;
45
+ /**
46
+ * Enable internal cache of summaries/snapshots.
47
+ * Reduces Summarizer boot time and reduces server load in E2E tests.
48
+ * Default: true
49
+ */
50
+ enableInternalSummaryCaching: boolean;
45
51
  }
@@ -106,7 +106,7 @@ export class RouterliciousRestWrapper extends RestWrapper {
106
106
  }
107
107
 
108
108
  private generateHeaders(requestHeaders?: AxiosRequestHeaders | undefined): Record<string, string> {
109
- const correlationId = requestHeaders?.["x-correlation-id"] || uuid();
109
+ const correlationId = requestHeaders?.["x-correlation-id"] ?? uuid();
110
110
 
111
111
  return {
112
112
  ...requestHeaders,
@@ -107,7 +107,7 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
107
107
  requestVersion = versions[0];
108
108
  }
109
109
 
110
- const cachedSnapshotTree = await this.snapshotTreeCache?.get(requestVersion.treeId);
110
+ const cachedSnapshotTree = await this.snapshotTreeCache?.get(this.getCacheKey(requestVersion.treeId));
111
111
  if (cachedSnapshotTree) {
112
112
  return cachedSnapshotTree.snapshotTree as ISnapshotTreeEx;
113
113
  }
@@ -128,12 +128,15 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
128
128
  },
129
129
  );
130
130
  const tree = buildHierarchy(rawTree, this.blobsShaCache, true);
131
- await this.snapshotTreeCache?.put(tree.id, { id: requestVersion.id, snapshotTree: tree });
131
+ await this.snapshotTreeCache?.put(
132
+ this.getCacheKey(tree.id),
133
+ { id: requestVersion.id, snapshotTree: tree },
134
+ );
132
135
  return tree;
133
136
  }
134
137
 
135
138
  public async readBlob(blobId: string): Promise<ArrayBufferLike> {
136
- const cachedBlob = await this.blobCache?.get(blobId);
139
+ const cachedBlob = await this.blobCache?.get(this.getCacheKey(blobId));
137
140
  if (cachedBlob) {
138
141
  return cachedBlob;
139
142
  }
@@ -155,7 +158,7 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
155
158
  );
156
159
  this.blobsShaCache.set(value.sha, "");
157
160
  const bufferContent = stringToBuffer(value.content, value.encoding);
158
- await this.blobCache?.put(value.sha, bufferContent);
161
+ await this.blobCache?.put(this.getCacheKey(value.sha), bufferContent);
159
162
  return bufferContent;
160
163
  }
161
164
 
@@ -164,6 +167,9 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
164
167
  this.logger,
165
168
  {
166
169
  eventName: "uploadSummaryWithContext",
170
+ proposalHandle: context.proposalHandle,
171
+ ackHandle: context.ackHandle,
172
+ referenceSequenceNumber: context.referenceSequenceNumber,
167
173
  },
168
174
  async () => {
169
175
  const summaryUploadManager = await this.getSummaryUploadManager();
@@ -209,4 +215,8 @@ export class ShreddedSummaryDocumentStorageService implements IDocumentStorageSe
209
215
  })
210
216
  : undefined;
211
217
  }
218
+
219
+ private getCacheKey(blobId: string): string {
220
+ return `${this.id}:${blobId}`;
221
+ }
212
222
  }
package/src/tokens.ts CHANGED
@@ -13,10 +13,15 @@ export interface ITokenService {
13
13
  }
14
14
 
15
15
  export interface ITokenResponse {
16
- // JWT value
16
+ /**
17
+ * {@link https://jwt.io/introduction/ | JSON Web Token (JWT)} value.
18
+ */
17
19
  jwt: string;
18
20
 
19
- // Flag indicating whether token was obtained from local cache
21
+ /**
22
+ * Flag indicating whether token was obtained from local cache.
23
+ * Undefined indicates that the source of the token could not be determined.
24
+ */
20
25
  fromCache?: boolean;
21
26
  }
22
27
 
@@ -120,7 +120,7 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
120
120
  }
121
121
 
122
122
  public async readBlob(blobId: string): Promise<ArrayBufferLike> {
123
- const cachedBlob = await this.blobCache.get(blobId);
123
+ const cachedBlob = await this.blobCache.get(this.getCacheKey(blobId));
124
124
  if (cachedBlob !== undefined) {
125
125
  return cachedBlob;
126
126
  }
@@ -142,7 +142,7 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
142
142
  );
143
143
  const bufferValue = stringToBuffer(blob.content, blob.encoding);
144
144
 
145
- await this.blobCache.put(blob.sha, bufferValue);
145
+ await this.blobCache.put(this.getCacheKey(blob.sha), bufferValue);
146
146
 
147
147
  return bufferValue;
148
148
  }
@@ -152,6 +152,9 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
152
152
  this.logger,
153
153
  {
154
154
  eventName: "uploadSummaryWithContext",
155
+ proposalHandle: context.proposalHandle,
156
+ ackHandle: context.ackHandle,
157
+ referenceSequenceNumber: context.referenceSequenceNumber,
155
158
  },
156
159
  async () => {
157
160
  const summaryUploadManager = await this.getSummaryUploadManager();
@@ -205,7 +208,7 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
205
208
  }
206
209
 
207
210
  private async fetchAndCacheSnapshotTree(versionId: string, disableCache?: boolean): Promise<ISnapshotTreeVersion> {
208
- const cachedSnapshotTreeVersion = await this.snapshotTreeCache.get(versionId);
211
+ const cachedSnapshotTreeVersion = await this.snapshotTreeCache.get(this.getCacheKey(versionId));
209
212
  if (cachedSnapshotTreeVersion !== undefined) {
210
213
  return { id: cachedSnapshotTreeVersion.id, snapshotTree: cachedSnapshotTreeVersion.snapshotTree };
211
214
  }
@@ -233,7 +236,7 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
233
236
 
234
237
  const cachePs: Promise<any>[] = [
235
238
  this.snapshotTreeCache.put(
236
- snapshotTreeId,
239
+ this.getCacheKey(snapshotTreeId),
237
240
  snapshotTreeVersion,
238
241
  ),
239
242
  this.initBlobCache(normalizedWholeSummary.blobs),
@@ -244,7 +247,7 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
244
247
  // However, for something like Redis, this will cache the same value twice. Alternatively, could we simply
245
248
  // cache with versionId?
246
249
  cachePs.push(this.snapshotTreeCache.put(
247
- versionId,
250
+ this.getCacheKey(versionId),
248
251
  snapshotTreeVersion,
249
252
  ));
250
253
  }
@@ -257,8 +260,13 @@ export class WholeSummaryDocumentStorageService implements IDocumentStorageServi
257
260
  private async initBlobCache(blobs: Map<string, ArrayBuffer>): Promise<void> {
258
261
  const blobCachePutPs: Promise<void>[] = [];
259
262
  blobs.forEach((value, id) => {
260
- blobCachePutPs.push(this.blobCache.put(id, value));
263
+ const cacheKey = this.getCacheKey(id);
264
+ blobCachePutPs.push(this.blobCache.put(cacheKey, value));
261
265
  });
262
266
  await Promise.all(blobCachePutPs);
263
267
  }
268
+
269
+ private getCacheKey(blobId: string): string {
270
+ return `${this.id}:${blobId}`;
271
+ }
264
272
  }