@fluidframework/routerlicious-driver 2.0.0-dev.2.3.0.115467 → 2.0.0-dev.4.1.0.148229

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 (170) hide show
  1. package/.eslintrc.js +10 -12
  2. package/.mocharc.js +2 -2
  3. package/README.md +1 -1
  4. package/api-extractor.json +2 -2
  5. package/dist/cache.d.ts +3 -0
  6. package/dist/cache.d.ts.map +1 -1
  7. package/dist/cache.js +6 -4
  8. package/dist/cache.js.map +1 -1
  9. package/dist/createNewUtils.d.ts.map +1 -1
  10. package/dist/createNewUtils.js +4 -2
  11. package/dist/createNewUtils.js.map +1 -1
  12. package/dist/defaultTokenProvider.d.ts.map +1 -1
  13. package/dist/defaultTokenProvider.js.map +1 -1
  14. package/dist/definitions.d.ts.map +1 -1
  15. package/dist/definitions.js.map +1 -1
  16. package/dist/deltaStorageService.d.ts.map +1 -1
  17. package/dist/deltaStorageService.js +4 -1
  18. package/dist/deltaStorageService.js.map +1 -1
  19. package/dist/documentDeltaConnection.d.ts.map +1 -1
  20. package/dist/documentDeltaConnection.js.map +1 -1
  21. package/dist/documentService.d.ts +4 -2
  22. package/dist/documentService.d.ts.map +1 -1
  23. package/dist/documentService.js +28 -41
  24. package/dist/documentService.js.map +1 -1
  25. package/dist/documentServiceFactory.d.ts +0 -1
  26. package/dist/documentServiceFactory.d.ts.map +1 -1
  27. package/dist/documentServiceFactory.js +26 -13
  28. package/dist/documentServiceFactory.js.map +1 -1
  29. package/dist/documentStorageService.d.ts +1 -1
  30. package/dist/documentStorageService.d.ts.map +1 -1
  31. package/dist/documentStorageService.js +8 -6
  32. package/dist/documentStorageService.js.map +1 -1
  33. package/dist/errorUtils.d.ts +11 -3
  34. package/dist/errorUtils.d.ts.map +1 -1
  35. package/dist/errorUtils.js +19 -6
  36. package/dist/errorUtils.js.map +1 -1
  37. package/dist/index.d.ts +2 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +4 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/mapWithExpiration.d.ts +34 -0
  42. package/dist/mapWithExpiration.d.ts.map +1 -0
  43. package/dist/mapWithExpiration.js +105 -0
  44. package/dist/mapWithExpiration.js.map +1 -0
  45. package/dist/nullBlobStorageService.d.ts.map +1 -1
  46. package/dist/nullBlobStorageService.js.map +1 -1
  47. package/dist/packageVersion.d.ts +1 -1
  48. package/dist/packageVersion.js +1 -1
  49. package/dist/packageVersion.js.map +1 -1
  50. package/dist/policies.d.ts.map +1 -1
  51. package/dist/policies.js.map +1 -1
  52. package/dist/restWrapper.d.ts +8 -5
  53. package/dist/restWrapper.d.ts.map +1 -1
  54. package/dist/restWrapper.js +38 -44
  55. package/dist/restWrapper.js.map +1 -1
  56. package/dist/retriableGitManager.d.ts.map +1 -1
  57. package/dist/retriableGitManager.js.map +1 -1
  58. package/dist/shreddedSummaryDocumentStorageService.d.ts +1 -1
  59. package/dist/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
  60. package/dist/shreddedSummaryDocumentStorageService.js +9 -5
  61. package/dist/shreddedSummaryDocumentStorageService.js.map +1 -1
  62. package/dist/tokens.d.ts +24 -7
  63. package/dist/tokens.d.ts.map +1 -1
  64. package/dist/tokens.js.map +1 -1
  65. package/dist/treeUtils.d.ts +51 -0
  66. package/dist/treeUtils.d.ts.map +1 -0
  67. package/dist/treeUtils.js +85 -0
  68. package/dist/treeUtils.js.map +1 -0
  69. package/dist/urlUtils.d.ts.map +1 -1
  70. package/dist/urlUtils.js.map +1 -1
  71. package/dist/wholeSummaryDocumentStorageService.d.ts +1 -1
  72. package/dist/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  73. package/dist/wholeSummaryDocumentStorageService.js +30 -17
  74. package/dist/wholeSummaryDocumentStorageService.js.map +1 -1
  75. package/lib/cache.d.ts +3 -0
  76. package/lib/cache.d.ts.map +1 -1
  77. package/lib/cache.js +6 -4
  78. package/lib/cache.js.map +1 -1
  79. package/lib/createNewUtils.d.ts.map +1 -1
  80. package/lib/createNewUtils.js +4 -2
  81. package/lib/createNewUtils.js.map +1 -1
  82. package/lib/defaultTokenProvider.d.ts.map +1 -1
  83. package/lib/defaultTokenProvider.js.map +1 -1
  84. package/lib/definitions.d.ts.map +1 -1
  85. package/lib/definitions.js.map +1 -1
  86. package/lib/deltaStorageService.d.ts.map +1 -1
  87. package/lib/deltaStorageService.js +4 -1
  88. package/lib/deltaStorageService.js.map +1 -1
  89. package/lib/documentDeltaConnection.d.ts.map +1 -1
  90. package/lib/documentDeltaConnection.js.map +1 -1
  91. package/lib/documentService.d.ts +4 -2
  92. package/lib/documentService.d.ts.map +1 -1
  93. package/lib/documentService.js +30 -24
  94. package/lib/documentService.js.map +1 -1
  95. package/lib/documentServiceFactory.d.ts +0 -1
  96. package/lib/documentServiceFactory.d.ts.map +1 -1
  97. package/lib/documentServiceFactory.js +27 -14
  98. package/lib/documentServiceFactory.js.map +1 -1
  99. package/lib/documentStorageService.d.ts +1 -1
  100. package/lib/documentStorageService.d.ts.map +1 -1
  101. package/lib/documentStorageService.js +9 -7
  102. package/lib/documentStorageService.js.map +1 -1
  103. package/lib/errorUtils.d.ts +11 -3
  104. package/lib/errorUtils.d.ts.map +1 -1
  105. package/lib/errorUtils.js +18 -5
  106. package/lib/errorUtils.js.map +1 -1
  107. package/lib/index.d.ts +2 -1
  108. package/lib/index.d.ts.map +1 -1
  109. package/lib/index.js +3 -1
  110. package/lib/index.js.map +1 -1
  111. package/lib/mapWithExpiration.d.ts +34 -0
  112. package/lib/mapWithExpiration.d.ts.map +1 -0
  113. package/lib/mapWithExpiration.js +101 -0
  114. package/lib/mapWithExpiration.js.map +1 -0
  115. package/lib/nullBlobStorageService.d.ts.map +1 -1
  116. package/lib/nullBlobStorageService.js.map +1 -1
  117. package/lib/packageVersion.d.ts +1 -1
  118. package/lib/packageVersion.js +1 -1
  119. package/lib/packageVersion.js.map +1 -1
  120. package/lib/policies.d.ts.map +1 -1
  121. package/lib/policies.js.map +1 -1
  122. package/lib/restWrapper.d.ts +8 -5
  123. package/lib/restWrapper.d.ts.map +1 -1
  124. package/lib/restWrapper.js +38 -44
  125. package/lib/restWrapper.js.map +1 -1
  126. package/lib/retriableGitManager.d.ts.map +1 -1
  127. package/lib/retriableGitManager.js.map +1 -1
  128. package/lib/shreddedSummaryDocumentStorageService.d.ts +1 -1
  129. package/lib/shreddedSummaryDocumentStorageService.d.ts.map +1 -1
  130. package/lib/shreddedSummaryDocumentStorageService.js +10 -6
  131. package/lib/shreddedSummaryDocumentStorageService.js.map +1 -1
  132. package/lib/tokens.d.ts +24 -7
  133. package/lib/tokens.d.ts.map +1 -1
  134. package/lib/tokens.js.map +1 -1
  135. package/lib/treeUtils.d.ts +51 -0
  136. package/lib/treeUtils.d.ts.map +1 -0
  137. package/lib/treeUtils.js +80 -0
  138. package/lib/treeUtils.js.map +1 -0
  139. package/lib/urlUtils.d.ts.map +1 -1
  140. package/lib/urlUtils.js.map +1 -1
  141. package/lib/wholeSummaryDocumentStorageService.d.ts +1 -1
  142. package/lib/wholeSummaryDocumentStorageService.d.ts.map +1 -1
  143. package/lib/wholeSummaryDocumentStorageService.js +30 -17
  144. package/lib/wholeSummaryDocumentStorageService.js.map +1 -1
  145. package/package.json +55 -52
  146. package/prettier.config.cjs +1 -1
  147. package/src/cache.ts +21 -14
  148. package/src/createNewUtils.ts +24 -22
  149. package/src/defaultTokenProvider.ts +13 -15
  150. package/src/definitions.ts +2 -2
  151. package/src/deltaStorageService.ts +99 -95
  152. package/src/documentDeltaConnection.ts +53 -47
  153. package/src/documentService.ts +260 -241
  154. package/src/documentServiceFactory.ts +268 -237
  155. package/src/documentStorageService.ts +87 -83
  156. package/src/errorUtils.ts +91 -76
  157. package/src/index.ts +7 -1
  158. package/src/mapWithExpiration.ts +124 -0
  159. package/src/nullBlobStorageService.ts +24 -21
  160. package/src/packageVersion.ts +1 -1
  161. package/src/policies.ts +44 -44
  162. package/src/restWrapper.ts +270 -208
  163. package/src/retriableGitManager.ts +152 -151
  164. package/src/shreddedSummaryDocumentStorageService.ts +202 -194
  165. package/src/tokens.ts +69 -44
  166. package/src/treeUtils.ts +107 -0
  167. package/src/urlUtils.ts +26 -23
  168. package/src/wholeSummaryDocumentStorageService.ts +248 -228
  169. package/tsconfig.esnext.json +6 -6
  170. package/tsconfig.json +9 -13
