@fluidframework/container-runtime 2.0.0-internal.5.4.0 → 2.0.0-internal.6.1.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 (223) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/dist/batchTracker.d.ts +2 -1
  3. package/dist/batchTracker.d.ts.map +1 -1
  4. package/dist/batchTracker.js.map +1 -1
  5. package/dist/blobManager.d.ts +4 -1
  6. package/dist/blobManager.d.ts.map +1 -1
  7. package/dist/blobManager.js +61 -26
  8. package/dist/blobManager.js.map +1 -1
  9. package/dist/connectionTelemetry.js +10 -2
  10. package/dist/connectionTelemetry.js.map +1 -1
  11. package/dist/containerRuntime.d.ts +26 -11
  12. package/dist/containerRuntime.d.ts.map +1 -1
  13. package/dist/containerRuntime.js +189 -131
  14. package/dist/containerRuntime.js.map +1 -1
  15. package/dist/dataStore.js +8 -2
  16. package/dist/dataStore.js.map +1 -1
  17. package/dist/dataStoreContext.d.ts.map +1 -1
  18. package/dist/dataStoreContext.js +24 -26
  19. package/dist/dataStoreContext.js.map +1 -1
  20. package/dist/dataStores.d.ts +20 -4
  21. package/dist/dataStores.d.ts.map +1 -1
  22. package/dist/dataStores.js +107 -53
  23. package/dist/dataStores.js.map +1 -1
  24. package/dist/deltaManagerProxyBase.d.ts +35 -0
  25. package/dist/deltaManagerProxyBase.d.ts.map +1 -0
  26. package/dist/deltaManagerProxyBase.js +77 -0
  27. package/dist/deltaManagerProxyBase.js.map +1 -0
  28. package/dist/deltaManagerSummarizerProxy.d.ts +1 -1
  29. package/dist/deltaManagerSummarizerProxy.d.ts.map +1 -1
  30. package/dist/deltaManagerSummarizerProxy.js +2 -2
  31. package/dist/deltaManagerSummarizerProxy.js.map +1 -1
  32. package/dist/gc/garbageCollection.js +17 -20
  33. package/dist/gc/garbageCollection.js.map +1 -1
  34. package/dist/gc/gcConfigs.js +13 -11
  35. package/dist/gc/gcConfigs.js.map +1 -1
  36. package/dist/gc/gcHelpers.js +4 -6
  37. package/dist/gc/gcHelpers.js.map +1 -1
  38. package/dist/gc/gcSummaryStateTracker.js +4 -6
  39. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  40. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  41. package/dist/gc/gcTelemetry.js +55 -37
  42. package/dist/gc/gcTelemetry.js.map +1 -1
  43. package/dist/id-compressor/idCompressor.js +49 -51
  44. package/dist/id-compressor/idCompressor.js.map +1 -1
  45. package/dist/id-compressor/idRange.js +2 -2
  46. package/dist/id-compressor/idRange.js.map +1 -1
  47. package/dist/id-compressor/sessionIdNormalizer.js +11 -16
  48. package/dist/id-compressor/sessionIdNormalizer.js.map +1 -1
  49. package/dist/index.d.ts +1 -1
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js.map +1 -1
  52. package/dist/opLifecycle/batchManager.js +10 -6
  53. package/dist/opLifecycle/batchManager.js.map +1 -1
  54. package/dist/opLifecycle/opCompressor.js +6 -1
  55. package/dist/opLifecycle/opCompressor.js.map +1 -1
  56. package/dist/opLifecycle/opDecompressor.js +11 -9
  57. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  58. package/dist/opLifecycle/opGroupingManager.js +13 -5
  59. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  60. package/dist/opLifecycle/opSplitter.js +10 -6
  61. package/dist/opLifecycle/opSplitter.js.map +1 -1
  62. package/dist/opLifecycle/outbox.js +1 -2
  63. package/dist/opLifecycle/outbox.js.map +1 -1
  64. package/dist/opLifecycle/remoteMessageProcessor.js +1 -1
  65. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  66. package/dist/opProperties.js +1 -2
  67. package/dist/opProperties.js.map +1 -1
  68. package/dist/packageVersion.d.ts +1 -1
  69. package/dist/packageVersion.js +1 -1
  70. package/dist/packageVersion.js.map +1 -1
  71. package/dist/pendingStateManager.d.ts +2 -2
  72. package/dist/pendingStateManager.d.ts.map +1 -1
  73. package/dist/pendingStateManager.js +22 -22
  74. package/dist/pendingStateManager.js.map +1 -1
  75. package/dist/scheduleManager.js +14 -10
  76. package/dist/scheduleManager.js.map +1 -1
  77. package/dist/summary/orderedClientElection.d.ts +2 -1
  78. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  79. package/dist/summary/orderedClientElection.js +17 -18
  80. package/dist/summary/orderedClientElection.js.map +1 -1
  81. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  82. package/dist/summary/runningSummarizer.js +35 -57
  83. package/dist/summary/runningSummarizer.js.map +1 -1
  84. package/dist/summary/summarizer.js +4 -7
  85. package/dist/summary/summarizer.js.map +1 -1
  86. package/dist/summary/summarizerClientElection.js +5 -9
  87. package/dist/summary/summarizerClientElection.js.map +1 -1
  88. package/dist/summary/summarizerHeuristics.js +8 -12
  89. package/dist/summary/summarizerHeuristics.js.map +1 -1
  90. package/dist/summary/summarizerNode/summarizerNode.js +22 -15
  91. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  92. package/dist/summary/summarizerNode/summarizerNodeUtils.js +2 -4
  93. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  94. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +17 -16
  95. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  96. package/dist/summary/summaryCollection.js +3 -5
  97. package/dist/summary/summaryCollection.js.map +1 -1
  98. package/dist/summary/summaryFormat.js +1 -2
  99. package/dist/summary/summaryFormat.js.map +1 -1
  100. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  101. package/dist/summary/summaryGenerator.js +62 -21
  102. package/dist/summary/summaryGenerator.js.map +1 -1
  103. package/dist/summary/summaryManager.js +3 -5
  104. package/dist/summary/summaryManager.js.map +1 -1
  105. package/lib/batchTracker.d.ts +2 -1
  106. package/lib/batchTracker.d.ts.map +1 -1
  107. package/lib/batchTracker.js.map +1 -1
  108. package/lib/blobManager.d.ts +4 -1
  109. package/lib/blobManager.d.ts.map +1 -1
  110. package/lib/blobManager.js +61 -26
  111. package/lib/blobManager.js.map +1 -1
  112. package/lib/connectionTelemetry.js +10 -2
  113. package/lib/connectionTelemetry.js.map +1 -1
  114. package/lib/containerRuntime.d.ts +26 -11
  115. package/lib/containerRuntime.d.ts.map +1 -1
  116. package/lib/containerRuntime.js +189 -131
  117. package/lib/containerRuntime.js.map +1 -1
  118. package/lib/dataStore.js +8 -2
  119. package/lib/dataStore.js.map +1 -1
  120. package/lib/dataStoreContext.d.ts.map +1 -1
  121. package/lib/dataStoreContext.js +24 -26
  122. package/lib/dataStoreContext.js.map +1 -1
  123. package/lib/dataStores.d.ts +20 -4
  124. package/lib/dataStores.d.ts.map +1 -1
  125. package/lib/dataStores.js +107 -53
  126. package/lib/dataStores.js.map +1 -1
  127. package/lib/deltaManagerProxyBase.d.ts +35 -0
  128. package/lib/deltaManagerProxyBase.d.ts.map +1 -0
  129. package/lib/deltaManagerProxyBase.js +73 -0
  130. package/lib/deltaManagerProxyBase.js.map +1 -0
  131. package/lib/deltaManagerSummarizerProxy.d.ts +1 -1
  132. package/lib/deltaManagerSummarizerProxy.d.ts.map +1 -1
  133. package/lib/deltaManagerSummarizerProxy.js +1 -1
  134. package/lib/deltaManagerSummarizerProxy.js.map +1 -1
  135. package/lib/gc/garbageCollection.js +17 -20
  136. package/lib/gc/garbageCollection.js.map +1 -1
  137. package/lib/gc/gcConfigs.js +13 -11
  138. package/lib/gc/gcConfigs.js.map +1 -1
  139. package/lib/gc/gcHelpers.js +4 -6
  140. package/lib/gc/gcHelpers.js.map +1 -1
  141. package/lib/gc/gcSummaryStateTracker.js +4 -6
  142. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  143. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  144. package/lib/gc/gcTelemetry.js +55 -37
  145. package/lib/gc/gcTelemetry.js.map +1 -1
  146. package/lib/id-compressor/idCompressor.js +49 -51
  147. package/lib/id-compressor/idCompressor.js.map +1 -1
  148. package/lib/id-compressor/idRange.js +2 -2
  149. package/lib/id-compressor/idRange.js.map +1 -1
  150. package/lib/id-compressor/sessionIdNormalizer.js +11 -16
  151. package/lib/id-compressor/sessionIdNormalizer.js.map +1 -1
  152. package/lib/index.d.ts +1 -1
  153. package/lib/index.d.ts.map +1 -1
  154. package/lib/index.js.map +1 -1
  155. package/lib/opLifecycle/batchManager.js +10 -6
  156. package/lib/opLifecycle/batchManager.js.map +1 -1
  157. package/lib/opLifecycle/opCompressor.js +6 -1
  158. package/lib/opLifecycle/opCompressor.js.map +1 -1
  159. package/lib/opLifecycle/opDecompressor.js +11 -9
  160. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  161. package/lib/opLifecycle/opGroupingManager.js +13 -5
  162. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  163. package/lib/opLifecycle/opSplitter.js +10 -6
  164. package/lib/opLifecycle/opSplitter.js.map +1 -1
  165. package/lib/opLifecycle/outbox.js +1 -2
  166. package/lib/opLifecycle/outbox.js.map +1 -1
  167. package/lib/opLifecycle/remoteMessageProcessor.js +1 -1
  168. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  169. package/lib/opProperties.js +1 -2
  170. package/lib/opProperties.js.map +1 -1
  171. package/lib/packageVersion.d.ts +1 -1
  172. package/lib/packageVersion.js +1 -1
  173. package/lib/packageVersion.js.map +1 -1
  174. package/lib/pendingStateManager.d.ts +2 -2
  175. package/lib/pendingStateManager.d.ts.map +1 -1
  176. package/lib/pendingStateManager.js +22 -22
  177. package/lib/pendingStateManager.js.map +1 -1
  178. package/lib/scheduleManager.js +14 -10
  179. package/lib/scheduleManager.js.map +1 -1
  180. package/lib/summary/orderedClientElection.d.ts +2 -1
  181. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  182. package/lib/summary/orderedClientElection.js +17 -18
  183. package/lib/summary/orderedClientElection.js.map +1 -1
  184. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  185. package/lib/summary/runningSummarizer.js +35 -57
  186. package/lib/summary/runningSummarizer.js.map +1 -1
  187. package/lib/summary/summarizer.js +4 -7
  188. package/lib/summary/summarizer.js.map +1 -1
  189. package/lib/summary/summarizerClientElection.js +5 -9
  190. package/lib/summary/summarizerClientElection.js.map +1 -1
  191. package/lib/summary/summarizerHeuristics.js +8 -12
  192. package/lib/summary/summarizerHeuristics.js.map +1 -1
  193. package/lib/summary/summarizerNode/summarizerNode.js +22 -15
  194. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  195. package/lib/summary/summarizerNode/summarizerNodeUtils.js +2 -4
  196. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  197. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +17 -16
  198. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  199. package/lib/summary/summaryCollection.js +3 -5
  200. package/lib/summary/summaryCollection.js.map +1 -1
  201. package/lib/summary/summaryFormat.js +1 -2
  202. package/lib/summary/summaryFormat.js.map +1 -1
  203. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  204. package/lib/summary/summaryGenerator.js +62 -21
  205. package/lib/summary/summaryGenerator.js.map +1 -1
  206. package/lib/summary/summaryManager.js +3 -5
  207. package/lib/summary/summaryManager.js.map +1 -1
  208. package/package.json +19 -19
  209. package/src/batchTracker.ts +2 -1
  210. package/src/blobManager.ts +43 -2
  211. package/src/containerRuntime.ts +95 -67
  212. package/src/dataStore.ts +7 -1
  213. package/src/dataStoreContext.ts +1 -2
  214. package/src/dataStores.ts +95 -55
  215. package/src/deltaManagerProxyBase.ts +111 -0
  216. package/src/deltaManagerSummarizerProxy.ts +2 -1
  217. package/src/gc/gcTelemetry.ts +1 -2
  218. package/src/index.ts +0 -1
  219. package/src/packageVersion.ts +1 -1
  220. package/src/pendingStateManager.ts +12 -15
  221. package/src/summary/orderedClientElection.ts +2 -1
  222. package/src/summary/runningSummarizer.ts +9 -31
  223. package/src/summary/summaryGenerator.ts +0 -1
@@ -119,13 +119,12 @@ class DataStores {
119
119
  return pendingAliasPromise === undefined ? "Success" : pendingAliasPromise;
120
120
  }
121
121
  processAttachMessage(message, local) {
122
- var _a, _b;
123
122
  const attachMessage = message.contents;
124
123
  this.dataStoresSinceLastGC.push(attachMessage.id);
125
124
  // The local object has already been attached
126
125
  if (local) {
127
126
  (0, common_utils_1.assert)(this.pendingAttach.has(attachMessage.id), 0x15e /* "Local object does not have matching attach message id" */);
128
- (_a = this.contexts.get(attachMessage.id)) === null || _a === void 0 ? void 0 : _a.emit("attached");
127
+ this.contexts.get(attachMessage.id)?.emit("attached");
129
128
  this.pendingAttach.delete(attachMessage.id);
130
129
  return;
131
130
  }
@@ -134,7 +133,10 @@ class DataStores {
134
133
  // TODO: dataStoreId may require a different tag from PackageData #7488
135
134
  const error = new container_utils_1.DataCorruptionError(
136
135
  // pre-0.58 error message: duplicateDataStoreCreatedWithExistingId
137
- "Duplicate DataStore created with existing id", Object.assign(Object.assign({}, (0, container_utils_1.extractSafePropertiesFromMessage)(message)), (0, telemetry_utils_1.tagCodeArtifacts)({ dataStoreId: attachMessage.id })));
136
+ "Duplicate DataStore created with existing id", {
137
+ ...(0, container_utils_1.extractSafePropertiesFromMessage)(message),
138
+ ...(0, telemetry_utils_1.tagCodeArtifacts)({ dataStoreId: attachMessage.id }),
139
+ });
138
140
  throw error;
139
141
  }