@@ -5,18 +5,22 @@
5
5
 
6
6
  import { assert } from "@fluidframework/common-utils";
7
7
  import {
8
- IDocumentService,
9
- IDocumentServiceFactory,
10
- IFluidResolvedUrl,
11
- IResolvedUrl,
8
+ FiveDaysMs,
9
+ IDocumentService,
10
+ IDocumentServiceFactory,
11
+ IDocumentStorageServicePolicies,
12
+ IFluidResolvedUrl,
13
+ IResolvedUrl,
14
+ LoaderCachingPolicy,
12
15
  } from "@fluidframework/driver-definitions";
13
16
  import { ITelemetryBaseLogger } from "@fluidframework/common-definitions";
14
17
  import { ISummaryTree } from "@fluidframework/protocol-definitions";
15
18
  import {
16
- ensureFluidResolvedUrl,
17
- getDocAttributesFromProtocolSummary,
18
- getQuorumValuesFromProtocolSummary,
19
- RateLimiter,
19
+ ensureFluidResolvedUrl,
20
+ getDocAttributesFromProtocolSummary,
21
+ getQuorumValuesFromProtocolSummary,
22
+ isCombinedAppAndProtocolSummary,
23
+ RateLimiter,
20
24
  } from "@fluidframework/driver-utils";
21
25
  import { ChildLogger, PerformanceEvent } from "@fluidframework/telemetry-utils";
22
26
  import { ISession } from "@fluidframework/server-services-client";
@@ -30,15 +34,17 @@ import { ICache, InMemoryCache, NullCache } from "./cache";
30
34
  import { pkgVersion as driverVersion } from "./packageVersion";
31
35
  import { ISnapshotTreeVersion } from "./definitions";
32
36
 
37
+ const maximumSnapshotCacheDurationMs: FiveDaysMs = 432_000_000; // 5 days in ms
38
+
33
39
  const defaultRouterliciousDriverPolicies: IRouterliciousDriverPolicies = {
34
- enablePrefetch: true,
35
- maxConcurrentStorageRequests: 100,
36
- maxConcurrentOrdererRequests: 100,
37
- aggregateBlobsSmallerThanBytes: undefined,
38
- enableDiscovery: false,
39
- enableWholeSummaryUpload: false,
40
- enableRestLess: true,
41
- enableInternalSummaryCaching: true,
40
+ enablePrefetch: true,
41
+ maxConcurrentStorageRequests: 100,
42
+ maxConcurrentOrdererRequests: 100,
43
+ aggregateBlobsSmallerThanBytes: undefined,
44
+ enableDiscovery: false,
45
+ enableWholeSummaryUpload: false,
46
+ enableRestLess: true,
47
+ enableInternalSummaryCaching: true,
42
48
  };
43
49
 
44
50
  /**
@@ -46,234 +52,257 @@ const defaultRouterliciousDriverPolicies: IRouterliciousDriverPolicies = {
46
52
  * use the routerlicious implementation.
47
53
  */