140
142
  const flatAttachBlobs = new Map();
@@ -154,7 +156,7 @@ class DataStores {
154
156
  createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(attachMessage.id, {
155
157
  type: runtime_definitions_1.CreateSummarizerNodeSource.FromAttach,
156
158
  sequenceNumber: message.sequenceNumber,
157
- snapshot: (_b = attachMessage.snapshot) !== null && _b !== void 0 ? _b : {
159
+ snapshot: attachMessage.snapshot ?? {
158
160
  entries: [(0, dataStoreContext_1.createAttributesBlob)(pkg, true /* isRootDataStore */)],
159
161
  },
160
162
  }),
@@ -165,7 +167,9 @@ class DataStores {
165
167
  processAliasMessage(message, localOpMetadata, local) {
166
168
  const aliasMessage = message.contents;
167
169
  if (!(0, dataStore_1.isDataStoreAliasMessage)(aliasMessage)) {
168
- throw new container_utils_1.DataCorruptionError("malformedDataStoreAliasMessage", Object.assign({}, (0, container_utils_1.extractSafePropertiesFromMessage)(message)));
170
+ throw new container_utils_1.DataCorruptionError("malformedDataStoreAliasMessage", {
171
+ ...(0, container_utils_1.extractSafePropertiesFromMessage)(message),
172
+ });
169
173
  }
170
174
  const resolve = localOpMetadata;
171
175
  const aliasResult = this.processAliasMessageCore(aliasMessage);
@@ -278,9 +282,8 @@ class DataStores {
278
282
  }
279
283
  processFluidDataStoreOp(message, local, localMessageMetadata) {
280
284
  const envelope = message.contents;
281
- const transformed = Object.assign(Object.assign({}, message), { contents: envelope.contents });
282
- const request = { url: envelope.address };
283
- this.validateNotDeleted(envelope.address, request);
285
+ const transformed = { ...message, contents: envelope.contents };
286
+ this.validateNotDeleted(envelope.address);
284
287
  const context = this.contexts.get(envelope.address);
285
288
  (0, common_utils_1.assert)(!!context, 0x162 /* "There should be a store context for the op" */);
286
289
  context.process(transformed, local, localMessageMetadata);
@@ -289,76 +292,121 @@ class DataStores {
289
292
  this.gcNodeUpdated(`/${envelope.address}`, message.timestamp, context.isLoaded ? context.packagePath : undefined);
290
293
  }
291
294
  async getDataStore(id, requestHeaderData) {
292
- const headerData = Object.assign(Object.assign({}, containerRuntime_1.defaultRuntimeHeaderData), requestHeaderData);
293
- const request = { url: id };
294
- this.validateNotDeleted(id, request, headerData);
295
+ const headerData = { ...containerRuntime_1.defaultRuntimeHeaderData, ...requestHeaderData };
296
+ this.validateNotDeleted(id, headerData);
295
297
  const context = await this.contexts.getBoundOrRemoted(id, headerData.wait);
296
298
  if (context === undefined) {
297
299
  // The requested data store does not exits. Throw a 404 response exception.
300
+ const request = { url: id };
298
301
  throw (0, runtime_utils_1.responseToException)((0, runtime_utils_1.create404Response)(request), request);
299
302
  }
300
- this.validateNotTombstoned(context, request, requestHeaderData);
303
+ this.validateNotTombstoned(context, requestHeaderData);
301
304
  return context;
302
305
  }
303
306
  /**
304
- * Validate that the data store had not been deleted by GC.
305
- *
307
+ * Returns the data store requested with the given id if available. Otherwise, returns undefined.
308
+ */
309
+ async getDataStoreIfAvailable(id, requestHeaderData) {
310
+ // If the data store has been deleted, return undefined.
311
+ if (this.checkIfDeleted(id, requestHeaderData)) {
312
+ return undefined;
313
+ }
314
+ const headerData = { ...containerRuntime_1.defaultRuntimeHeaderData, ...requestHeaderData };
315
+ const context = await this.contexts.getBoundOrRemoted(id, headerData.wait);
316
+ if (context === undefined) {
317
+ return undefined;
318
+ }
319
+ // Check if the data store is tombstoned. If so, we want to log a telemetry event.
320
+ this.checkIfTombstoned(context, requestHeaderData);
321
+ return context;
322
+ }
323
+ /**
324
+ * Checks if the data store has been deleted by GC.
306
325
  * @param id - data store id
307
326
  * @param request - the request information to log if the validation detects the data store has been deleted
308
327
  * @param requestHeaderData - the request header information to log if the validation detects the data store has been deleted
328
+ * @returns true if the data store is deleted. Otherwise, returns false.
309
329
  */
310
- validateNotDeleted(id, request, requestHeaderData) {
330
+ checkIfDeleted(id, requestHeaderData) {
311
331
  const dataStoreNodePath = `/${id}`;
312
- if (this.isDataStoreDeleted(dataStoreNodePath)) {
313
- (0, common_utils_1.assert)(!this.contexts.has(id), 0x570 /* Inconsistent state! GC says the data store is deleted, but the data store is not deleted from the runtime. */);
332
+ if (!this.isDataStoreDeleted(dataStoreNodePath)) {
333
+ return false;
334
+ }
335
+ (0, common_utils_1.assert)(!this.contexts.has(id), 0x570 /* Inconsistent state! GC says the data store is deleted, but the data store is not deleted from the runtime. */);
336
+ (0, gc_1.sendGCUnexpectedUsageEvent)(this.mc, {
337
+ eventName: "GC_Deleted_DataStore_Requested",
338
+ category: "error",
339
+ isSummarizerClient: this.runtime.clientDetails.type === summary_1.summarizerClientType,
340
+ id,
341
+ headers: JSON.stringify(requestHeaderData),
342
+ gcTombstoneEnforcementAllowed: this.runtime.gcTombstoneEnforcementAllowed,
343
+ }, undefined /* packagePath */);
344
+ return true;
345
+ }
346
+ /**
347
+ * Validate that the data store had not been deleted by GC.
348
+ * @param id - data store id
349
+ * @param requestHeaderData - the request header information to log if the validation detects the data store has been deleted
350
+ */
351
+ validateNotDeleted(id, requestHeaderData) {
352
+ if (this.checkIfDeleted(id, requestHeaderData)) {
314
353
  // The requested data store is removed by gc. Create a 404 gc response exception.
315
- const error = (0, runtime_utils_1.responseToException)((0, runtime_utils_1.createResponseError)(404, "DataStore was deleted", request), request);
316
- (0, gc_1.sendGCUnexpectedUsageEvent)(this.mc, {
317
- eventName: "GC_Deleted_DataStore_Requested",
318
- category: "error",
319
- isSummarizerClient: this.runtime.clientDetails.type === summary_1.summarizerClientType,
320
- headers: JSON.stringify(requestHeaderData),
321
- gcTombstoneEnforcementAllowed: this.runtime.gcTombstoneEnforcementAllowed,
322
- }, undefined /** packagePath */, error);
323
- throw error;
354
+ const request = { url: id };
355
+ throw (0, runtime_utils_1.responseToException)((0, runtime_utils_1.createResponseError)(404, "DataStore was deleted", request), request);
356
+ }
357
+ }
358
+ /**
359
+ * Checks if the data store has not been marked as tombstone by GC or not.
360
+ * @param context - the data store context in question
361
+ * @param requestHeaderData - the request header information to log if the validation detects the data store has been tombstoned
362
+ * @returns true if the data store is tombstoned. Otherwise, returns false.
363
+ */
364
+ checkIfTombstoned(context, requestHeaderData) {
365
+ if (!context.tombstoned) {
366
+ return false;
324
367
  }
368
+ const logErrorEvent = this.throwOnTombstoneLoad && !requestHeaderData.allowTombstone;
369
+ (0, gc_1.sendGCUnexpectedUsageEvent)(this.mc, {
370
+ eventName: "GC_Tombstone_DataStore_Requested",
371
+ category: logErrorEvent ? "error" : "generic",
372
+ isSummarizerClient: this.runtime.clientDetails.type === summary_1.summarizerClientType,
373
+ id: context.id,
374
+ headers: JSON.stringify(requestHeaderData),
375
+ gcTombstoneEnforcementAllowed: this.runtime.gcTombstoneEnforcementAllowed,
376
+ }, context.isLoaded ? context.packagePath : undefined);
377
+ return true;
325
378
  }
326
379
  /**
327
380
  * Validates that the data store context requested has not been marked as tombstone by GC.
328
- *
329
381
  * @param context - the data store context in question
330
382
  * @param request - the request information to log if the validation detects the data store has been tombstoned
331
- * @param headerData - the request header information to log if the validation detects the data store has been tombstoned
383
+ * @param requestHeaderData - the request header information to log if the validation detects the data store has been tombstoned
332
384
  */
333
- validateNotTombstoned(context, request, headerData) {
334
- if (context.tombstoned) {
335
- const shouldFail = this.throwOnTombstoneLoad && !headerData.allowTombstone;
385
+ validateNotTombstoned(context, requestHeaderData) {
386
+ if (this.checkIfTombstoned(context, requestHeaderData)) {
336
387
  // The requested data store is removed by gc. Create a 404 gc response exception.
388
+ const request = { url: context.id };
337
389
  const error = (0, runtime_utils_1.responseToException)((0, runtime_utils_1.createResponseError)(404, "DataStore was deleted", request, {
338
390
  [containerRuntime_1.TombstoneResponseHeaderKey]: true,
339
391
  }), request);
340
- (0, gc_1.sendGCUnexpectedUsageEvent)(this.mc, {
341
- eventName: "GC_Tombstone_DataStore_Requested",
342
- category: shouldFail ? "error" : "generic",
343
- isSummarizerClient: this.runtime.clientDetails.type === summary_1.summarizerClientType,
344
- headers: JSON.stringify(headerData),
345
- gcTombstoneEnforcementAllowed: this.runtime.gcTombstoneEnforcementAllowed,
346
- }, context.isLoaded ? context.packagePath : undefined, error);
347
- if (shouldFail) {
392
+ // Throw an error if configured via options and via request headers.
393
+ if (this.throwOnTombstoneLoad && !requestHeaderData.allowTombstone) {
348
394
  throw error;
349
395
  }
350
396
  }
351
397
  }
352
398
  processSignal(fluidDataStoreId, message, local) {
353
- const request = { url: fluidDataStoreId };
354
- this.validateNotDeleted(fluidDataStoreId, request);
399
+ this.validateNotDeleted(fluidDataStoreId);
355
400
  const context = this.contexts.get(fluidDataStoreId);
356
401
  if (!context) {
357
402
  // Attach message may not have been processed yet
358
403
  (0, common_utils_1.assert)(!local, 0x163 /* "Missing datastore for local signal" */);
359
- this.mc.logger.sendTelemetryEvent(Object.assign({ eventName: "SignalFluidDataStoreNotFound" }, (0, telemetry_utils_1.tagCodeArtifacts)({
360
- fluidDataStoreId,
361
- })));
404
+ this.mc.logger.sendTelemetryEvent({
405
+ eventName: "SignalFluidDataStoreNotFound",
406
+ ...(0, telemetry_utils_1.tagCodeArtifacts)({
407
+ fluidDataStoreId,
408
+ }),
409
+ });
362
410
  return;
363
411
  }
364
412
  context.processSignal(message, local);
@@ -369,12 +417,17 @@ class DataStores {
369
417
  context.setConnectionState(connected, clientId);
370
418
  }
371
419
  catch (error) {
372
- this.mc.logger.sendErrorEvent(Object.assign(Object.assign({ eventName: "SetConnectionStateError", clientId }, (0, telemetry_utils_1.tagCodeArtifacts)({
373
- fluidDataStoreId,
374
- })), { details: JSON.stringify({
420
+ this.mc.logger.sendErrorEvent({
421
+ eventName: "SetConnectionStateError",
422
+ clientId,
423
+ ...(0, telemetry_utils_1.tagCodeArtifacts)({
424
+ fluidDataStoreId,
425
+ }),
426
+ details: JSON.stringify({
375
427
  runtimeConnected: this.runtime.connected,
376
428
  connected,
377
- }) }), error);
429
+ }),
430
+ }, error);
378
431
  }
379
432
  }
380
433
  }
@@ -495,7 +548,6 @@ class DataStores {
495
548
  * @param usedRoutes - The routes that are used in all data stores in this Container.
496
549
  */
497
550
  updateUsedRoutes(usedRoutes) {
498
- var _a;
499
551
  // Get a map of data store ids to routes used in it.
500
552
  const usedDataStoreRoutes = (0, runtime_utils_1.unpackChildNodesUsedRoutes)(usedRoutes);
501
553
  // Verify that the used routes are correct.
@@ -504,7 +556,7 @@ class DataStores {
504
556
  }
505
557
  // Update the used routes in each data store. Used routes is empty for unused data stores.
506
558
  for (const [contextId, context] of this.contexts) {
507
- context.updateUsedRoutes((_a = usedDataStoreRoutes.get(contextId)) !== null && _a !== void 0 ? _a : []);
559
+ context.updateUsedRoutes(usedDataStoreRoutes.get(contextId) ?? []);
508
560
  }
509
561
  }
510
562
  /**
@@ -603,11 +655,10 @@ class DataStores {
603
655
  * Called by GC to retrieve the package path of a data store node with the given path.
604
656
  */
605
657
  async getDataStorePackagePath(nodePath) {
606
- var _a;
607
658
  // If the node belongs to a data store, return its package path. For DDSes, we return the package path of the
608
659
  // data store that contains it.
609
660
  const context = this.contexts.get(nodePath.split("/")[1]);
610
- return (_a = (await (context === null || context === void 0 ? void 0 : context.getInitialSnapshotDetails()))) === null || _a === void 0 ? void 0 : _a.pkg;
661
+ return (await context?.getInitialSnapshotDetails())?.pkg;
611
662
  }
612
663
  /**
613
664
  * Called by GC to determine if a node is for a data store or for an object within a data store (for e.g. DDS).
@@ -644,7 +695,10 @@ function getSummaryForDatastores(snapshot, metadata) {
644
695
  datastoresTrees[key] = value;
645
696
  }
646
697
  }
647
- return Object.assign(Object.assign({}, snapshot), { trees: datastoresTrees });
698
+ return {
699
+ ...snapshot,
700
+ trees: datastoresTrees,
701
+ };
648
702
  }
649
703
  }
650
704
  exports.getSummaryForDatastores = getSummaryForDatastores;
@@ -1 +1 @@
1
- {"version":3,"file":"dataStores.js","sourceRoot":"","sources":["../src/dataStores.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tDataCorruptionError,\n\textractSafePropertiesFromMessage,\n} from \"@fluidframework/container-utils\";\nimport {\n\tITelemetryBaseLogger,\n\tIDisposable,\n\tIFluidHandle,\n\tIRequest,\n} from \"@fluidframework/core-interfaces\";\nimport { FluidObjectHandle } from \"@fluidframework/datastore\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tAliasResult,\n\tchannelsTreeName,\n\tCreateChildSummarizerNodeFn,\n\tCreateChildSummarizerNodeParam,\n\tCreateSummarizerNodeSource,\n\tIAttachMessage,\n\tIEnvelope,\n\tIFluidDataStoreContextDetached,\n\tIGarbageCollectionData,\n\tIInboundSignalMessage,\n\tInboundAttachMessage,\n\tISummarizeResult,\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n\tconvertSnapshotTreeToSummaryTree,\n\tconvertToSummaryTree,\n\tcreate404Response,\n\tcreateResponseError,\n\tGCDataBuilder,\n\tresponseToException,\n\tSummaryTreeBuilder,\n\tunpackChildNodesUsedRoutes,\n} from \"@fluidframework/runtime-utils\";\nimport {\n\tLoggingError,\n\tMonitoringContext,\n\tcreateChildMonitoringContext,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { buildSnapshotTree } from \"@fluidframework/driver-utils\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { Lazy } from \"@fluidframework/core-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport { DataStoreContexts } from \"./dataStoreContexts\";\nimport {\n\tContainerRuntime,\n\tdefaultRuntimeHeaderData,\n\tRuntimeHeaderData,\n\tTombstoneResponseHeaderKey,\n} from \"./containerRuntime\";\nimport {\n\tFluidDataStoreContext,\n\tRemoteFluidDataStoreContext,\n\tLocalFluidDataStoreContext,\n\tcreateAttributesBlob,\n\tLocalDetachedFluidDataStoreContext,\n} from \"./dataStoreContext\";\nimport { StorageServiceWithAttachBlobs } from \"./storageServiceWithAttachBlobs\";\nimport { IDataStoreAliasMessage, isDataStoreAliasMessage } from \"./dataStore\";\nimport {\n\tGCNodeType,\n\tsweepDatastoresKey,\n\tthrowOnTombstoneLoadKey,\n\tsendGCUnexpectedUsageEvent,\n} from \"./gc\";\nimport {\n\tsummarizerClientType,\n\tIContainerRuntimeMetadata,\n\tnonDataStorePaths,\n\trootHasIsolatedChannels,\n} from \"./summary\";\n\ntype PendingAliasResolve = (success: boolean) => void;\n\n/**\n * This class encapsulates data store handling. Currently it is only used by the container runtime,\n * but eventually could be hosted on any channel once we formalize the channel api boundary.\n */\nexport class DataStores implements IDisposable {\n\t// Stores tracked by the Domain\n\tprivate readonly pendingAttach = new Map<string, IAttachMessage>();\n\t// 0.24 back-compat attachingBeforeSummary\n\tpublic readonly attachOpFiredForDataStore = new Set<string>();\n\n\tprivate readonly mc: MonitoringContext;\n\n\tprivate readonly disposeOnce = new Lazy<void>(() => this.contexts.dispose());\n\n\tpublic readonly containerLoadStats: {\n\t\t// number of dataStores during loadContainer\n\t\treadonly containerLoadDataStoreCount: number;\n\t\t// number of unreferenced dataStores during loadContainer\n\t\treadonly referencedDataStoreCount: number;\n\t};\n\n\t// Stores the ids of new data stores between two GC runs. This is used to notify the garbage collector of new\n\t// root data stores that are added.\n\tprivate dataStoresSinceLastGC: string[] = [];\n\t/** If true, throw an error when a tombstone data store is retrieved. */\n\tprivate readonly throwOnTombstoneLoad: boolean;\n\t// The handle to the container runtime. This is used mainly for GC purposes to represent outbound reference from\n\t// the container runtime to other nodes.\n\tprivate readonly containerRuntimeHandle: IFluidHandle;\n\tprivate readonly pendingAliasMap: Map<string, Promise<AliasResult>> = new Map<\n\t\tstring,\n\t\tPromise<AliasResult>\n\t>();\n\n\tconstructor(\n\t\tprivate readonly baseSnapshot: ISnapshotTree | undefined,\n\t\tprivate readonly runtime: ContainerRuntime,\n\t\tprivate readonly submitAttachFn: (attachContent: IAttachMessage) => void,\n\t\tprivate readonly getCreateChildSummarizerNodeFn: (\n\t\t\tid: string,\n\t\t\tcreateParam: CreateChildSummarizerNodeParam,\n\t\t) => CreateChildSummarizerNodeFn,\n\t\tprivate readonly deleteChildSummarizerNodeFn: (id: string) => void,\n\t\tbaseLogger: ITelemetryBaseLogger,\n\t\tprivate readonly gcNodeUpdated: (\n\t\t\tnodePath: string,\n\t\t\ttimestampMs: number,\n\t\t\tpackagePath?: readonly string[],\n\t\t) => void,\n\t\tprivate readonly isDataStoreDeleted: (nodePath: string) => boolean,\n\t\tprivate readonly aliasMap: Map<string, string>,\n\t\tprivate readonly contexts: DataStoreContexts = new DataStoreContexts(baseLogger),\n\t) {\n\t\tthis.mc = createChildMonitoringContext({ logger: baseLogger });\n\t\tthis.containerRuntimeHandle = new FluidObjectHandle(\n\t\t\tthis.runtime,\n\t\t\t\"/\",\n\t\t\tthis.runtime.IFluidHandleContext,\n\t\t);\n\n\t\t// Tombstone should only throw when the feature flag is enabled and the client isn't a summarizer\n\t\tthis.throwOnTombstoneLoad =\n\t\t\tthis.mc.config.getBoolean(throwOnTombstoneLoadKey) === true &&\n\t\t\tthis.runtime.gcTombstoneEnforcementAllowed &&\n\t\t\tthis.runtime.clientDetails.type !== summarizerClientType;\n\n\t\t// Extract stores stored inside the snapshot\n\t\tconst fluidDataStores = new Map<string, ISnapshotTree>();\n\t\tif (baseSnapshot) {\n\t\t\tfor (const [key, value] of Object.entries(baseSnapshot.trees)) {\n\t\t\t\tfluidDataStores.set(key, value);\n\t\t\t}\n\t\t}\n\n\t\tlet unreferencedDataStoreCount = 0;\n\t\t// Create a context for each of them\n\t\tfor (const [key, value] of fluidDataStores) {\n\t\t\tlet dataStoreContext: FluidDataStoreContext;\n\n\t\t\t// counting number of unreferenced data stores\n\t\t\tif (value.unreferenced) {\n\t\t\t\tunreferencedDataStoreCount++;\n\t\t\t}\n\t\t\t// If we have a detached container, then create local data store contexts.\n\t\t\tif (this.runtime.attachState !== AttachState.Detached) {\n\t\t\t\tdataStoreContext = new RemoteFluidDataStoreContext({\n\t\t\t\t\tid: key,\n\t\t\t\t\tsnapshotTree: value,\n\t\t\t\t\truntime: this.runtime,\n\t\t\t\t\tstorage: this.runtime.storage,\n\t\t\t\t\tscope: this.runtime.scope,\n\t\t\t\t\tcreateSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(key, {\n\t\t\t\t\t\ttype: CreateSummarizerNodeSource.FromSummary,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tif (typeof value !== \"object\") {\n\t\t\t\t\tthrow new LoggingError(\"Snapshot should be there to load from!!\");\n\t\t\t\t}\n\t\t\t\tconst snapshotTree = value;\n\t\t\t\tdataStoreContext = new LocalFluidDataStoreContext({\n\t\t\t\t\tid: key,\n\t\t\t\t\tpkg: undefined,\n\t\t\t\t\truntime: this.runtime,\n\t\t\t\t\tstorage: this.runtime.storage,\n\t\t\t\t\tscope: this.runtime.scope,\n\t\t\t\t\tcreateSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(key, {\n\t\t\t\t\t\ttype: CreateSummarizerNodeSource.FromSummary,\n\t\t\t\t\t}),\n\t\t\t\t\tmakeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(key),\n\t\t\t\t\tsnapshotTree,\n\t\t\t\t\tisRootDataStore: undefined,\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.contexts.addBoundOrRemoted(dataStoreContext);\n\t\t}\n\t\tthis.containerLoadStats = {\n\t\t\tcontainerLoadDataStoreCount: fluidDataStores.size,\n\t\t\treferencedDataStoreCount: fluidDataStores.size - unreferencedDataStoreCount,\n\t\t};\n\t}\n\n\tpublic get aliases(): ReadonlyMap<string, string> {\n\t\treturn this.aliasMap;\n\t}\n\n\tpublic get pendingAliases(): Map<string, Promise<AliasResult>> {\n\t\treturn this.pendingAliasMap;\n\t}\n\n\tpublic async waitIfPendingAlias(maybeAlias: string): Promise<AliasResult> {\n\t\tconst pendingAliasPromise = this.pendingAliases.get(maybeAlias);\n\t\treturn pendingAliasPromise === undefined ? \"Success\" : pendingAliasPromise;\n\t}\n\n\tpublic processAttachMessage(message: ISequencedDocumentMessage, local: boolean) {\n\t\tconst attachMessage = message.contents as InboundAttachMessage;\n\n\t\tthis.dataStoresSinceLastGC.push(attachMessage.id);\n\n\t\t// The local object has already been attached\n\t\tif (local) {\n\t\t\tassert(\n\t\t\t\tthis.pendingAttach.has(attachMessage.id),\n\t\t\t\t0x15e /* \"Local object does not have matching attach message id\" */,\n\t\t\t);\n\t\t\tthis.contexts.get(attachMessage.id)?.emit(\"attached\");\n\t\t\tthis.pendingAttach.delete(attachMessage.id);\n\t\t\treturn;\n\t\t}\n\n\t\t// If a non-local operation then go and create the object, otherwise mark it as officially attached.\n\t\tif (this.alreadyProcessed(attachMessage.id)) {\n\t\t\t// TODO: dataStoreId may require a different tag from PackageData #7488\n\t\t\tconst error = new DataCorruptionError(\n\t\t\t\t// pre-0.58 error message: duplicateDataStoreCreatedWithExistingId\n\t\t\t\t\"Duplicate DataStore created with existing id\",\n\t\t\t\t{\n\t\t\t\t\t...extractSafePropertiesFromMessage(message),\n\t\t\t\t\t...tagCodeArtifacts({ dataStoreId: attachMessage.id }),\n\t\t\t\t},\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\n\t\tconst flatAttachBlobs = new Map<string, ArrayBufferLike>();\n\t\tlet snapshotTree: ISnapshotTree | undefined;\n\t\tif (attachMessage.snapshot) {\n\t\t\tsnapshotTree = buildSnapshotTree(attachMessage.snapshot.entries, flatAttachBlobs);\n\t\t}\n\n\t\t// Include the type of attach message which is the pkg of the store to be\n\t\t// used by RemoteFluidDataStoreContext in case it is not in the snapshot.\n\t\tconst pkg = [attachMessage.type];\n\t\tconst remoteFluidDataStoreContext = new RemoteFluidDataStoreContext({\n\t\t\tid: attachMessage.id,\n\t\t\tsnapshotTree,\n\t\t\truntime: this.runtime,\n\t\t\tstorage: new StorageServiceWithAttachBlobs(this.runtime.storage, flatAttachBlobs),\n\t\t\tscope: this.runtime.scope,\n\t\t\tcreateSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(attachMessage.id, {\n\t\t\t\ttype: CreateSummarizerNodeSource.FromAttach,\n\t\t\t\tsequenceNumber: message.sequenceNumber,\n\t\t\t\tsnapshot: attachMessage.snapshot ?? {\n\t\t\t\t\tentries: [createAttributesBlob(pkg, true /* isRootDataStore */)],\n\t\t\t\t},\n\t\t\t}),\n\t\t\tpkg,\n\t\t});\n\n\t\tthis.contexts.addBoundOrRemoted(remoteFluidDataStoreContext);\n\t}\n\n\tpublic processAliasMessage(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocalOpMetadata: unknown,\n\t\tlocal: boolean,\n\t): void {\n\t\tconst aliasMessage = message.contents as IDataStoreAliasMessage;\n\t\tif (!isDataStoreAliasMessage(aliasMessage)) {\n\t\t\tthrow new DataCorruptionError(\"malformedDataStoreAliasMessage\", {\n\t\t\t\t...extractSafePropertiesFromMessage(message),\n\t\t\t});\n\t\t}\n\n\t\tconst resolve = localOpMetadata as PendingAliasResolve;\n\t\tconst aliasResult = this.processAliasMessageCore(aliasMessage);\n\t\tif (local) {\n\t\t\tresolve(aliasResult);\n\t\t}\n\t}\n\n\tpublic processAliasMessageCore(aliasMessage: IDataStoreAliasMessage): boolean {\n\t\tif (this.alreadyProcessed(aliasMessage.alias)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst context = this.contexts.get(aliasMessage.internalId);\n\t\tif (context === undefined) {\n\t\t\tthis.mc.logger.sendErrorEvent({\n\t\t\t\teventName: \"AliasFluidDataStoreNotFound\",\n\t\t\t\tfluidDataStoreId: aliasMessage.internalId,\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\tconst handle = new FluidObjectHandle(\n\t\t\tcontext,\n\t\t\taliasMessage.internalId,\n\t\t\tthis.runtime.IFluidHandleContext,\n\t\t);\n\t\tthis.runtime.addedGCOutboundReference(this.containerRuntimeHandle, handle);\n\n\t\tthis.aliasMap.set(aliasMessage.alias, context.id);\n\t\tcontext.setInMemoryRoot();\n\t\treturn true;\n\t}\n\n\tprivate alreadyProcessed(id: string): boolean {\n\t\treturn this.aliasMap.get(id) !== undefined || this.contexts.get(id) !== undefined;\n\t}\n\n\t/**\n\t * Make the data stores locally visible in the container graph by moving the data store context from unbound to\n\t * bound list. This data store can now be reached from the root.\n\t * @param id - The id of the data store context to make visible.\n\t */\n\tprivate makeDataStoreLocallyVisible(id: string): void {\n\t\tconst localContext = this.contexts.getUnbound(id);\n\t\tassert(!!localContext, 0x15f /* \"Could not find unbound context to bind\" */);\n\n\t\t/**\n\t\t * If the container is not detached, it is globally visible to all clients. This data store should also be\n\t\t * globally visible. Move it to attaching state and send an \"attach\" op for it.\n\t\t * If the container is detached, this data store will be part of the summary that makes the container attached.\n\t\t */\n\t\tif (this.runtime.attachState !== AttachState.Detached) {\n\t\t\tlocalContext.emit(\"attaching\");\n\t\t\tconst message = localContext.generateAttachMessage();\n\n\t\t\tthis.pendingAttach.set(id, message);\n\t\t\tthis.submitAttachFn(message);\n\t\t\tthis.attachOpFiredForDataStore.add(id);\n\t\t}\n\n\t\tthis.contexts.bind(id);\n\t}\n\n\tpublic createDetachedDataStoreCore(\n\t\tpkg: Readonly<string[]>,\n\t\tisRoot: boolean,\n\t\tid = uuid(),\n\t): IFluidDataStoreContextDetached {\n\t\tassert(!id.includes(\"/\"), 0x30c /* Id cannot contain slashes */);\n\n\t\tconst context = new LocalDetachedFluidDataStoreContext({\n\t\t\tid,\n\t\t\tpkg,\n\t\t\truntime: this.runtime,\n\t\t\tstorage: this.runtime.storage,\n\t\t\tscope: this.runtime.scope,\n\t\t\tcreateSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(id, {\n\t\t\t\ttype: CreateSummarizerNodeSource.Local,\n\t\t\t}),\n\t\t\tmakeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(id),\n\t\t\tsnapshotTree: undefined,\n\t\t\tisRootDataStore: isRoot,\n\t\t});\n\t\tthis.contexts.addUnbound(context);\n\t\treturn context;\n\t}\n\n\tpublic _createFluidDataStoreContext(pkg: string[], id: string, props?: any) {\n\t\tassert(!id.includes(\"/\"), 0x30d /* Id cannot contain slashes */);\n\t\tconst context = new LocalFluidDataStoreContext({\n\t\t\tid,\n\t\t\tpkg,\n\t\t\truntime: this.runtime,\n\t\t\tstorage: this.runtime.storage,\n\t\t\tscope: this.runtime.scope,\n\t\t\tcreateSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(id, {\n\t\t\t\ttype: CreateSummarizerNodeSource.Local,\n\t\t\t}),\n\t\t\tmakeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(id),\n\t\t\tsnapshotTree: undefined,\n\t\t\tisRootDataStore: false,\n\t\t\tcreateProps: props,\n\t\t});\n\t\tthis.contexts.addUnbound(context);\n\t\treturn context;\n\t}\n\n\tpublic get disposed() {\n\t\treturn this.disposeOnce.evaluated;\n\t}\n\tpublic readonly dispose = () => this.disposeOnce.value;\n\n\tpublic resubmitDataStoreOp(envelope: IEnvelope, localOpMetadata: unknown) {\n\t\tconst context = this.contexts.get(envelope.address);\n\t\tassert(!!context, 0x160 /* \"There should be a store context for the op\" */);\n\t\tcontext.reSubmit(envelope.contents, localOpMetadata);\n\t}\n\n\tpublic rollbackDataStoreOp(envelope: IEnvelope, localOpMetadata: unknown) {\n\t\tconst context = this.contexts.get(envelope.address);\n\t\tassert(!!context, 0x2e8 /* \"There should be a store context for the op\" */);\n\t\tcontext.rollback(envelope.contents, localOpMetadata);\n\t}\n\n\tpublic async applyStashedOp(envelope: IEnvelope): Promise<unknown> {\n\t\tconst context = this.contexts.get(envelope.address);\n\t\tassert(!!context, 0x161 /* \"There should be a store context for the op\" */);\n\t\treturn context.applyStashedOp(envelope.contents);\n\t}\n\n\tpublic async applyStashedAttachOp(message: IAttachMessage) {\n\t\tthis.pendingAttach.set(message.id, message);\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\tthis.processAttachMessage({ contents: message } as ISequencedDocumentMessage, false);\n\t}\n\n\tpublic processFluidDataStoreOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalMessageMetadata: unknown,\n\t) {\n\t\tconst envelope = message.contents as IEnvelope;\n\t\tconst transformed = { ...message, contents: envelope.contents };\n\t\tconst request = { url: envelope.address };\n\t\tthis.validateNotDeleted(envelope.address, request);\n\t\tconst context = this.contexts.get(envelope.address);\n\t\tassert(!!context, 0x162 /* \"There should be a store context for the op\" */);\n\t\tcontext.process(transformed, local, localMessageMetadata);\n\n\t\t// Notify that a GC node for the data store changed. This is used to detect if a deleted data store is\n\t\t// being used.\n\t\tthis.gcNodeUpdated(\n\t\t\t`/${envelope.address}`,\n\t\t\tmessage.timestamp,\n\t\t\tcontext.isLoaded ? context.packagePath : undefined,\n\t\t);\n\t}\n\n\tpublic async getDataStore(\n\t\tid: string,\n\t\trequestHeaderData: RuntimeHeaderData,\n\t): Promise<FluidDataStoreContext> {\n\t\tconst headerData = { ...defaultRuntimeHeaderData, ...requestHeaderData };\n\t\tconst request = { url: id };\n\n\t\tthis.validateNotDeleted(id, request, headerData);\n\n\t\tconst context = await this.contexts.getBoundOrRemoted(id, headerData.wait);\n\t\tif (context === undefined) {\n\t\t\t// The requested data store does not exits. Throw a 404 response exception.\n\t\t\tthrow responseToException(create404Response(request), request);\n\t\t}\n\n\t\tthis.validateNotTombstoned(context, request, requestHeaderData);\n\n\t\treturn context;\n\t}\n\n\t/**\n\t * Validate that the data store had not been deleted by GC.\n\t *\n\t * @param id - data store id\n\t * @param request - the request information to log if the validation detects the data store has been deleted\n\t * @param requestHeaderData - the request header information to log if the validation detects the data store has been deleted\n\t */\n\tprivate validateNotDeleted(\n\t\tid: string,\n\t\trequest: IRequest,\n\t\trequestHeaderData?: RuntimeHeaderData,\n\t) {\n\t\tconst dataStoreNodePath = `/${id}`;\n\t\tif (this.isDataStoreDeleted(dataStoreNodePath)) {\n\t\t\tassert(\n\t\t\t\t!this.contexts.has(id),\n\t\t\t\t0x570 /* Inconsistent state! GC says the data store is deleted, but the data store is not deleted from the runtime. */,\n\t\t\t);\n\t\t\t// The requested data store is removed by gc. Create a 404 gc response exception.\n\t\t\tconst error = responseToException(\n\t\t\t\tcreateResponseError(404, \"DataStore was deleted\", request),\n\t\t\t\trequest,\n\t\t\t);\n\t\t\tsendGCUnexpectedUsageEvent(\n\t\t\t\tthis.mc,\n\t\t\t\t{\n\t\t\t\t\teventName: \"GC_Deleted_DataStore_Requested\",\n\t\t\t\t\tcategory: \"error\",\n\t\t\t\t\tisSummarizerClient: this.runtime.clientDetails.type === summarizerClientType,\n\t\t\t\t\theaders: JSON.stringify(requestHeaderData),\n\t\t\t\t\tgcTombstoneEnforcementAllowed: this.runtime.gcTombstoneEnforcementAllowed,\n\t\t\t\t},\n\t\t\t\tundefined /** packagePath */,\n\t\t\t\terror,\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Validates that the data store context requested has not been marked as tombstone by GC.\n\t *\n\t * @param context - the data store context in question\n\t * @param request - the request information to log if the validation detects the data store has been tombstoned\n\t * @param headerData - the request header information to log if the validation detects the data store has been tombstoned\n\t */\n\tprivate validateNotTombstoned(\n\t\tcontext: FluidDataStoreContext,\n\t\trequest: IRequest,\n\t\theaderData: RuntimeHeaderData,\n\t) {\n\t\tif (context.tombstoned) {\n\t\t\tconst shouldFail = this.throwOnTombstoneLoad && !headerData.allowTombstone;\n\n\t\t\t// The requested data store is removed by gc. Create a 404 gc response exception.\n\t\t\tconst error = responseToException(\n\t\t\t\tcreateResponseError(404, \"DataStore was deleted\", request, {\n\t\t\t\t\t[TombstoneResponseHeaderKey]: true,\n\t\t\t\t}),\n\t\t\t\trequest,\n\t\t\t);\n\t\t\tsendGCUnexpectedUsageEvent(\n\t\t\t\tthis.mc,\n\t\t\t\t{\n\t\t\t\t\teventName: \"GC_Tombstone_DataStore_Requested\",\n\t\t\t\t\tcategory: shouldFail ? \"error\" : \"generic\",\n\t\t\t\t\tisSummarizerClient: this.runtime.clientDetails.type === summarizerClientType,\n\t\t\t\t\theaders: JSON.stringify(headerData),\n\t\t\t\t\tgcTombstoneEnforcementAllowed: this.runtime.gcTombstoneEnforcementAllowed,\n\t\t\t\t},\n\t\t\t\tcontext.isLoaded ? context.packagePath : undefined,\n\t\t\t\terror,\n\t\t\t);\n\n\t\t\tif (shouldFail) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic processSignal(fluidDataStoreId: string, message: IInboundSignalMessage, local: boolean) {\n\t\tconst request = { url: fluidDataStoreId };\n\t\tthis.validateNotDeleted(fluidDataStoreId, request);\n\t\tconst context = this.contexts.get(fluidDataStoreId);\n\t\tif (!context) {\n\t\t\t// Attach message may not have been processed yet\n\t\t\tassert(!local, 0x163 /* \"Missing datastore for local signal\" */);\n\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"SignalFluidDataStoreNotFound\",\n\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\tfluidDataStoreId,\n\t\t\t\t}),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tcontext.processSignal(message, local);\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\tfor (const [fluidDataStoreId, context] of this.contexts) {\n\t\t\ttry {\n\t\t\t\tcontext.setConnectionState(connected, clientId);\n\t\t\t} catch (error) {\n\t\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"SetConnectionStateError\",\n\t\t\t\t\t\tclientId,\n\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\tfluidDataStoreId,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t\truntimeConnected: this.runtime.connected,\n\t\t\t\t\t\t\tconnected,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {\n\t\tconst eventName = attachState === AttachState.Attaching ? \"attaching\" : \"attached\";\n\t\tfor (const [, context] of this.contexts) {\n\t\t\t// Fire only for bounded stores.\n\t\t\tif (!this.contexts.isNotBound(context.id)) {\n\t\t\t\tcontext.emit(eventName);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic get size(): number {\n\t\treturn this.contexts.size;\n\t}\n\n\tpublic async summarize(\n\t\tfullTree: boolean,\n\t\ttrackState: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummaryTreeWithStats> {\n\t\tconst summaryBuilder = new SummaryTreeBuilder();\n\n\t\t// Iterate over each store and ask it to snapshot\n\t\tawait Promise.all(\n\t\t\tArray.from(this.contexts)\n\t\t\t\t.filter(([_, context]) => {\n\t\t\t\t\t// Summarizer works only with clients with no local changes. A data store in attaching\n\t\t\t\t\t// state indicates an op was sent to attach a local data store.\n\t\t\t\t\tassert(\n\t\t\t\t\t\tcontext.attachState !== AttachState.Attaching,\n\t\t\t\t\t\t0x588 /* Local data store detected in attaching state during summarize */,\n\t\t\t\t\t);\n\t\t\t\t\treturn context.attachState === AttachState.Attached;\n\t\t\t\t})\n\t\t\t\t.map(async ([contextId, context]) => {\n\t\t\t\t\tconst contextSummary = await context.summarize(\n\t\t\t\t\t\tfullTree,\n\t\t\t\t\t\ttrackState,\n\t\t\t\t\t\ttelemetryContext,\n\t\t\t\t\t);\n\t\t\t\t\tsummaryBuilder.addWithStats(contextId, contextSummary);\n\t\t\t\t}),\n\t\t);\n\n\t\treturn summaryBuilder.getSummaryTree();\n\t}\n\n\tpublic createSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {\n\t\tconst builder = new SummaryTreeBuilder();\n\t\t// Attaching graph of some stores can cause other stores to get bound too.\n\t\t// So keep taking summary until no new stores get bound.\n\t\tlet notBoundContextsLength: number;\n\t\tdo {\n\t\t\tconst builderTree = builder.summary.tree;\n\t\t\tnotBoundContextsLength = this.contexts.notBoundLength();\n\t\t\t// Iterate over each data store and ask it to snapshot\n\t\t\tArray.from(this.contexts)\n\t\t\t\t.filter(\n\t\t\t\t\t([key, _]) =>\n\t\t\t\t\t\t// Take summary of bounded data stores only, make sure we haven't summarized them already\n\t\t\t\t\t\t// and no attach op has been fired for that data store because for loader versions <= 0.24\n\t\t\t\t\t\t// we set attach state as \"attaching\" before taking createNew summary.\n\t\t\t\t\t\t!(\n\t\t\t\t\t\t\tthis.contexts.isNotBound(key) ||\n\t\t\t\t\t\t\tbuilderTree[key] ||\n\t\t\t\t\t\t\tthis.attachOpFiredForDataStore.has(key)\n\t\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\t.map(([key, value]) => {\n\t\t\t\t\tlet dataStoreSummary: ISummarizeResult;\n\t\t\t\t\tif (value.isLoaded) {\n\t\t\t\t\t\tconst snapshot = value.generateAttachMessage().snapshot;\n\t\t\t\t\t\tdataStoreSummary = convertToSummaryTree(snapshot, true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If this data store is not yet loaded, then there should be no changes in the snapshot from\n\t\t\t\t\t\t// which it was created as it is detached container. So just use the previous snapshot.\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\t!!this.baseSnapshot,\n\t\t\t\t\t\t\t0x166 /* \"BaseSnapshot should be there as detached container loaded from snapshot\" */,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdataStoreSummary = convertSnapshotTreeToSummaryTree(\n\t\t\t\t\t\t\tthis.baseSnapshot.trees[key],\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tbuilder.addWithStats(key, dataStoreSummary);\n\t\t\t\t});\n\t\t} while (notBoundContextsLength !== this.contexts.notBoundLength());\n\n\t\treturn builder.getSummaryTree();\n\t}\n\n\t/**\n\t * Before GC runs, called by the garbage collector to update any pending GC state.\n\t * The garbage collector needs to know all outbound references that are added. Since root data stores are not\n\t * explicitly marked as referenced, notify GC of new root data stores that were added since the last GC run.\n\t */\n\tpublic async updateStateBeforeGC(): Promise<void> {\n\t\tfor (const id of this.dataStoresSinceLastGC) {\n\t\t\tconst context = this.contexts.get(id);\n\t\t\tassert(context !== undefined, 0x2b6 /* Missing data store context */);\n\t\t\tif (await context.isRoot()) {\n\t\t\t\t// A root data store is basically a reference from the container runtime to the data store.\n\t\t\t\tconst handle = new FluidObjectHandle(context, id, this.runtime.IFluidHandleContext);\n\t\t\t\tthis.runtime.addedGCOutboundReference(this.containerRuntimeHandle, handle);\n\t\t\t}\n\t\t}\n\t\tthis.dataStoresSinceLastGC = [];\n\t}\n\n\t/**\n\t * Generates data used for garbage collection. It does the following:\n\t *\n\t * 1. Calls into each child data store context to get its GC data.\n\t *\n\t * 2. Prefixes the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be\n\t * identified as belonging to the child.\n\t *\n\t * 3. Adds a GC node for this channel to the nodes received from the children. All these nodes together represent\n\t * the GC data of this channel.\n\t *\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tconst builder = new GCDataBuilder();\n\t\t// Iterate over each store and get their GC data.\n\t\tawait Promise.all(\n\t\t\tArray.from(this.contexts)\n\t\t\t\t.filter(([_, context]) => {\n\t\t\t\t\t// Summarizer client and hence GC works only with clients with no local changes. A data store in\n\t\t\t\t\t// attaching state indicates an op was sent to attach a local data store.\n\t\t\t\t\tassert(\n\t\t\t\t\t\tcontext.attachState !== AttachState.Attaching,\n\t\t\t\t\t\t0x589 /* Local data store detected in attaching state while running GC */,\n\t\t\t\t\t);\n\t\t\t\t\treturn context.attachState === AttachState.Attached;\n\t\t\t\t})\n\t\t\t\t.map(async ([contextId, context]) => {\n\t\t\t\t\tconst contextGCData = await context.getGCData(fullGC);\n\t\t\t\t\t// Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.\n\t\t\t\t\t// This also gradually builds the id of each node to be a path from the root.\n\t\t\t\t\tbuilder.prefixAndAddNodes(contextId, contextGCData.gcNodes);\n\t\t\t\t}),\n\t\t);\n\n\t\t// Get the outbound routes and add a GC node for this channel.\n\t\tbuilder.addNode(\"/\", await this.getOutboundRoutes());\n\t\treturn builder.getGCData();\n\t}\n\n\t/**\n\t * After GC has run, called to notify this Container's data stores of routes that are used in it.\n\t * @param usedRoutes - The routes that are used in all data stores in this Container.\n\t */\n\tpublic updateUsedRoutes(usedRoutes: string[]) {\n\t\t// Get a map of data store ids to routes used in it.\n\t\tconst usedDataStoreRoutes = unpackChildNodesUsedRoutes(usedRoutes);\n\n\t\t// Verify that the used routes are correct.\n\t\tfor (const [id] of usedDataStoreRoutes) {\n\t\t\tassert(\n\t\t\t\tthis.contexts.has(id),\n\t\t\t\t0x167 /* \"Used route does not belong to any known data store\" */,\n\t\t\t);\n\t\t}\n\n\t\t// Update the used routes in each data store. Used routes is empty for unused data stores.\n\t\tfor (const [contextId, context] of this.contexts) {\n\t\t\tcontext.updateUsedRoutes(usedDataStoreRoutes.get(contextId) ?? []);\n\t\t}\n\t}\n\n\t/**\n\t * This is called to update objects whose routes are unused. The unused objects are deleted.\n\t * @param unusedRoutes - The routes that are unused in all data stores in this Container.\n\t */\n\tpublic updateUnusedRoutes(unusedRoutes: string[]) {\n\t\tfor (const route of unusedRoutes) {\n\t\t\tconst pathParts = route.split(\"/\");\n\t\t\t// Delete data store only if its route (/datastoreId) is in unusedRoutes. We don't want to delete a data\n\t\t\t// store based on its DDS being unused.\n\t\t\tif (pathParts.length > 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst dataStoreId = pathParts[1];\n\t\t\tassert(this.contexts.has(dataStoreId), 0x2d7 /* No data store with specified id */);\n\t\t\t// Delete the contexts of unused data stores.\n\t\t\tthis.contexts.delete(dataStoreId);\n\t\t\t// Delete the summarizer node of the unused data stores.\n\t\t\tthis.deleteChildSummarizerNodeFn(dataStoreId);\n\t\t}\n\t}\n\n\t/**\n\t * Delete data stores and its objects that are sweep ready.\n\t * @param sweepReadyDataStoreRoutes - The routes of data stores and its objects that are sweep ready and should\n\t * be deleted.\n\t * @returns - The routes of data stores and its objects that were deleted.\n\t */\n\tpublic deleteSweepReadyNodes(sweepReadyDataStoreRoutes: string[]): string[] {\n\t\t// If sweep for data stores is not enabled, return empty list indicating nothing is deleted.\n\t\tif (this.mc.config.getBoolean(sweepDatastoresKey) !== true) {\n\t\t\treturn [];\n\t\t}\n\t\tfor (const route of sweepReadyDataStoreRoutes) {\n\t\t\tconst pathParts = route.split(\"/\");\n\t\t\tconst dataStoreId = pathParts[1];\n\n\t\t\t// TODO: GC:Validation - Skip any routes already deleted\n\t\t\t// Ignore sub-data store routes because a data store and its sub-routes are deleted together, so, we only\n\t\t\t// need to delete the data store.\n\t\t\tif (pathParts.length > 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!this.contexts.has(dataStoreId)) {\n\t\t\t\tthis.mc.logger.sendErrorEvent({\n\t\t\t\t\teventName: \"DeletedDataStoreNotFound\",\n\t\t\t\t\tdataStoreId,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst dataStore = this.contexts.get(dataStoreId);\n\t\t\tassert(dataStore !== undefined, 0x571 /* Attempting to delete unknown dataStore */);\n\t\t\tdataStore.delete();\n\n\t\t\t// Delete the contexts of sweep ready data stores.\n\t\t\tthis.contexts.delete(dataStoreId);\n\t\t\t// Delete the summarizer node of the sweep ready data stores.\n\t\t\tthis.deleteChildSummarizerNodeFn(dataStoreId);\n\t\t}\n\t\treturn Array.from(sweepReadyDataStoreRoutes);\n\t}\n\n\t/**\n\t * This is called to update objects whose routes are tombstones. Tombstoned datastore contexts enable testing\n\t * scenarios with accessing deleted content without actually deleting content from summaries.\n\t * @param tombstonedRoutes - The routes that are tombstones in all data stores in this Container.\n\t */\n\tpublic updateTombstonedRoutes(tombstonedRoutes: string[]) {\n\t\tconst tombstonedDataStoresSet: Set<string> = new Set();\n\t\tfor (const route of tombstonedRoutes) {\n\t\t\tconst pathParts = route.split(\"/\");\n\t\t\t// Tombstone data store only if its route (/datastoreId) is directly in tombstoneRoutes.\n\t\t\tif (pathParts.length > 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst dataStoreId = pathParts[1];\n\t\t\tassert(this.contexts.has(dataStoreId), 0x510 /* No data store with specified id */);\n\t\t\ttombstonedDataStoresSet.add(dataStoreId);\n\t\t}\n\n\t\t// Update the used routes in each data store. Used routes is empty for unused data stores.\n\t\tfor (const [contextId, context] of this.contexts) {\n\t\t\tcontext.setTombstone(tombstonedDataStoresSet.has(contextId));\n\t\t}\n\t}\n\n\t/**\n\t * Returns the outbound routes of this channel. Only root data stores are considered referenced and their paths are\n\t * part of outbound routes.\n\t */\n\tprivate async getOutboundRoutes(): Promise<string[]> {\n\t\tconst outboundRoutes: string[] = [];\n\t\tfor (const [contextId, context] of this.contexts) {\n\t\t\tconst isRootDataStore = await context.isRoot();\n\t\t\tif (isRootDataStore) {\n\t\t\t\toutboundRoutes.push(`/${contextId}`);\n\t\t\t}\n\t\t}\n\t\treturn outboundRoutes;\n\t}\n\n\t/**\n\t * Called by GC to retrieve the package path of a data store node with the given path.\n\t */\n\tpublic async getDataStorePackagePath(nodePath: string): Promise<readonly string[] | undefined> {\n\t\t// If the node belongs to a data store, return its package path. For DDSes, we return the package path of the\n\t\t// data store that contains it.\n\t\tconst context = this.contexts.get(nodePath.split(\"/\")[1]);\n\t\treturn (await context?.getInitialSnapshotDetails())?.pkg;\n\t}\n\n\t/**\n\t * Called by GC to determine if a node is for a data store or for an object within a data store (for e.g. DDS).\n\t * @returns the GC node type if the node belongs to a data store or object within data store, undefined otherwise.\n\t */\n\tpublic getGCNodeType(nodePath: string): GCNodeType | undefined {\n\t\tconst pathParts = nodePath.split(\"/\");\n\t\tif (!this.contexts.has(pathParts[1])) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Data stores paths are of the format \"/dataStoreId\".\n\t\t// Sub data store paths are of the format \"/dataStoreId/subPath/...\".\n\t\tif (pathParts.length === 2) {\n\t\t\treturn GCNodeType.DataStore;\n\t\t}\n\t\treturn GCNodeType.SubDataStore;\n\t}\n}\n\nexport function getSummaryForDatastores(\n\tsnapshot: ISnapshotTree | undefined,\n\tmetadata?: IContainerRuntimeMetadata,\n): ISnapshotTree | undefined {\n\tif (!snapshot) {\n\t\treturn undefined;\n\t}\n\n\tif (rootHasIsolatedChannels(metadata)) {\n\t\tconst datastoresSnapshot = snapshot.trees[channelsTreeName];\n\t\tassert(!!datastoresSnapshot, 0x168 /* Expected tree in snapshot not found */);\n\t\treturn datastoresSnapshot;\n\t} else {\n\t\t// back-compat: strip out all non-datastore paths before giving to DataStores object.\n\t\tconst datastoresTrees: ISnapshotTree[\"trees\"] = {};\n\t\tfor (const [key, value] of Object.entries(snapshot.trees)) {\n\t\t\tif (!nonDataStorePaths.includes(key)) {\n\t\t\t\tdatastoresTrees[key] = value;\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\t...snapshot,\n\t\t\ttrees: datastoresTrees,\n\t\t};\n\t}\n}\n"]}
1
+ {"version":3,"file":"dataStores.js","sourceRoot":"","sources":["../src/dataStores.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tDataCorruptionError,\n\textractSafePropertiesFromMessage,\n} from \"@fluidframework/container-utils\";\nimport {\n\tITelemetryBaseLogger,\n\tIDisposable,\n\tIFluidHandle,\n\tIRequest,\n} from \"@fluidframework/core-interfaces\";\nimport { FluidObjectHandle } from \"@fluidframework/datastore\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tAliasResult,\n\tchannelsTreeName,\n\tCreateChildSummarizerNodeFn,\n\tCreateChildSummarizerNodeParam,\n\tCreateSummarizerNodeSource,\n\tIAttachMessage,\n\tIEnvelope,\n\tIFluidDataStoreContextDetached,\n\tIGarbageCollectionData,\n\tIInboundSignalMessage,\n\tInboundAttachMessage,\n\tISummarizeResult,\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n\tconvertSnapshotTreeToSummaryTree,\n\tconvertToSummaryTree,\n\tcreate404Response,\n\tcreateResponseError,\n\tGCDataBuilder,\n\tresponseToException,\n\tSummaryTreeBuilder,\n\tunpackChildNodesUsedRoutes,\n} from \"@fluidframework/runtime-utils\";\nimport {\n\tLoggingError,\n\tMonitoringContext,\n\tcreateChildMonitoringContext,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { buildSnapshotTree } from \"@fluidframework/driver-utils\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { Lazy } from \"@fluidframework/core-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport { DataStoreContexts } from \"./dataStoreContexts\";\nimport {\n\tContainerRuntime,\n\tdefaultRuntimeHeaderData,\n\tRuntimeHeaderData,\n\tTombstoneResponseHeaderKey,\n} from \"./containerRuntime\";\nimport {\n\tFluidDataStoreContext,\n\tRemoteFluidDataStoreContext,\n\tLocalFluidDataStoreContext,\n\tcreateAttributesBlob,\n\tLocalDetachedFluidDataStoreContext,\n} from \"./dataStoreContext\";\nimport { StorageServiceWithAttachBlobs } from \"./storageServiceWithAttachBlobs\";\nimport { IDataStoreAliasMessage, isDataStoreAliasMessage } from \"./dataStore\";\nimport {\n\tGCNodeType,\n\tsweepDatastoresKey,\n\tthrowOnTombstoneLoadKey,\n\tsendGCUnexpectedUsageEvent,\n} from \"./gc\";\nimport {\n\tsummarizerClientType,\n\tIContainerRuntimeMetadata,\n\tnonDataStorePaths,\n\trootHasIsolatedChannels,\n} from \"./summary\";\n\ntype PendingAliasResolve = (success: boolean) => void;\n\n/**\n * This class encapsulates data store handling. Currently it is only used by the container runtime,\n * but eventually could be hosted on any channel once we formalize the channel api boundary.\n */\nexport class DataStores implements IDisposable {\n\t// Stores tracked by the Domain\n\tprivate readonly pendingAttach = new Map<string, IAttachMessage>();\n\t// 0.24 back-compat attachingBeforeSummary\n\tpublic readonly attachOpFiredForDataStore = new Set<string>();\n\n\tprivate readonly mc: MonitoringContext;\n\n\tprivate readonly disposeOnce = new Lazy<void>(() => this.contexts.dispose());\n\n\tpublic readonly containerLoadStats: {\n\t\t// number of dataStores during loadContainer\n\t\treadonly containerLoadDataStoreCount: number;\n\t\t// number of unreferenced dataStores during loadContainer\n\t\treadonly referencedDataStoreCount: number;\n\t};\n\n\t// Stores the ids of new data stores between two GC runs. This is used to notify the garbage collector of new\n\t// root data stores that are added.\n\tprivate dataStoresSinceLastGC: string[] = [];\n\t/** If true, throw an error when a tombstone data store is retrieved. */\n\tprivate readonly throwOnTombstoneLoad: boolean;\n\t// The handle to the container runtime. This is used mainly for GC purposes to represent outbound reference from\n\t// the container runtime to other nodes.\n\tprivate readonly containerRuntimeHandle: IFluidHandle;\n\tprivate readonly pendingAliasMap: Map<string, Promise<AliasResult>> = new Map<\n\t\tstring,\n\t\tPromise<AliasResult>\n\t>();\n\n\tconstructor(\n\t\tprivate readonly baseSnapshot: ISnapshotTree | undefined,\n\t\tprivate readonly runtime: ContainerRuntime,\n\t\tprivate readonly submitAttachFn: (attachContent: IAttachMessage) => void,\n\t\tprivate readonly getCreateChildSummarizerNodeFn: (\n\t\t\tid: string,\n\t\t\tcreateParam: CreateChildSummarizerNodeParam,\n\t\t) => CreateChildSummarizerNodeFn,\n\t\tprivate readonly deleteChildSummarizerNodeFn: (id: string) => void,\n\t\tbaseLogger: ITelemetryBaseLogger,\n\t\tprivate readonly gcNodeUpdated: (\n\t\t\tnodePath: string,\n\t\t\ttimestampMs: number,\n\t\t\tpackagePath?: readonly string[],\n\t\t) => void,\n\t\tprivate readonly isDataStoreDeleted: (nodePath: string) => boolean,\n\t\tprivate readonly aliasMap: Map<string, string>,\n\t\tprivate readonly contexts: DataStoreContexts = new DataStoreContexts(baseLogger),\n\t) {\n\t\tthis.mc = createChildMonitoringContext({ logger: baseLogger });\n\t\tthis.containerRuntimeHandle = new FluidObjectHandle(\n\t\t\tthis.runtime,\n\t\t\t\"/\",\n\t\t\tthis.runtime.IFluidHandleContext,\n\t\t);\n\n\t\t// Tombstone should only throw when the feature flag is enabled and the client isn't a summarizer\n\t\tthis.throwOnTombstoneLoad =\n\t\t\tthis.mc.config.getBoolean(throwOnTombstoneLoadKey) === true &&\n\t\t\tthis.runtime.gcTombstoneEnforcementAllowed &&\n\t\t\tthis.runtime.clientDetails.type !== summarizerClientType;\n\n\t\t// Extract stores stored inside the snapshot\n\t\tconst fluidDataStores = new Map<string, ISnapshotTree>();\n\t\tif (baseSnapshot) {\n\t\t\tfor (const [key, value] of Object.entries(baseSnapshot.trees)) {\n\t\t\t\tfluidDataStores.set(key, value);\n\t\t\t}\n\t\t}\n\n\t\tlet unreferencedDataStoreCount = 0;\n\t\t// Create a context for each of them\n\t\tfor (const [key, value] of fluidDataStores) {\n\t\t\tlet dataStoreContext: FluidDataStoreContext;\n\n\t\t\t// counting number of unreferenced data stores\n\t\t\tif (value.unreferenced) {\n\t\t\t\tunreferencedDataStoreCount++;\n\t\t\t}\n\t\t\t// If we have a detached container, then create local data store contexts.\n\t\t\tif (this.runtime.attachState !== AttachState.Detached) {\n\t\t\t\tdataStoreContext = new RemoteFluidDataStoreContext({\n\t\t\t\t\tid: key,\n\t\t\t\t\tsnapshotTree: value,\n\t\t\t\t\truntime: this.runtime,\n\t\t\t\t\tstorage: this.runtime.storage,\n\t\t\t\t\tscope: this.runtime.scope,\n\t\t\t\t\tcreateSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(key, {\n\t\t\t\t\t\ttype: CreateSummarizerNodeSource.FromSummary,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tif (typeof value !== \"object\") {\n\t\t\t\t\tthrow new LoggingError(\"Snapshot should be there to load from!!\");\n\t\t\t\t}\n\t\t\t\tconst snapshotTree = value;\n\t\t\t\tdataStoreContext = new LocalFluidDataStoreContext({\n\t\t\t\t\tid: key,\n\t\t\t\t\tpkg: undefined,\n\t\t\t\t\truntime: this.runtime,\n\t\t\t\t\tstorage: this.runtime.storage,\n\t\t\t\t\tscope: this.runtime.scope,\n\t\t\t\t\tcreateSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(key, {\n\t\t\t\t\t\ttype: CreateSummarizerNodeSource.FromSummary,\n\t\t\t\t\t}),\n\t\t\t\t\tmakeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(key),\n\t\t\t\t\tsnapshotTree,\n\t\t\t\t\tisRootDataStore: undefined,\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.contexts.addBoundOrRemoted(dataStoreContext);\n\t\t}\n\t\tthis.containerLoadStats = {\n\t\t\tcontainerLoadDataStoreCount: fluidDataStores.size,\n\t\t\treferencedDataStoreCount: fluidDataStores.size - unreferencedDataStoreCount,\n\t\t};\n\t}\n\n\tpublic get aliases(): ReadonlyMap<string, string> {\n\t\treturn this.aliasMap;\n\t}\n\n\tpublic get pendingAliases(): Map<string, Promise<AliasResult>> {\n\t\treturn this.pendingAliasMap;\n\t}\n\n\tpublic async waitIfPendingAlias(maybeAlias: string): Promise<AliasResult> {\n\t\tconst pendingAliasPromise = this.pendingAliases.get(maybeAlias);\n\t\treturn pendingAliasPromise === undefined ? \"Success\" : pendingAliasPromise;\n\t}\n\n\tpublic processAttachMessage(message: ISequencedDocumentMessage, local: boolean) {\n\t\tconst attachMessage = message.contents as InboundAttachMessage;\n\n\t\tthis.dataStoresSinceLastGC.push(attachMessage.id);\n\n\t\t// The local object has already been attached\n\t\tif (local) {\n\t\t\tassert(\n\t\t\t\tthis.pendingAttach.has(attachMessage.id),\n\t\t\t\t0x15e /* \"Local object does not have matching attach message id\" */,\n\t\t\t);\n\t\t\tthis.contexts.get(attachMessage.id)?.emit(\"attached\");\n\t\t\tthis.pendingAttach.delete(attachMessage.id);\n\t\t\treturn;\n\t\t}\n\n\t\t// If a non-local operation then go and create the object, otherwise mark it as officially attached.\n\t\tif (this.alreadyProcessed(attachMessage.id)) {\n\t\t\t// TODO: dataStoreId may require a different tag from PackageData #7488\n\t\t\tconst error = new DataCorruptionError(\n\t\t\t\t// pre-0.58 error message: duplicateDataStoreCreatedWithExistingId\n\t\t\t\t\"Duplicate DataStore created with existing id\",\n\t\t\t\t{\n\t\t\t\t\t...extractSafePropertiesFromMessage(message),\n\t\t\t\t\t...tagCodeArtifacts({ dataStoreId: attachMessage.id }),\n\t\t\t\t},\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\n\t\tconst flatAttachBlobs = new Map<string, ArrayBufferLike>();\n\t\tlet snapshotTree: ISnapshotTree | undefined;\n\t\tif (attachMessage.snapshot) {\n\t\t\tsnapshotTree = buildSnapshotTree(attachMessage.snapshot.entries, flatAttachBlobs);\n\t\t}\n\n\t\t// Include the type of attach message which is the pkg of the store to be\n\t\t// used by RemoteFluidDataStoreContext in case it is not in the snapshot.\n\t\tconst pkg = [attachMessage.type];\n\t\tconst remoteFluidDataStoreContext = new RemoteFluidDataStoreContext({\n\t\t\tid: attachMessage.id,\n\t\t\tsnapshotTree,\n\t\t\truntime: this.runtime,\n\t\t\tstorage: new StorageServiceWithAttachBlobs(this.runtime.storage, flatAttachBlobs),\n\t\t\tscope: this.runtime.scope,\n\t\t\tcreateSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(attachMessage.id, {\n\t\t\t\ttype: CreateSummarizerNodeSource.FromAttach,\n\t\t\t\tsequenceNumber: message.sequenceNumber,\n\t\t\t\tsnapshot: attachMessage.snapshot ?? {\n\t\t\t\t\tentries: [createAttributesBlob(pkg, true /* isRootDataStore */)],\n\t\t\t\t},\n\t\t\t}),\n\t\t\tpkg,\n\t\t});\n\n\t\tthis.contexts.addBoundOrRemoted(remoteFluidDataStoreContext);\n\t}\n\n\tpublic processAliasMessage(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocalOpMetadata: unknown,\n\t\tlocal: boolean,\n\t): void {\n\t\tconst aliasMessage = message.contents as IDataStoreAliasMessage;\n\t\tif (!isDataStoreAliasMessage(aliasMessage)) {\n\t\t\tthrow new DataCorruptionError(\"malformedDataStoreAliasMessage\", {\n\t\t\t\t...extractSafePropertiesFromMessage(message),\n\t\t\t});\n\t\t}\n\n\t\tconst resolve = localOpMetadata as PendingAliasResolve;\n\t\tconst aliasResult = this.processAliasMessageCore(aliasMessage);\n\t\tif (local) {\n\t\t\tresolve(aliasResult);\n\t\t}\n\t}\n\n\tpublic processAliasMessageCore(aliasMessage: IDataStoreAliasMessage): boolean {\n\t\tif (this.alreadyProcessed(aliasMessage.alias)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst context = this.contexts.get(aliasMessage.internalId);\n\t\tif (context === undefined) {\n\t\t\tthis.mc.logger.sendErrorEvent({\n\t\t\t\teventName: \"AliasFluidDataStoreNotFound\",\n\t\t\t\tfluidDataStoreId: aliasMessage.internalId,\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\tconst handle = new FluidObjectHandle(\n\t\t\tcontext,\n\t\t\taliasMessage.internalId,\n\t\t\tthis.runtime.IFluidHandleContext,\n\t\t);\n\t\tthis.runtime.addedGCOutboundReference(this.containerRuntimeHandle, handle);\n\n\t\tthis.aliasMap.set(aliasMessage.alias, context.id);\n\t\tcontext.setInMemoryRoot();\n\t\treturn true;\n\t}\n\n\tprivate alreadyProcessed(id: string): boolean {\n\t\treturn this.aliasMap.get(id) !== undefined || this.contexts.get(id) !== undefined;\n\t}\n\n\t/**\n\t * Make the data stores locally visible in the container graph by moving the data store context from unbound to\n\t * bound list. This data store can now be reached from the root.\n\t * @param id - The id of the data store context to make visible.\n\t */\n\tprivate makeDataStoreLocallyVisible(id: string): void {\n\t\tconst localContext = this.contexts.getUnbound(id);\n\t\tassert(!!localContext, 0x15f /* \"Could not find unbound context to bind\" */);\n\n\t\t/**\n\t\t * If the container is not detached, it is globally visible to all clients. This data store should also be\n\t\t * globally visible. Move it to attaching state and send an \"attach\" op for it.\n\t\t * If the container is detached, this data store will be part of the summary that makes the container attached.\n\t\t */\n\t\tif (this.runtime.attachState !== AttachState.Detached) {\n\t\t\tlocalContext.emit(\"attaching\");\n\t\t\tconst message = localContext.generateAttachMessage();\n\n\t\t\tthis.pendingAttach.set(id, message);\n\t\t\tthis.submitAttachFn(message);\n\t\t\tthis.attachOpFiredForDataStore.add(id);\n\t\t}\n\n\t\tthis.contexts.bind(id);\n\t}\n\n\tpublic createDetachedDataStoreCore(\n\t\tpkg: Readonly<string[]>,\n\t\tisRoot: boolean,\n\t\tid = uuid(),\n\t): IFluidDataStoreContextDetached {\n\t\tassert(!id.includes(\"/\"), 0x30c /* Id cannot contain slashes */);\n\n\t\tconst context = new LocalDetachedFluidDataStoreContext({\n\t\t\tid,\n\t\t\tpkg,\n\t\t\truntime: this.runtime,\n\t\t\tstorage: this.runtime.storage,\n\t\t\tscope: this.runtime.scope,\n\t\t\tcreateSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(id, {\n\t\t\t\ttype: CreateSummarizerNodeSource.Local,\n\t\t\t}),\n\t\t\tmakeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(id),\n\t\t\tsnapshotTree: undefined,\n\t\t\tisRootDataStore: isRoot,\n\t\t});\n\t\tthis.contexts.addUnbound(context);\n\t\treturn context;\n\t}\n\n\tpublic _createFluidDataStoreContext(pkg: string[], id: string, props?: any) {\n\t\tassert(!id.includes(\"/\"), 0x30d /* Id cannot contain slashes */);\n\t\tconst context = new LocalFluidDataStoreContext({\n\t\t\tid,\n\t\t\tpkg,\n\t\t\truntime: this.runtime,\n\t\t\tstorage: this.runtime.storage,\n\t\t\tscope: this.runtime.scope,\n\t\t\tcreateSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(id, {\n\t\t\t\ttype: CreateSummarizerNodeSource.Local,\n\t\t\t}),\n\t\t\tmakeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(id),\n\t\t\tsnapshotTree: undefined,\n\t\t\tisRootDataStore: false,\n\t\t\tcreateProps: props,\n\t\t});\n\t\tthis.contexts.addUnbound(context);\n\t\treturn context;\n\t}\n\n\tpublic get disposed() {\n\t\treturn this.disposeOnce.evaluated;\n\t}\n\tpublic readonly dispose = () => this.disposeOnce.value;\n\n\tpublic resubmitDataStoreOp(envelope: IEnvelope, localOpMetadata: unknown) {\n\t\tconst context = this.contexts.get(envelope.address);\n\t\tassert(!!context, 0x160 /* \"There should be a store context for the op\" */);\n\t\tcontext.reSubmit(envelope.contents, localOpMetadata);\n\t}\n\n\tpublic rollbackDataStoreOp(envelope: IEnvelope, localOpMetadata: unknown) {\n\t\tconst context = this.contexts.get(envelope.address);\n\t\tassert(!!context, 0x2e8 /* \"There should be a store context for the op\" */);\n\t\tcontext.rollback(envelope.contents, localOpMetadata);\n\t}\n\n\tpublic async applyStashedOp(envelope: IEnvelope): Promise<unknown> {\n\t\tconst context = this.contexts.get(envelope.address);\n\t\tassert(!!context, 0x161 /* \"There should be a store context for the op\" */);\n\t\treturn context.applyStashedOp(envelope.contents);\n\t}\n\n\tpublic async applyStashedAttachOp(message: IAttachMessage) {\n\t\tthis.pendingAttach.set(message.id, message);\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\tthis.processAttachMessage({ contents: message } as ISequencedDocumentMessage, false);\n\t}\n\n\tpublic processFluidDataStoreOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalMessageMetadata: unknown,\n\t) {\n\t\tconst envelope = message.contents as IEnvelope;\n\t\tconst transformed = { ...message, contents: envelope.contents };\n\t\tthis.validateNotDeleted(envelope.address);\n\t\tconst context = this.contexts.get(envelope.address);\n\t\tassert(!!context, 0x162 /* \"There should be a store context for the op\" */);\n\t\tcontext.process(transformed, local, localMessageMetadata);\n\n\t\t// Notify that a GC node for the data store changed. This is used to detect if a deleted data store is\n\t\t// being used.\n\t\tthis.gcNodeUpdated(\n\t\t\t`/${envelope.address}`,\n\t\t\tmessage.timestamp,\n\t\t\tcontext.isLoaded ? context.packagePath : undefined,\n\t\t);\n\t}\n\n\tpublic async getDataStore(\n\t\tid: string,\n\t\trequestHeaderData: RuntimeHeaderData,\n\t): Promise<FluidDataStoreContext> {\n\t\tconst headerData = { ...defaultRuntimeHeaderData, ...requestHeaderData };\n\t\tthis.validateNotDeleted(id, headerData);\n\n\t\tconst context = await this.contexts.getBoundOrRemoted(id, headerData.wait);\n\t\tif (context === undefined) {\n\t\t\t// The requested data store does not exits. Throw a 404 response exception.\n\t\t\tconst request: IRequest = { url: id };\n\t\t\tthrow responseToException(create404Response(request), request);\n\t\t}\n\n\t\tthis.validateNotTombstoned(context, requestHeaderData);\n\n\t\treturn context;\n\t}\n\n\t/**\n\t * Returns the data store requested with the given id if available. Otherwise, returns undefined.\n\t */\n\tpublic async getDataStoreIfAvailable(\n\t\tid: string,\n\t\trequestHeaderData: RuntimeHeaderData,\n\t): Promise<FluidDataStoreContext | undefined> {\n\t\t// If the data store has been deleted, return undefined.\n\t\tif (this.checkIfDeleted(id, requestHeaderData)) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst headerData = { ...defaultRuntimeHeaderData, ...requestHeaderData };\n\t\tconst context = await this.contexts.getBoundOrRemoted(id, headerData.wait);\n\t\tif (context === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\t// Check if the data store is tombstoned. If so, we want to log a telemetry event.\n\t\tthis.checkIfTombstoned(context, requestHeaderData);\n\t\treturn context;\n\t}\n\n\t/**\n\t * Checks if the data store has been deleted by GC.\n\t * @param id - data store id\n\t * @param request - the request information to log if the validation detects the data store has been deleted\n\t * @param requestHeaderData - the request header information to log if the validation detects the data store has been deleted\n\t * @returns true if the data store is deleted. Otherwise, returns false.\n\t */\n\tprivate checkIfDeleted(id: string, requestHeaderData?: RuntimeHeaderData) {\n\t\tconst dataStoreNodePath = `/${id}`;\n\t\tif (!this.isDataStoreDeleted(dataStoreNodePath)) {\n\t\t\treturn false;\n\t\t}\n\t\tassert(\n\t\t\t!this.contexts.has(id),\n\t\t\t0x570 /* Inconsistent state! GC says the data store is deleted, but the data store is not deleted from the runtime. */,\n\t\t);\n\t\tsendGCUnexpectedUsageEvent(\n\t\t\tthis.mc,\n\t\t\t{\n\t\t\t\teventName: \"GC_Deleted_DataStore_Requested\",\n\t\t\t\tcategory: \"error\",\n\t\t\t\tisSummarizerClient: this.runtime.clientDetails.type === summarizerClientType,\n\t\t\t\tid,\n\t\t\t\theaders: JSON.stringify(requestHeaderData),\n\t\t\t\tgcTombstoneEnforcementAllowed: this.runtime.gcTombstoneEnforcementAllowed,\n\t\t\t},\n\t\t\tundefined /* packagePath */,\n\t\t);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Validate that the data store had not been deleted by GC.\n\t * @param id - data store id\n\t * @param requestHeaderData - the request header information to log if the validation detects the data store has been deleted\n\t */\n\tprivate validateNotDeleted(id: string, requestHeaderData?: RuntimeHeaderData) {\n\t\tif (this.checkIfDeleted(id, requestHeaderData)) {\n\t\t\t// The requested data store is removed by gc. Create a 404 gc response exception.\n\t\t\tconst request: IRequest = { url: id };\n\t\t\tthrow responseToException(\n\t\t\t\tcreateResponseError(404, \"DataStore was deleted\", request),\n\t\t\t\trequest,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Checks if the data store has not been marked as tombstone by GC or not.\n\t * @param context - the data store context in question\n\t * @param requestHeaderData - the request header information to log if the validation detects the data store has been tombstoned\n\t * @returns true if the data store is tombstoned. Otherwise, returns false.\n\t */\n\tprivate checkIfTombstoned(\n\t\tcontext: FluidDataStoreContext,\n\t\trequestHeaderData: RuntimeHeaderData,\n\t) {\n\t\tif (!context.tombstoned) {\n\t\t\treturn false;\n\t\t}\n\t\tconst logErrorEvent = this.throwOnTombstoneLoad && !requestHeaderData.allowTombstone;\n\t\tsendGCUnexpectedUsageEvent(\n\t\t\tthis.mc,\n\t\t\t{\n\t\t\t\teventName: \"GC_Tombstone_DataStore_Requested\",\n\t\t\t\tcategory: logErrorEvent ? \"error\" : \"generic\",\n\t\t\t\tisSummarizerClient: this.runtime.clientDetails.type === summarizerClientType,\n\t\t\t\tid: context.id,\n\t\t\t\theaders: JSON.stringify(requestHeaderData),\n\t\t\t\tgcTombstoneEnforcementAllowed: this.runtime.gcTombstoneEnforcementAllowed,\n\t\t\t},\n\t\t\tcontext.isLoaded ? context.packagePath : undefined,\n\t\t);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Validates that the data store context requested has not been marked as tombstone by GC.\n\t * @param context - the data store context in question\n\t * @param request - the request information to log if the validation detects the data store has been tombstoned\n\t * @param requestHeaderData - the request header information to log if the validation detects the data store has been tombstoned\n\t */\n\tprivate validateNotTombstoned(\n\t\tcontext: FluidDataStoreContext,\n\t\trequestHeaderData: RuntimeHeaderData,\n\t) {\n\t\tif (this.checkIfTombstoned(context, requestHeaderData)) {\n\t\t\t// The requested data store is removed by gc. Create a 404 gc response exception.\n\t\t\tconst request: IRequest = { url: context.id };\n\t\t\tconst error = responseToException(\n\t\t\t\tcreateResponseError(404, \"DataStore was deleted\", request, {\n\t\t\t\t\t[TombstoneResponseHeaderKey]: true,\n\t\t\t\t}),\n\t\t\t\trequest,\n\t\t\t);\n\t\t\t// Throw an error if configured via options and via request headers.\n\t\t\tif (this.throwOnTombstoneLoad && !requestHeaderData.allowTombstone) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic processSignal(fluidDataStoreId: string, message: IInboundSignalMessage, local: boolean) {\n\t\tthis.validateNotDeleted(fluidDataStoreId);\n\t\tconst context = this.contexts.get(fluidDataStoreId);\n\t\tif (!context) {\n\t\t\t// Attach message may not have been processed yet\n\t\t\tassert(!local, 0x163 /* \"Missing datastore for local signal\" */);\n\t\t\tthis.mc.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"SignalFluidDataStoreNotFound\",\n\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\tfluidDataStoreId,\n\t\t\t\t}),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tcontext.processSignal(message, local);\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\tfor (const [fluidDataStoreId, context] of this.contexts) {\n\t\t\ttry {\n\t\t\t\tcontext.setConnectionState(connected, clientId);\n\t\t\t} catch (error) {\n\t\t\t\tthis.mc.logger.sendErrorEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"SetConnectionStateError\",\n\t\t\t\t\t\tclientId,\n\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\tfluidDataStoreId,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t\truntimeConnected: this.runtime.connected,\n\t\t\t\t\t\t\tconnected,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {\n\t\tconst eventName = attachState === AttachState.Attaching ? \"attaching\" : \"attached\";\n\t\tfor (const [, context] of this.contexts) {\n\t\t\t// Fire only for bounded stores.\n\t\t\tif (!this.contexts.isNotBound(context.id)) {\n\t\t\t\tcontext.emit(eventName);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic get size(): number {\n\t\treturn this.contexts.size;\n\t}\n\n\tpublic async summarize(\n\t\tfullTree: boolean,\n\t\ttrackState: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummaryTreeWithStats> {\n\t\tconst summaryBuilder = new SummaryTreeBuilder();\n\n\t\t// Iterate over each store and ask it to snapshot\n\t\tawait Promise.all(\n\t\t\tArray.from(this.contexts)\n\t\t\t\t.filter(([_, context]) => {\n\t\t\t\t\t// Summarizer works only with clients with no local changes. A data store in attaching\n\t\t\t\t\t// state indicates an op was sent to attach a local data store.\n\t\t\t\t\tassert(\n\t\t\t\t\t\tcontext.attachState !== AttachState.Attaching,\n\t\t\t\t\t\t0x588 /* Local data store detected in attaching state during summarize */,\n\t\t\t\t\t);\n\t\t\t\t\treturn context.attachState === AttachState.Attached;\n\t\t\t\t})\n\t\t\t\t.map(async ([contextId, context]) => {\n\t\t\t\t\tconst contextSummary = await context.summarize(\n\t\t\t\t\t\tfullTree,\n\t\t\t\t\t\ttrackState,\n\t\t\t\t\t\ttelemetryContext,\n\t\t\t\t\t);\n\t\t\t\t\tsummaryBuilder.addWithStats(contextId, contextSummary);\n\t\t\t\t}),\n\t\t);\n\n\t\treturn summaryBuilder.getSummaryTree();\n\t}\n\n\tpublic createSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {\n\t\tconst builder = new SummaryTreeBuilder();\n\t\t// Attaching graph of some stores can cause other stores to get bound too.\n\t\t// So keep taking summary until no new stores get bound.\n\t\tlet notBoundContextsLength: number;\n\t\tdo {\n\t\t\tconst builderTree = builder.summary.tree;\n\t\t\tnotBoundContextsLength = this.contexts.notBoundLength();\n\t\t\t// Iterate over each data store and ask it to snapshot\n\t\t\tArray.from(this.contexts)\n\t\t\t\t.filter(\n\t\t\t\t\t([key, _]) =>\n\t\t\t\t\t\t// Take summary of bounded data stores only, make sure we haven't summarized them already\n\t\t\t\t\t\t// and no attach op has been fired for that data store because for loader versions <= 0.24\n\t\t\t\t\t\t// we set attach state as \"attaching\" before taking createNew summary.\n\t\t\t\t\t\t!(\n\t\t\t\t\t\t\tthis.contexts.isNotBound(key) ||\n\t\t\t\t\t\t\tbuilderTree[key] ||\n\t\t\t\t\t\t\tthis.attachOpFiredForDataStore.has(key)\n\t\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\t.map(([key, value]) => {\n\t\t\t\t\tlet dataStoreSummary: ISummarizeResult;\n\t\t\t\t\tif (value.isLoaded) {\n\t\t\t\t\t\tconst snapshot = value.generateAttachMessage().snapshot;\n\t\t\t\t\t\tdataStoreSummary = convertToSummaryTree(snapshot, true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If this data store is not yet loaded, then there should be no changes in the snapshot from\n\t\t\t\t\t\t// which it was created as it is detached container. So just use the previous snapshot.\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\t!!this.baseSnapshot,\n\t\t\t\t\t\t\t0x166 /* \"BaseSnapshot should be there as detached container loaded from snapshot\" */,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tdataStoreSummary = convertSnapshotTreeToSummaryTree(\n\t\t\t\t\t\t\tthis.baseSnapshot.trees[key],\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tbuilder.addWithStats(key, dataStoreSummary);\n\t\t\t\t});\n\t\t} while (notBoundContextsLength !== this.contexts.notBoundLength());\n\n\t\treturn builder.getSummaryTree();\n\t}\n\n\t/**\n\t * Before GC runs, called by the garbage collector to update any pending GC state.\n\t * The garbage collector needs to know all outbound references that are added. Since root data stores are not\n\t * explicitly marked as referenced, notify GC of new root data stores that were added since the last GC run.\n\t */\n\tpublic async updateStateBeforeGC(): Promise<void> {\n\t\tfor (const id of this.dataStoresSinceLastGC) {\n\t\t\tconst context = this.contexts.get(id);\n\t\t\tassert(context !== undefined, 0x2b6 /* Missing data store context */);\n\t\t\tif (await context.isRoot()) {\n\t\t\t\t// A root data store is basically a reference from the container runtime to the data store.\n\t\t\t\tconst handle = new FluidObjectHandle(context, id, this.runtime.IFluidHandleContext);\n\t\t\t\tthis.runtime.addedGCOutboundReference(this.containerRuntimeHandle, handle);\n\t\t\t}\n\t\t}\n\t\tthis.dataStoresSinceLastGC = [];\n\t}\n\n\t/**\n\t * Generates data used for garbage collection. It does the following:\n\t *\n\t * 1. Calls into each child data store context to get its GC data.\n\t *\n\t * 2. Prefixes the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be\n\t * identified as belonging to the child.\n\t *\n\t * 3. Adds a GC node for this channel to the nodes received from the children. All these nodes together represent\n\t * the GC data of this channel.\n\t *\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tconst builder = new GCDataBuilder();\n\t\t// Iterate over each store and get their GC data.\n\t\tawait Promise.all(\n\t\t\tArray.from(this.contexts)\n\t\t\t\t.filter(([_, context]) => {\n\t\t\t\t\t// Summarizer client and hence GC works only with clients with no local changes. A data store in\n\t\t\t\t\t// attaching state indicates an op was sent to attach a local data store.\n\t\t\t\t\tassert(\n\t\t\t\t\t\tcontext.attachState !== AttachState.Attaching,\n\t\t\t\t\t\t0x589 /* Local data store detected in attaching state while running GC */,\n\t\t\t\t\t);\n\t\t\t\t\treturn context.attachState === AttachState.Attached;\n\t\t\t\t})\n\t\t\t\t.map(async ([contextId, context]) => {\n\t\t\t\t\tconst contextGCData = await context.getGCData(fullGC);\n\t\t\t\t\t// Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.\n\t\t\t\t\t// This also gradually builds the id of each node to be a path from the root.\n\t\t\t\t\tbuilder.prefixAndAddNodes(contextId, contextGCData.gcNodes);\n\t\t\t\t}),\n\t\t);\n\n\t\t// Get the outbound routes and add a GC node for this channel.\n\t\tbuilder.addNode(\"/\", await this.getOutboundRoutes());\n\t\treturn builder.getGCData();\n\t}\n\n\t/**\n\t * After GC has run, called to notify this Container's data stores of routes that are used in it.\n\t * @param usedRoutes - The routes that are used in all data stores in this Container.\n\t */\n\tpublic updateUsedRoutes(usedRoutes: string[]) {\n\t\t// Get a map of data store ids to routes used in it.\n\t\tconst usedDataStoreRoutes = unpackChildNodesUsedRoutes(usedRoutes);\n\n\t\t// Verify that the used routes are correct.\n\t\tfor (const [id] of usedDataStoreRoutes) {\n\t\t\tassert(\n\t\t\t\tthis.contexts.has(id),\n\t\t\t\t0x167 /* \"Used route does not belong to any known data store\" */,\n\t\t\t);\n\t\t}\n\n\t\t// Update the used routes in each data store. Used routes is empty for unused data stores.\n\t\tfor (const [contextId, context] of this.contexts) {\n\t\t\tcontext.updateUsedRoutes(usedDataStoreRoutes.get(contextId) ?? []);\n\t\t}\n\t}\n\n\t/**\n\t * This is called to update objects whose routes are unused. The unused objects are deleted.\n\t * @param unusedRoutes - The routes that are unused in all data stores in this Container.\n\t */\n\tpublic updateUnusedRoutes(unusedRoutes: string[]) {\n\t\tfor (const route of unusedRoutes) {\n\t\t\tconst pathParts = route.split(\"/\");\n\t\t\t// Delete data store only if its route (/datastoreId) is in unusedRoutes. We don't want to delete a data\n\t\t\t// store based on its DDS being unused.\n\t\t\tif (pathParts.length > 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst dataStoreId = pathParts[1];\n\t\t\tassert(this.contexts.has(dataStoreId), 0x2d7 /* No data store with specified id */);\n\t\t\t// Delete the contexts of unused data stores.\n\t\t\tthis.contexts.delete(dataStoreId);\n\t\t\t// Delete the summarizer node of the unused data stores.\n\t\t\tthis.deleteChildSummarizerNodeFn(dataStoreId);\n\t\t}\n\t}\n\n\t/**\n\t * Delete data stores and its objects that are sweep ready.\n\t * @param sweepReadyDataStoreRoutes - The routes of data stores and its objects that are sweep ready and should\n\t * be deleted.\n\t * @returns - The routes of data stores and its objects that were deleted.\n\t */\n\tpublic deleteSweepReadyNodes(sweepReadyDataStoreRoutes: string[]): string[] {\n\t\t// If sweep for data stores is not enabled, return empty list indicating nothing is deleted.\n\t\tif (this.mc.config.getBoolean(sweepDatastoresKey) !== true) {\n\t\t\treturn [];\n\t\t}\n\t\tfor (const route of sweepReadyDataStoreRoutes) {\n\t\t\tconst pathParts = route.split(\"/\");\n\t\t\tconst dataStoreId = pathParts[1];\n\n\t\t\t// TODO: GC:Validation - Skip any routes already deleted\n\t\t\t// Ignore sub-data store routes because a data store and its sub-routes are deleted together, so, we only\n\t\t\t// need to delete the data store.\n\t\t\tif (pathParts.length > 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!this.contexts.has(dataStoreId)) {\n\t\t\t\tthis.mc.logger.sendErrorEvent({\n\t\t\t\t\teventName: \"DeletedDataStoreNotFound\",\n\t\t\t\t\tdataStoreId,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst dataStore = this.contexts.get(dataStoreId);\n\t\t\tassert(dataStore !== undefined, 0x571 /* Attempting to delete unknown dataStore */);\n\t\t\tdataStore.delete();\n\n\t\t\t// Delete the contexts of sweep ready data stores.\n\t\t\tthis.contexts.delete(dataStoreId);\n\t\t\t// Delete the summarizer node of the sweep ready data stores.\n\t\t\tthis.deleteChildSummarizerNodeFn(dataStoreId);\n\t\t}\n\t\treturn Array.from(sweepReadyDataStoreRoutes);\n\t}\n\n\t/**\n\t * This is called to update objects whose routes are tombstones. Tombstoned datastore contexts enable testing\n\t * scenarios with accessing deleted content without actually deleting content from summaries.\n\t * @param tombstonedRoutes - The routes that are tombstones in all data stores in this Container.\n\t */\n\tpublic updateTombstonedRoutes(tombstonedRoutes: string[]) {\n\t\tconst tombstonedDataStoresSet: Set<string> = new Set();\n\t\tfor (const route of tombstonedRoutes) {\n\t\t\tconst pathParts = route.split(\"/\");\n\t\t\t// Tombstone data store only if its route (/datastoreId) is directly in tombstoneRoutes.\n\t\t\tif (pathParts.length > 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst dataStoreId = pathParts[1];\n\t\t\tassert(this.contexts.has(dataStoreId), 0x510 /* No data store with specified id */);\n\t\t\ttombstonedDataStoresSet.add(dataStoreId);\n\t\t}\n\n\t\t// Update the used routes in each data store. Used routes is empty for unused data stores.\n\t\tfor (const [contextId, context] of this.contexts) {\n\t\t\tcontext.setTombstone(tombstonedDataStoresSet.has(contextId));\n\t\t}\n\t}\n\n\t/**\n\t * Returns the outbound routes of this channel. Only root data stores are considered referenced and their paths are\n\t * part of outbound routes.\n\t */\n\tprivate async getOutboundRoutes(): Promise<string[]> {\n\t\tconst outboundRoutes: string[] = [];\n\t\tfor (const [contextId, context] of this.contexts) {\n\t\t\tconst isRootDataStore = await context.isRoot();\n\t\t\tif (isRootDataStore) {\n\t\t\t\toutboundRoutes.push(`/${contextId}`);\n\t\t\t}\n\t\t}\n\t\treturn outboundRoutes;\n\t}\n\n\t/**\n\t * Called by GC to retrieve the package path of a data store node with the given path.\n\t */\n\tpublic async getDataStorePackagePath(nodePath: string): Promise<readonly string[] | undefined> {\n\t\t// If the node belongs to a data store, return its package path. For DDSes, we return the package path of the\n\t\t// data store that contains it.\n\t\tconst context = this.contexts.get(nodePath.split(\"/\")[1]);\n\t\treturn (await context?.getInitialSnapshotDetails())?.pkg;\n\t}\n\n\t/**\n\t * Called by GC to determine if a node is for a data store or for an object within a data store (for e.g. DDS).\n\t * @returns the GC node type if the node belongs to a data store or object within data store, undefined otherwise.\n\t */\n\tpublic getGCNodeType(nodePath: string): GCNodeType | undefined {\n\t\tconst pathParts = nodePath.split(\"/\");\n\t\tif (!this.contexts.has(pathParts[1])) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Data stores paths are of the format \"/dataStoreId\".\n\t\t// Sub data store paths are of the format \"/dataStoreId/subPath/...\".\n\t\tif (pathParts.length === 2) {\n\t\t\treturn GCNodeType.DataStore;\n\t\t}\n\t\treturn GCNodeType.SubDataStore;\n\t}\n}\n\nexport function getSummaryForDatastores(\n\tsnapshot: ISnapshotTree | undefined,\n\tmetadata?: IContainerRuntimeMetadata,\n): ISnapshotTree | undefined {\n\tif (!snapshot) {\n\t\treturn undefined;\n\t}\n\n\tif (rootHasIsolatedChannels(metadata)) {\n\t\tconst datastoresSnapshot = snapshot.trees[channelsTreeName];\n\t\tassert(!!datastoresSnapshot, 0x168 /* Expected tree in snapshot not found */);\n\t\treturn datastoresSnapshot;\n\t} else {\n\t\t// back-compat: strip out all non-datastore paths before giving to DataStores object.\n\t\tconst datastoresTrees: ISnapshotTree[\"trees\"] = {};\n\t\tfor (const [key, value] of Object.entries(snapshot.trees)) {\n\t\t\tif (!nonDataStorePaths.includes(key)) {\n\t\t\t\tdatastoresTrees[key] = value;\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\t...snapshot,\n\t\t\ttrees: datastoresTrees,\n\t\t};\n\t}\n}\n"]}
@@ -0,0 +1,35 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { EventForwarder } from "@fluidframework/common-utils";
6
+ import { IDeltaManager, IDeltaManagerEvents, IDeltaQueue, IDeltaSender, ReadOnlyInfo } from "@fluidframework/container-definitions";
7
+ import { IClientConfiguration, IClientDetails, IDocumentMessage, ISequencedDocumentMessage, ISignalMessage } from "@fluidframework/protocol-definitions";
8
+ /**
9
+ * Base class for creating proxy to the real delta manager. It implements all required methods on IDeltaManager and
10
+ * proxy implementations can override specific methods.
11
+ */
12
+ export declare class DeltaManagerProxyBase extends EventForwarder<IDeltaManagerEvents> implements IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {
13
+ protected readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
14
+ get IDeltaSender(): IDeltaSender;
15
+ get inbound(): IDeltaQueue<ISequencedDocumentMessage>;
16
+ get outbound(): IDeltaQueue<IDocumentMessage[]>;
17
+ get inboundSignal(): IDeltaQueue<ISignalMessage>;
18
+ get minimumSequenceNumber(): number;
19
+ get lastSequenceNumber(): number;
20
+ get lastMessage(): ISequencedDocumentMessage | undefined;
21
+ get lastKnownSeqNumber(): number;
22
+ get initialSequenceNumber(): number;
23
+ get hasCheckpointSequenceNumber(): boolean;
24
+ get clientDetails(): IClientDetails;
25
+ get version(): string;
26
+ get maxMessageSize(): number;
27
+ get serviceConfiguration(): IClientConfiguration | undefined;
28
+ get active(): boolean;
29
+ get readOnlyInfo(): ReadOnlyInfo;
30
+ constructor(deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>);
31
+ dispose(): void;
32
+ submitSignal(content: any): void;
33
+ flush(): void;
34
+ }
35
+ //# sourceMappingURL=deltaManagerProxyBase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deltaManagerProxyBase.d.ts","sourceRoot":"","sources":["../src/deltaManagerProxyBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACN,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,MAAM,sCAAsC,CAAC;AAE9C;;;GAGG;AACH,qBAAa,qBACZ,SAAQ,cAAc,CAAC,mBAAmB,CAC1C,YAAW,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC;IAmEpE,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC;IAjE5F,IAAW,YAAY,IAAI,YAAY,CAEtC;IAED,IAAW,OAAO,IAAI,WAAW,CAAC,yBAAyB,CAAC,CAE3D;IAED,IAAW,QAAQ,IAAI,WAAW,CAAC,gBAAgB,EAAE,CAAC,CAErD;IAED,IAAW,aAAa,IAAI,WAAW,CAAC,cAAc,CAAC,CAEtD;IAED,IAAW,qBAAqB,IAAI,MAAM,CAEzC;IAED,IAAW,kBAAkB,IAAI,MAAM,CAEtC;IAED,IAAW,WAAW,0CAErB;IAED,IAAW,kBAAkB,WAE5B;IAED,IAAW,qBAAqB,IAAI,MAAM,CAEzC;IAED,IAAW,2BAA2B,YAErC;IAED,IAAW,aAAa,IAAI,cAAc,CAEzC;IAED,IAAW,OAAO,IAAI,MAAM,CAE3B;IAED,IAAW,cAAc,IAAI,MAAM,CAElC;IAED,IAAW,oBAAoB,IAAI,oBAAoB,GAAG,SAAS,CAElE;IAED,IAAW,MAAM,IAAI,OAAO,CAE3B;IAED,IAAW,YAAY,IAAI,YAAY,CAEtC;gBAGmB,YAAY,EAAE,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC;IAKrF,OAAO,IAAI,IAAI;IAIf,YAAY,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAIhC,KAAK,IAAI,IAAI;CAGpB"}