48
54
  export class RouterliciousDocumentServiceFactory implements IDocumentServiceFactory {
49
- public readonly protocolName = "fluid:";
50
- private readonly driverPolicies: IRouterliciousDriverPolicies;
51
- private readonly blobCache: ICache<ArrayBufferLike>;
52
- private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion>;
55
+ private readonly driverPolicies: IRouterliciousDriverPolicies;
56
+ private readonly blobCache: ICache<ArrayBufferLike>;
57
+ private readonly snapshotTreeCache: ICache<ISnapshotTreeVersion>;
58
+
59
+ constructor(
60
+ private readonly tokenProvider: ITokenProvider,
61
+ driverPolicies: Partial<IRouterliciousDriverPolicies> = {},
62
+ ) {
63
+ // Use the maximum allowed by the policy (IDocumentStorageServicePolicies.maximumCacheDurationMs set below)
64
+ const snapshotCacheExpiryMs: FiveDaysMs = maximumSnapshotCacheDurationMs;
65
+
66
+ this.driverPolicies = {
67
+ ...defaultRouterliciousDriverPolicies,
68
+ ...driverPolicies,
69
+ };
70
+ this.blobCache = new InMemoryCache<ArrayBufferLike>();
71
+ this.snapshotTreeCache = this.driverPolicies.enableInternalSummaryCaching
72
+ ? new InMemoryCache<ISnapshotTreeVersion>(snapshotCacheExpiryMs)
73
+ : new NullCache<ISnapshotTreeVersion>();
74
+ }
75
+
76
+ /**
77
+ * {@inheritDoc @fluidframework/driver-definitions#IDocumentServiceFactory.createContainer}
78
+ *
79
+ * @throws {@link DocumentPostCreateError}
80
+ * If an exception is thrown while invoking the provided {@link ITokenProvider.documentPostCreateCallback}.
81
+ */
82
+ public async createContainer(
83
+ createNewSummary: ISummaryTree | undefined,
84
+ resolvedUrl: IResolvedUrl,
85
+ logger?: ITelemetryBaseLogger,
86
+ clientIsSummarizer?: boolean,
87
+ ): Promise<IDocumentService> {
88
+ ensureFluidResolvedUrl(resolvedUrl);
89
+ if (createNewSummary === undefined) {
90
+ throw new Error("Empty file summary creation isn't supported in this driver.");
91
+ }
92
+ assert(!!resolvedUrl.endpoints.ordererUrl, 0x0b2 /* "Missing orderer URL!" */);
93
+ let parsedUrl = parseFluidUrl(resolvedUrl.url);
94
+ if (!parsedUrl.pathname) {
95
+ throw new Error("Parsed url should contain tenant and doc Id!!");
96
+ }
97
+ const [, tenantId] = parsedUrl.pathname.split("/");
53
98
 
54
- constructor(
55
- private readonly tokenProvider: ITokenProvider,
56
- driverPolicies: Partial<IRouterliciousDriverPolicies> = {},
57
- ) {
58
- this.driverPolicies = {
59
- ...defaultRouterliciousDriverPolicies,
60
- ...driverPolicies,
61
- };
62
- this.blobCache = new InMemoryCache<ArrayBufferLike>();
63
- this.snapshotTreeCache = this.driverPolicies.enableInternalSummaryCaching
64
- ? new InMemoryCache<ISnapshotTreeVersion>()
65
- : new NullCache<ISnapshotTreeVersion>();
66
- }
99
+ if (!isCombinedAppAndProtocolSummary(createNewSummary)) {
100
+ throw new Error("Protocol and App Summary required in the full summary");
101
+ }
102
+ const protocolSummary = createNewSummary.tree[".protocol"];
103
+ const appSummary = createNewSummary.tree[".app"];
67
104
 
68
- /**
69
- * {@inheritDoc @fluidframework/driver-definitions#IDocumentServiceFactory.createContainer}
70
- *
71
- * @throws {@link DocumentPostCreateError}
72
- * If an exception is thrown while invoking the provided {@link ITokenProvider.documentPostCreateCallback}.
73
- */
74
- public async createContainer(
75
- createNewSummary: ISummaryTree | undefined,
76
- resolvedUrl: IResolvedUrl,
77
- logger?: ITelemetryBaseLogger,
78
- clientIsSummarizer?: boolean,
79
- ): Promise<IDocumentService> {
80
- ensureFluidResolvedUrl(resolvedUrl);
81
- if (createNewSummary === undefined) {
82
- throw new Error("Empty file summary creation isn't supported in this driver.");
83
- }
84
- assert(!!resolvedUrl.endpoints.ordererUrl, 0x0b2 /* "Missing orderer URL!" */);
85
- let parsedUrl = parseFluidUrl(resolvedUrl.url);
86
- if (!parsedUrl.pathname) {
87
- throw new Error("Parsed url should contain tenant and doc Id!!");
88
- }
89
- const [, tenantId] = parsedUrl.pathname.split("/");
105
+ const documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);
106
+ const quorumValues = getQuorumValuesFromProtocolSummary(protocolSummary);
90
107
 
91
- const protocolSummary = createNewSummary.tree[".protocol"] as ISummaryTree;
92
- const appSummary = createNewSummary.tree[".app"] as ISummaryTree;
93
- if (!(protocolSummary && appSummary)) {
94
- throw new Error("Protocol and App Summary required in the full summary");
95
- }
96
- const documentAttributes = getDocAttributesFromProtocolSummary(protocolSummary);
97
- const quorumValues = getQuorumValuesFromProtocolSummary(protocolSummary);
108
+ const logger2 = ChildLogger.create(logger, "RouterliciousDriver");
109
+ const rateLimiter = new RateLimiter(this.driverPolicies.maxConcurrentOrdererRequests);
110
+ const ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(
111
+ tenantId,
112
+ undefined,
113
+ this.tokenProvider,
114
+ logger2,
115
+ rateLimiter,
116
+ this.driverPolicies.enableRestLess,
117
+ resolvedUrl.endpoints.ordererUrl,
118
+ );
98
119
 
99
- const logger2 = ChildLogger.create(logger, "RouterliciousDriver");
100
- const rateLimiter = new RateLimiter(this.driverPolicies.maxConcurrentOrdererRequests);
101
- const ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(
102
- tenantId,
103
- undefined,
104
- this.tokenProvider,
105
- logger2,
106
- rateLimiter,
107
- this.driverPolicies.enableRestLess,
108
- resolvedUrl.endpoints.ordererUrl,
109
- );
120
+ const res = await PerformanceEvent.timedExecAsync(
121
+ logger2,
122
+ {
123
+ eventName: "CreateNew",
124
+ details: JSON.stringify({
125
+ enableDiscovery: this.driverPolicies.enableDiscovery,
126
+ sequenceNumber: documentAttributes.sequenceNumber,
127
+ }),
128
+ },
129
+ async (event) => {
130
+ // @TODO: Remove returned "string" type when removing back-compat code
131
+ const postRes = await ordererRestWrapper.post<
132
+ { id: string; token?: string; session?: ISession } | string
133
+ >(`/documents/${tenantId}`, {
134
+ summary: convertSummaryToCreateNewSummary(appSummary),
135
+ sequenceNumber: documentAttributes.sequenceNumber,
136
+ values: quorumValues,
137
+ enableDiscovery: this.driverPolicies.enableDiscovery,
138
+ generateToken: this.tokenProvider.documentPostCreateCallback !== undefined,
139
+ });
110
140
 
111
- const res = await PerformanceEvent.timedExecAsync(
112
- logger2,
113
- {
114
- eventName: "CreateNew",
115
- details: JSON.stringify({
116
- enableDiscovery: this.driverPolicies.enableDiscovery,
117
- sequenceNumber: documentAttributes.sequenceNumber,
118
- }),
119
- },
120
- async (event) => {
121
- // @TODO: Remove returned "string" type when removing back-compat code
122
- const postRes = await ordererRestWrapper.post<
123
- { id: string; token?: string; session?: ISession; } | string
124
- >(`/documents/${tenantId}`, {
125
- summary: convertSummaryToCreateNewSummary(appSummary),
126
- sequenceNumber: documentAttributes.sequenceNumber,
127
- values: quorumValues,
128
- enableDiscovery: this.driverPolicies.enableDiscovery,
129
- generateToken:
130
- this.tokenProvider.documentPostCreateCallback !==
131
- undefined,
132
- });
141
+ event.end({
142
+ docId: typeof postRes === "string" ? postRes : postRes.id,
143
+ });
144
+ return postRes;
145
+ },
146
+ );
133
147
 
134
- event.end({
135
- docId: typeof postRes === "string" ? postRes : postRes.id,
136
- });
137
- return postRes;
138
- }
139
- );
148
+ // For supporting backward compatibility, when the request has generateToken === true, it will return
149
+ // an object instead of string
150
+ // @TODO: Remove the logic when no need to support back-compat
140
151
 
141
- // For supporting backward compatibility, when the request has generateToken === true, it will return
142
- // an object instead of string
143
- // @TODO: Remove the logic when no need to support back-compat
152
+ let documentId: string;
153
+ let token: string | undefined;
154
+ let session: ISession | undefined;
155
+ if (typeof res === "string") {
156
+ documentId = res;
157
+ } else {
158
+ documentId = res.id;
159
+ token = res.token;
160
+ session = this.driverPolicies.enableDiscovery ? res.session : undefined;
161
+ }
162
+ parsedUrl = parseFluidUrl(resolvedUrl.url);
144
163
 
145
- let documentId: string;
146
- let token: string | undefined;
147
- let session: ISession | undefined;
148
- if (typeof res === "string") {
149
- documentId = res;
150
- } else {
151
- documentId = res.id;
152
- token = res.token;
153
- session = this.driverPolicies.enableDiscovery ? res.session : undefined;
154
- }
155
- parsedUrl = parseFluidUrl(resolvedUrl.url);
164
+ // @TODO: Remove token from the condition, checking the documentPostCreateCallback !== undefined
165
+ // is sufficient to determine if the token will be undefined or not.
166
+ try {
167
+ await PerformanceEvent.timedExecAsync(
168
+ logger2,
169
+ {
170
+ eventName: "DocPostCreateCallback",
171
+ docId: documentId,
172
+ },
173
+ async () => {
174
+ if (token && this.tokenProvider.documentPostCreateCallback !== undefined) {
175
+ return this.tokenProvider.documentPostCreateCallback(documentId, token);
176
+ }
177
+ },
178
+ );
179
+ } catch (error: any) {
180
+ throw new DocumentPostCreateError(error);
181
+ }
156
182
 
157
- // @TODO: Remove token from the condition, checking the documentPostCreateCallback !== undefined
158
- // is sufficient to determine if the token will be undefined or not.
159
- try {
160
- await PerformanceEvent.timedExecAsync(
161
- logger2,
162
- {
163
- eventName: "DocPostCreateCallback",
164
- docId: documentId,
165
- },
166
- async () => {
167
- if (token && this.tokenProvider.documentPostCreateCallback !== undefined) {
168
- return this.tokenProvider.documentPostCreateCallback(documentId, token);
169
- }
170
- });
171
- } catch (error: any) {
172
- throw new DocumentPostCreateError(error);
173
- }
183
+ parsedUrl.set("pathname", replaceDocumentIdInPath(parsedUrl.pathname, documentId));
184
+ const deltaStorageUrl = resolvedUrl.endpoints.deltaStorageUrl;
185
+ if (!deltaStorageUrl) {
186
+ throw new Error(
187
+ `All endpoints urls must be provided. [deltaStorageUrl:${deltaStorageUrl}]`,
188
+ );
189
+ }
190
+ const parsedDeltaStorageUrl = new URL(deltaStorageUrl);
191
+ parsedDeltaStorageUrl.pathname = replaceDocumentIdInPath(
192
+ parsedDeltaStorageUrl.pathname,
193
+ documentId,
194
+ );
174
195
 
175
- parsedUrl.set("pathname", replaceDocumentIdInPath(parsedUrl.pathname, documentId));
176
- const deltaStorageUrl = resolvedUrl.endpoints.deltaStorageUrl;
177
- if (!deltaStorageUrl) {
178
- throw new Error(
179
- `All endpoints urls must be provided. [deltaStorageUrl:${deltaStorageUrl}]`);
180
- }
181
- const parsedDeltaStorageUrl = new URL(deltaStorageUrl);
182
- parsedDeltaStorageUrl.pathname = replaceDocumentIdInPath(parsedDeltaStorageUrl.pathname, documentId);
196
+ return this.createDocumentService(
197
+ {
198
+ ...resolvedUrl,
199
+ url: parsedUrl.toString(),
200
+ id: documentId,
201
+ endpoints: {
202
+ ...resolvedUrl.endpoints,
203
+ deltaStorageUrl: parsedDeltaStorageUrl.toString(),
204
+ },
205
+ },
206
+ logger,
207
+ clientIsSummarizer,
208
+ session,
209
+ );
210
+ }
183
211
 
184
- return this.createDocumentService(
185
- {
186
- ...resolvedUrl,
187
- url: parsedUrl.toString(),
188
- id: documentId,
189
- endpoints: {
190
- ...resolvedUrl.endpoints,
191
- deltaStorageUrl: parsedDeltaStorageUrl.toString(),
192
- },
193
- },
194
- logger,
195
- clientIsSummarizer,
196
- session,
197
- );
198
- }
212
+ /**
213
+ * {@inheritDoc @fluidframework/driver-definitions#IDocumentServiceFactory.createDocumentService}
214
+ *
215
+ * @returns Routerlicious document service.
216
+ */
217
+ public async createDocumentService(
218
+ resolvedUrl: IResolvedUrl,
219
+ logger?: ITelemetryBaseLogger,
220
+ clientIsSummarizer?: boolean,
221
+ session?: ISession,
222
+ ): Promise<IDocumentService> {
223
+ ensureFluidResolvedUrl(resolvedUrl);
224
+ const parsedUrl = parseFluidUrl(resolvedUrl.url);
225
+ const [, tenantId, documentId] = parsedUrl.pathname.split("/");
226
+ if (!documentId || !tenantId) {
227
+ throw new Error(
228
+ `Couldn't parse documentId and/or tenantId. [documentId:${documentId}][tenantId:${tenantId}]`,
229
+ );
230
+ }
231
+ const logger2 = ChildLogger.create(logger, "RouterliciousDriver", {
232
+ all: { driverVersion },
233
+ });
199
234
 
200
- /**
201
- * {@inheritDoc @fluidframework/driver-definitions#IDocumentServiceFactory.createDocumentService}
202
- *
203
- * @returns Routerlicious document service.
204
- */
205
- public async createDocumentService(
206
- resolvedUrl: IResolvedUrl,
207
- logger?: ITelemetryBaseLogger,
208
- clientIsSummarizer?: boolean,
209
- session?: ISession,
210
- ): Promise<IDocumentService> {
211
- ensureFluidResolvedUrl(resolvedUrl);
235
+ const rateLimiter = new RateLimiter(this.driverPolicies.maxConcurrentOrdererRequests);
236
+ const ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(
237
+ tenantId,
238
+ documentId,
239
+ this.tokenProvider,
240
+ logger2,
241
+ rateLimiter,
242
+ this.driverPolicies.enableRestLess,
243
+ );
212
244
 
213
- const parsedUrl = parseFluidUrl(resolvedUrl.url);
214
- const [, tenantId, documentId] = parsedUrl.pathname.split("/");
215
- if (!documentId || !tenantId) {
216
- throw new Error(
217
- `Couldn't parse documentId and/or tenantId. [documentId:${documentId}][tenantId:${tenantId}]`);
218
- }
219
- const logger2 = ChildLogger.create(logger, "RouterliciousDriver", { all: { driverVersion } });
245
+ const discoverFluidResolvedUrl = async (): Promise<IFluidResolvedUrl> => {
246
+ if (!this.driverPolicies.enableDiscovery) {
247
+ return resolvedUrl;
248
+ }
220
249
 
221
- const discoverFluidResolvedUrl = async (): Promise<IFluidResolvedUrl> => {
222
- if (!this.driverPolicies.enableDiscovery) {
223
- return resolvedUrl;
224
- }
225
- const rateLimiter = new RateLimiter(this.driverPolicies.maxConcurrentOrdererRequests);
226
- const ordererRestWrapper = await RouterliciousOrdererRestWrapper.load(
227
- tenantId,
228
- documentId,
229
- this.tokenProvider,
230
- logger2,
231
- rateLimiter,
232
- this.driverPolicies.enableRestLess,
233
- resolvedUrl.endpoints.ordererUrl,
234
- );
250
+ const discoveredSession = await PerformanceEvent.timedExecAsync(
251
+ logger2,
252
+ {
253
+ eventName: "DiscoverSession",
254
+ docId: documentId,
255
+ },
256
+ async () => {
257
+ // The service responds with the current document session associated with the container.
258
+ return ordererRestWrapper.get<ISession>(
259
+ `${resolvedUrl.endpoints.ordererUrl}/documents/${tenantId}/session/${documentId}`,
260
+ );
261
+ },
262
+ );
263
+ return getDiscoveredFluidResolvedUrl(resolvedUrl, discoveredSession);
264
+ };
265
+ const fluidResolvedUrl: IFluidResolvedUrl =
266
+ session !== undefined
267
+ ? getDiscoveredFluidResolvedUrl(resolvedUrl, session)
268
+ : await discoverFluidResolvedUrl();
235
269
 
236
- const discoveredSession = await PerformanceEvent.timedExecAsync(
237
- logger2,
238
- {
239
- eventName: "DiscoverSession",
240
- docId: documentId,
241
- },
242
- async () => {
243
- // The service responds with the current document session associated with the container.
244
- return ordererRestWrapper.get<ISession>(
245
- `/documents/${tenantId}/session/${documentId}`);
246
- });
247
- return getDiscoveredFluidResolvedUrl(resolvedUrl, discoveredSession);
248
- };
249
- const fluidResolvedUrl: IFluidResolvedUrl = session !== undefined
250
- ? getDiscoveredFluidResolvedUrl(resolvedUrl, session)
251
- : await discoverFluidResolvedUrl();
270
+ const storageUrl = fluidResolvedUrl.endpoints.storageUrl;
271
+ const ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;
272
+ const deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;
273
+ const deltaStreamUrl = fluidResolvedUrl.endpoints.deltaStreamUrl || ordererUrl; // backward compatibility
274
+ if (!ordererUrl || !deltaStorageUrl) {
275
+ throw new Error(
276
+ `All endpoints urls must be provided. [ordererUrl:${ordererUrl}][deltaStorageUrl:${deltaStorageUrl}]`,
277
+ );
278
+ }
252
279
 
253
- const storageUrl = fluidResolvedUrl.endpoints.storageUrl;
254
- const ordererUrl = fluidResolvedUrl.endpoints.ordererUrl;
255
- const deltaStorageUrl = fluidResolvedUrl.endpoints.deltaStorageUrl;
256
- const deltaStreamUrl = fluidResolvedUrl.endpoints.deltaStreamUrl || ordererUrl; // backward compatibility
257
- if (!ordererUrl || !deltaStorageUrl) {
258
- throw new Error(
259
- `All endpoints urls must be provided. [ordererUrl:${ordererUrl}][deltaStorageUrl:${deltaStorageUrl}]`);
260
- }
280
+ const documentStorageServicePolicies: IDocumentStorageServicePolicies = {
281
+ caching: this.driverPolicies.enablePrefetch
282
+ ? LoaderCachingPolicy.Prefetch
283
+ : LoaderCachingPolicy.NoCaching,
284
+ minBlobSize: this.driverPolicies.aggregateBlobsSmallerThanBytes,
285
+ maximumCacheDurationMs: maximumSnapshotCacheDurationMs,
286
+ };
261
287
 
262
- return new DocumentService(
263
- fluidResolvedUrl,
264
- ordererUrl,
265
- deltaStorageUrl,
266
- deltaStreamUrl,
267
- storageUrl,
268
- logger2,
269
- this.tokenProvider,
270
- tenantId,
271
- documentId,
272
- this.driverPolicies,
273
- this.blobCache,
274
- this.snapshotTreeCache,
275
- discoverFluidResolvedUrl);
276
- }
288
+ return new DocumentService(
289
+ fluidResolvedUrl,
290
+ ordererUrl,
291
+ deltaStorageUrl,
292
+ deltaStreamUrl,
293
+ storageUrl,
294
+ logger2,
295
+ this.tokenProvider,
296
+ tenantId,
297
+ documentId,
298
+ ordererRestWrapper,
299
+ documentStorageServicePolicies,
300
+ this.driverPolicies,
301
+ this.blobCache,
302
+ this.snapshotTreeCache,
303
+ discoverFluidResolvedUrl,
304
+ );
305
+ }
277
306
  }
278
307
 
279
308
  /**
@@ -288,16 +317,18 @@ export class RouterliciousDocumentServiceFactory implements IDocumentServiceFact
288
317
  * - What would a retry pattern look like here?
289
318
  */
290
319
  export class DocumentPostCreateError extends Error {
291
- public constructor(
292
- /**
293
- * Inner error being wrapped.
294
- */
295
- private readonly innerError: Error,
296
- ) {
297
- super(innerError.message);
298
- }
320
+ public constructor(
321
+ /**
322
+ * Inner error being wrapped.
323
+ */
324
+ private readonly innerError: Error,
325
+ ) {
326
+ super(innerError.message);
327
+ }
299
328
 
300
- public readonly name = "DocumentPostCreateError";
329
+ public readonly name = "DocumentPostCreateError";
301
330
 
302
- public get stack() { return this.innerError.stack; }
331
+ public get stack() {
332
+ return this.innerError.stack;
333
+ }
303
334
  }