@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
@@ -1 +1 @@
1
- {"version":3,"file":"gcTelemetry.js","sourceRoot":"","sources":["../../src/gc/gcTelemetry.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 { ITelemetryGenericEvent } from \"@fluidframework/core-interfaces\";\nimport { IGarbageCollectionData } from \"@fluidframework/runtime-definitions\";\nimport { packagePathToTelemetryProperty } from \"@fluidframework/runtime-utils\";\nimport {\n\tgenerateStack,\n\tITelemetryLoggerExt,\n\tMonitoringContext,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils\";\nimport { ICreateContainerMetadata } from \"../summary\";\nimport {\n\tdisableSweepLogKey,\n\tGCNodeType,\n\tUnreferencedState,\n\tIGarbageCollectorConfigs,\n\tdisableTombstoneKey,\n\tthrowOnTombstoneUsageKey,\n\tthrowOnTombstoneLoadKey,\n\trunSweepKey,\n} from \"./gcDefinitions\";\nimport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker\";\nimport { tagAsCodeArtifact } from \"./gcHelpers\";\n\ntype NodeUsageType = \"Changed\" | \"Loaded\" | \"Revived\";\n\n/** Properties that are common to IUnreferencedEventProps and INodeUsageProps */\ninterface ICommonProps {\n\tusageType: NodeUsageType;\n\tcompletedGCRuns: number;\n\tisTombstoned: boolean;\n\tlastSummaryTime?: number;\n\tviaHandle?: boolean;\n}\n\n/** The event that is logged when unreferenced node is used after a certain time. */\ninterface IUnreferencedEventProps extends ICreateContainerMetadata, ICommonProps {\n\tstate: UnreferencedState;\n\tid: {\n\t\tvalue: string;\n\t\ttag: string;\n\t};\n\ttype: GCNodeType;\n\tunrefTime: number;\n\tage: number;\n\ttimeout?: number;\n\tfromId?: {\n\t\tvalue: string;\n\t\ttag: string;\n\t};\n}\n\n/** Properties passed to nodeUsed function when a node is used. */\ninterface INodeUsageProps extends ICommonProps {\n\tid: string;\n\tcurrentReferenceTimestampMs: number | undefined;\n\tpackagePath: readonly string[] | undefined;\n\tfromId?: string;\n}\n\n/**\n * Encapsulates the logic that tracks the various telemetry logged by the Garbage Collector. There are 4 types of\n * telemetry logged:\n * 1. inactiveObject telemetry - When an inactive node is used - A node that has been unreferenced for inactiveTimeoutMs.\n * 2. sweepReadyObject telemetry - When a sweep ready node is used - A node that has been unreferenced for sweepTimeoutMs.\n * 3. Tombstone telemetry - When a tombstoned node is used - A node that that has been marked as tombstone.\n * 4. Sweep / deleted telemetry - When a node is detected as sweep ready in the sweep phase.\n * 5. Unknown outbound reference telemetry - When a node is referenced but GC is not explicitly notified of it.\n */\nexport class GCTelemetryTracker {\n\t// Keeps track of unreferenced events that are logged for a node. This is used to limit the log generation to one\n\t// per event per node.\n\tprivate readonly loggedUnreferencedEvents: Set<string> = new Set();\n\t// Queue for unreferenced events that should be logged the next time GC runs.\n\tprivate pendingEventsQueue: IUnreferencedEventProps[] = [];\n\n\tconstructor(\n\t\tprivate readonly mc: MonitoringContext,\n\t\tprivate readonly configs: Pick<\n\t\t\tIGarbageCollectorConfigs,\n\t\t\t\"inactiveTimeoutMs\" | \"sweepTimeoutMs\"\n\t\t>,\n\t\tprivate readonly isSummarizerClient: boolean,\n\t\tprivate readonly gcTombstoneEnforcementAllowed: boolean,\n\t\tprivate readonly createContainerMetadata: ICreateContainerMetadata,\n\t\tprivate readonly getNodeType: (nodeId: string) => GCNodeType,\n\t\tprivate readonly getNodeStateTracker: (\n\t\t\tnodeId: string,\n\t\t) => UnreferencedStateTracker | undefined,\n\t\tprivate readonly getNodePackagePath: (\n\t\t\tnodePath: string,\n\t\t) => Promise<readonly string[] | undefined>,\n\t) {}\n\n\t/**\n\t * Returns whether an event should be logged for a node that isn't active anymore. Some scenarios where we won't log:\n\t * 1. When a DDS is changed or loaded. The corresponding data store's event will be logged instead.\n\t * 2. An event is logged only once per container instance per event per node.\n\t */\n\tprivate shouldLogNonActiveEvent(\n\t\tnodeId: string,\n\t\tnodeType: GCNodeType,\n\t\tusageType: NodeUsageType,\n\t\tnodeStateTracker: UnreferencedStateTracker,\n\t\tuniqueEventId: string,\n\t) {\n\t\tif (nodeStateTracker.state === UnreferencedState.Active) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// For sub data store (DDS) nodes, if they are changed or loaded, its data store will also be changed or loaded,\n\t\t// so skip logging to make the telemetry less noisy.\n\t\tif (nodeType === GCNodeType.SubDataStore && usageType !== \"Revived\") {\n\t\t\treturn false;\n\t\t}\n\t\tif (nodeType === GCNodeType.Other) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.loggedUnreferencedEvents.has(uniqueEventId)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Called when a node is used. If the node is not active, log an event indicating object is used when its not active.\n\t */\n\tpublic nodeUsed(nodeUsageProps: INodeUsageProps) {\n\t\t// If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip\n\t\t// logging as nothing interesting would have happened worth logging.\n\t\t// If the node is not unreferenced, skip logging.\n\t\tconst nodeStateTracker = this.getNodeStateTracker(nodeUsageProps.id);\n\t\tif (!nodeStateTracker || nodeUsageProps.currentReferenceTimestampMs === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We log these events once per event per node. A unique id is generated by joining node state (inactive / sweep ready),\n\t\t// node's id and usage (loaded / changed / revived).\n\t\tconst uniqueEventId = `${nodeStateTracker.state}-${nodeUsageProps.id}-${nodeUsageProps.usageType}`;\n\t\tconst nodeType = this.getNodeType(nodeUsageProps.id);\n\t\tif (\n\t\t\t!this.shouldLogNonActiveEvent(\n\t\t\t\tnodeUsageProps.id,\n\t\t\t\tnodeType,\n\t\t\t\tnodeUsageProps.usageType,\n\t\t\t\tnodeStateTracker,\n\t\t\t\tuniqueEventId,\n\t\t\t)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Add the unique event id so that we don't generate a log for this event again in this session..\n\t\tthis.loggedUnreferencedEvents.add(uniqueEventId);\n\n\t\tconst state = nodeStateTracker.state;\n\t\tconst { usageType, currentReferenceTimestampMs, packagePath, id, fromId, ...propsToLog } =\n\t\t\tnodeUsageProps;\n\t\tconst eventProps: Omit<IUnreferencedEventProps, \"state\" | \"usageType\"> = {\n\t\t\ttype: nodeType,\n\t\t\tunrefTime: nodeStateTracker.unreferencedTimestampMs,\n\t\t\tage:\n\t\t\t\tnodeUsageProps.currentReferenceTimestampMs -\n\t\t\t\tnodeStateTracker.unreferencedTimestampMs,\n\t\t\ttimeout:\n\t\t\t\tstate === UnreferencedState.Inactive\n\t\t\t\t\t? this.configs.inactiveTimeoutMs\n\t\t\t\t\t: this.configs.sweepTimeoutMs,\n\t\t\t...tagCodeArtifacts({ id, fromId }),\n\t\t\t...propsToLog,\n\t\t\t...this.createContainerMetadata,\n\t\t};\n\n\t\t// This will log the following events:\n\t\t// GC_Tombstone_DataStore_Revived, GC_Tombstone_SubDataStore_Revived, GC_Tombstone_Blob_Revived\n\t\tif (nodeUsageProps.usageType === \"Revived\" && nodeUsageProps.isTombstoned) {\n\t\t\tsendGCUnexpectedUsageEvent(\n\t\t\t\tthis.mc,\n\t\t\t\t{\n\t\t\t\t\teventName: `GC_Tombstone_${nodeType}_Revived`,\n\t\t\t\t\tcategory: \"generic\",\n\t\t\t\t\turl: tagAsCodeArtifact(id),\n\t\t\t\t\tgcTombstoneEnforcementAllowed: this.gcTombstoneEnforcementAllowed,\n\t\t\t\t},\n\t\t\t\tundefined /* packagePath */,\n\t\t\t);\n\t\t}\n\n\t\t// For summarizer client, queue the event so it is logged the next time GC runs if the event is still valid.\n\t\t// For non-summarizer client, log the event now since GC won't run on it. This may result in false positives\n\t\t// but it's a good signal nonetheless and we can consume it with a grain of salt.\n\t\t// Inactive errors are usages of Objects that are unreferenced for at least a period of 7 days.\n\t\t// SweepReady errors are usages of Objects that will be deleted by GC Sweep!\n\t\tif (this.isSummarizerClient) {\n\t\t\tthis.pendingEventsQueue.push({\n\t\t\t\t...eventProps,\n\t\t\t\tusageType: nodeUsageProps.usageType,\n\t\t\t\tstate,\n\t\t\t});\n\t\t} else {\n\t\t\t// For non-summarizer clients, only log \"Loaded\" type events since these objects may not be loaded in the\n\t\t\t// summarizer clients if they are based off of user actions (such as scrolling to content for these objects)\n\t\t\t// Events generated:\n\t\t\t// InactiveObject_Loaded, SweepReadyObject_Loaded\n\t\t\tif (nodeUsageProps.usageType === \"Loaded\") {\n\t\t\t\tconst { id: taggedId, fromId: taggedFromId, ...otherProps } = eventProps;\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${nodeUsageProps.usageType}`,\n\t\t\t\t\tpkg: packagePathToTelemetryProperty(nodeUsageProps.packagePath),\n\t\t\t\t\tstack: generateStack(),\n\t\t\t\t\tid: taggedId,\n\t\t\t\t\tfromId: taggedFromId,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t...otherProps,\n\t\t\t\t\t}),\n\t\t\t\t};\n\n\t\t\t\t// Do not log the inactive object x events as error events as they are not the best signal for\n\t\t\t\t// detecting something wrong with GC either from the partner or from the runtime itself.\n\t\t\t\tif (state === UnreferencedState.Inactive) {\n\t\t\t\t\tthis.mc.logger.sendTelemetryEvent(event);\n\t\t\t\t} else {\n\t\t\t\t\tthis.mc.logger.sendErrorEvent(event);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Log all new references or outbound routes in the current graph that haven't been explicitly notified to GC.\n\t * The principle is that every new reference or outbound route must be notified to GC via the\n\t * addedOutboundReference method. It it hasn't, its a bug and we want to identify these scenarios.\n\t *\n\t * In more simple terms:\n\t * Missing Explicit References = Current References - Previous References - Explicitly Added References;\n\t *\n\t * @param currentGCData - The GC data (reference graph) from the current GC run.\n\t * @param previousGCData - The GC data (reference graph) from the previous GC run.\n\t * @param explicitReferences - New references added explicity between the previous and the current run.\n\t */\n\tpublic logIfMissingExplicitReferences(\n\t\tcurrentGCData: IGarbageCollectionData,\n\t\tpreviousGCData: IGarbageCollectionData,\n\t\texplicitReferences: Map<string, string[]>,\n\t\tlogger: ITelemetryLoggerExt,\n\t) {\n\t\tfor (const [nodeId, currentOutboundRoutes] of Object.entries(currentGCData.gcNodes)) {\n\t\t\tconst previousRoutes = previousGCData.gcNodes[nodeId] ?? [];\n\t\t\tconst explicitRoutes = explicitReferences.get(nodeId) ?? [];\n\n\t\t\t/**\n\t\t\t * 1. For routes in the current GC data, routes that were not present in previous GC data and did not have\n\t\t\t * explicit references should be added to missing explicit routes list.\n\t\t\t * 2. Only include data store and blob routes since GC only works for these two.\n\t\t\t * Note: Due to a bug with de-duped blobs, only adding data store routes for now.\n\t\t\t * 3. Ignore DDS routes to their parent datastores since those were added implicitly. So, there won't be\n\t\t\t * explicit routes to them.\n\t\t\t */\n\t\t\tconst missingExplicitRoutes: string[] = [];\n\t\t\tfor (const route of currentOutboundRoutes) {\n\t\t\t\tconst nodeType = this.getNodeType(route);\n\t\t\t\tif (\n\t\t\t\t\t(nodeType === GCNodeType.DataStore || nodeType === GCNodeType.Blob) &&\n\t\t\t\t\t!nodeId.startsWith(route) &&\n\t\t\t\t\t!previousRoutes.includes(route) &&\n\t\t\t\t\t!explicitRoutes.includes(route)\n\t\t\t\t) {\n\t\t\t\t\tmissingExplicitRoutes.push(route);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (missingExplicitRoutes.length > 0) {\n\t\t\t\tlogger.sendErrorEvent({\n\t\t\t\t\teventName: \"gcUnknownOutboundReferences\",\n\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\tid: nodeId,\n\t\t\t\t\t\troutes: JSON.stringify(missingExplicitRoutes),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Log events that are pending in pendingEventsQueue. This is called after GC runs in the summarizer client\n\t * so that the state of an unreferenced node is updated.\n\t */\n\tpublic async logPendingEvents(logger: ITelemetryLoggerExt) {\n\t\t// Events sent come only from the summarizer client. In between summaries, events are pushed to a queue and at\n\t\t// summary time they are then logged.\n\t\t// Events generated:\n\t\t// InactiveObject_Loaded, InactiveObject_Changed, InactiveObject_Revived\n\t\t// SweepReadyObject_Loaded, SweepReadyObject_Changed, SweepReadyObject_Revived\n\t\tfor (const eventProps of this.pendingEventsQueue) {\n\t\t\tconst { usageType, state, id, fromId, ...propsToLog } = eventProps;\n\t\t\t/**\n\t\t\t * Revived event is logged only if the node is active. If the node is not active, the reference to it was\n\t\t\t * from another unreferenced node and this scenario is not interesting to log.\n\t\t\t * Loaded and Changed events are logged only if the node is not active. If the node is active, it was\n\t\t\t * revived and a Revived event will be logged for it.\n\t\t\t */\n\t\t\tconst nodeStateTracker = this.getNodeStateTracker(eventProps.id.value);\n\t\t\tconst active =\n\t\t\t\tnodeStateTracker === undefined ||\n\t\t\t\tnodeStateTracker.state === UnreferencedState.Active;\n\t\t\tif ((usageType === \"Revived\") === active) {\n\t\t\t\tconst pkg = await this.getNodePackagePath(eventProps.id.value);\n\t\t\t\tconst fromPkg = eventProps.fromId\n\t\t\t\t\t? await this.getNodePackagePath(eventProps.fromId.value)\n\t\t\t\t\t: undefined;\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${usageType}`,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t...propsToLog,\n\t\t\t\t\t}),\n\t\t\t\t\tid,\n\t\t\t\t\tfromId,\n\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\tpkg: pkg?.join(\"/\"),\n\t\t\t\t\t\tfromPkg: fromPkg?.join(\"/\"),\n\t\t\t\t\t}),\n\t\t\t\t};\n\n\t\t\t\tif (state === UnreferencedState.Inactive) {\n\t\t\t\t\tlogger.sendTelemetryEvent(event);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.sendErrorEvent(event);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.pendingEventsQueue = [];\n\t}\n\n\t/**\n\t * For nodes that are ready to sweep, log an event for now. Until we start running sweep which deletes objects,\n\t * this will give us a view into how much deleted content a container has.\n\t */\n\tpublic logSweepEvents(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tcurrentReferenceTimestampMs: number,\n\t\tunreferencedNodesState: Map<string, UnreferencedStateTracker>,\n\t\tcompletedGCRuns: number,\n\t\tlastSummaryTime?: number,\n\t) {\n\t\tif (\n\t\t\tthis.mc.config.getBoolean(disableSweepLogKey) === true ||\n\t\t\tthis.configs.sweepTimeoutMs === undefined\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst deletedNodeIds: string[] = [];\n\t\tfor (const [nodeId, nodeStateTracker] of unreferencedNodesState) {\n\t\t\tif (nodeStateTracker.state !== UnreferencedState.SweepReady) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst nodeType = this.getNodeType(nodeId);\n\t\t\tif (nodeType !== GCNodeType.DataStore && nodeType !== GCNodeType.Blob) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Log deleted event for each node only once to reduce noise in telemetry.\n\t\t\tconst uniqueEventId = `Deleted-${nodeId}`;\n\t\t\tif (this.loggedUnreferencedEvents.has(uniqueEventId)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.loggedUnreferencedEvents.add(uniqueEventId);\n\t\t\tdeletedNodeIds.push(nodeId);\n\t\t}\n\n\t\tif (deletedNodeIds.length > 0) {\n\t\t\tlogger.sendTelemetryEvent({\n\t\t\t\teventName: \"GC_SweepReadyObjects_Delete\",\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\ttimeout: this.configs.sweepTimeoutMs,\n\t\t\t\t\tcompletedGCRuns,\n\t\t\t\t\tlastSummaryTime,\n\t\t\t\t\t...this.createContainerMetadata,\n\t\t\t\t}),\n\t\t\t\t...tagCodeArtifacts({ id: JSON.stringify(deletedNodeIds) }),\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a\n * tombstoned or deleted object is loaded.\n */\nexport function sendGCUnexpectedUsageEvent(\n\tmc: MonitoringContext,\n\tevent: ITelemetryGenericEvent & {\n\t\tcategory: \"error\" | \"generic\";\n\t\tgcTombstoneEnforcementAllowed: boolean | undefined;\n\t},\n\tpackagePath: readonly string[] | undefined,\n\terror?: unknown,\n) {\n\tevent.pkg = tagCodeArtifacts({ pkg: packagePath?.join(\"/\") })?.pkg;\n\tevent.tombstoneFlags = JSON.stringify({\n\t\tDisableTombstone: mc.config.getBoolean(disableTombstoneKey),\n\t\tThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\tThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadKey),\n\t});\n\tevent.sweepFlags = JSON.stringify({\n\t\tEnableSweepFlag: mc.config.getBoolean(runSweepKey),\n\t});\n\n\tmc.logger.sendTelemetryEvent(event, error);\n}\n"]}
1
+ {"version":3,"file":"gcTelemetry.js","sourceRoot":"","sources":["../../src/gc/gcTelemetry.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 { ITelemetryGenericEvent } from \"@fluidframework/core-interfaces\";\nimport { IGarbageCollectionData } from \"@fluidframework/runtime-definitions\";\nimport {\n\tgenerateStack,\n\tITelemetryLoggerExt,\n\tMonitoringContext,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils\";\nimport { ICreateContainerMetadata } from \"../summary\";\nimport {\n\tdisableSweepLogKey,\n\tGCNodeType,\n\tUnreferencedState,\n\tIGarbageCollectorConfigs,\n\tdisableTombstoneKey,\n\tthrowOnTombstoneUsageKey,\n\tthrowOnTombstoneLoadKey,\n\trunSweepKey,\n} from \"./gcDefinitions\";\nimport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker\";\nimport { tagAsCodeArtifact } from \"./gcHelpers\";\n\ntype NodeUsageType = \"Changed\" | \"Loaded\" | \"Revived\";\n\n/** Properties that are common to IUnreferencedEventProps and INodeUsageProps */\ninterface ICommonProps {\n\tusageType: NodeUsageType;\n\tcompletedGCRuns: number;\n\tisTombstoned: boolean;\n\tlastSummaryTime?: number;\n\tviaHandle?: boolean;\n}\n\n/** The event that is logged when unreferenced node is used after a certain time. */\ninterface IUnreferencedEventProps extends ICreateContainerMetadata, ICommonProps {\n\tstate: UnreferencedState;\n\tid: {\n\t\tvalue: string;\n\t\ttag: string;\n\t};\n\ttype: GCNodeType;\n\tunrefTime: number;\n\tage: number;\n\ttimeout?: number;\n\tfromId?: {\n\t\tvalue: string;\n\t\ttag: string;\n\t};\n}\n\n/** Properties passed to nodeUsed function when a node is used. */\ninterface INodeUsageProps extends ICommonProps {\n\tid: string;\n\tcurrentReferenceTimestampMs: number | undefined;\n\tpackagePath: readonly string[] | undefined;\n\tfromId?: string;\n}\n\n/**\n * Encapsulates the logic that tracks the various telemetry logged by the Garbage Collector. There are 4 types of\n * telemetry logged:\n * 1. inactiveObject telemetry - When an inactive node is used - A node that has been unreferenced for inactiveTimeoutMs.\n * 2. sweepReadyObject telemetry - When a sweep ready node is used - A node that has been unreferenced for sweepTimeoutMs.\n * 3. Tombstone telemetry - When a tombstoned node is used - A node that that has been marked as tombstone.\n * 4. Sweep / deleted telemetry - When a node is detected as sweep ready in the sweep phase.\n * 5. Unknown outbound reference telemetry - When a node is referenced but GC is not explicitly notified of it.\n */\nexport class GCTelemetryTracker {\n\t// Keeps track of unreferenced events that are logged for a node. This is used to limit the log generation to one\n\t// per event per node.\n\tprivate readonly loggedUnreferencedEvents: Set<string> = new Set();\n\t// Queue for unreferenced events that should be logged the next time GC runs.\n\tprivate pendingEventsQueue: IUnreferencedEventProps[] = [];\n\n\tconstructor(\n\t\tprivate readonly mc: MonitoringContext,\n\t\tprivate readonly configs: Pick<\n\t\t\tIGarbageCollectorConfigs,\n\t\t\t\"inactiveTimeoutMs\" | \"sweepTimeoutMs\"\n\t\t>,\n\t\tprivate readonly isSummarizerClient: boolean,\n\t\tprivate readonly gcTombstoneEnforcementAllowed: boolean,\n\t\tprivate readonly createContainerMetadata: ICreateContainerMetadata,\n\t\tprivate readonly getNodeType: (nodeId: string) => GCNodeType,\n\t\tprivate readonly getNodeStateTracker: (\n\t\t\tnodeId: string,\n\t\t) => UnreferencedStateTracker | undefined,\n\t\tprivate readonly getNodePackagePath: (\n\t\t\tnodePath: string,\n\t\t) => Promise<readonly string[] | undefined>,\n\t) {}\n\n\t/**\n\t * Returns whether an event should be logged for a node that isn't active anymore. Some scenarios where we won't log:\n\t * 1. When a DDS is changed or loaded. The corresponding data store's event will be logged instead.\n\t * 2. An event is logged only once per container instance per event per node.\n\t */\n\tprivate shouldLogNonActiveEvent(\n\t\tnodeId: string,\n\t\tnodeType: GCNodeType,\n\t\tusageType: NodeUsageType,\n\t\tnodeStateTracker: UnreferencedStateTracker,\n\t\tuniqueEventId: string,\n\t) {\n\t\tif (nodeStateTracker.state === UnreferencedState.Active) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// For sub data store (DDS) nodes, if they are changed or loaded, its data store will also be changed or loaded,\n\t\t// so skip logging to make the telemetry less noisy.\n\t\tif (nodeType === GCNodeType.SubDataStore && usageType !== \"Revived\") {\n\t\t\treturn false;\n\t\t}\n\t\tif (nodeType === GCNodeType.Other) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.loggedUnreferencedEvents.has(uniqueEventId)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Called when a node is used. If the node is not active, log an event indicating object is used when its not active.\n\t */\n\tpublic nodeUsed(nodeUsageProps: INodeUsageProps) {\n\t\t// If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip\n\t\t// logging as nothing interesting would have happened worth logging.\n\t\t// If the node is not unreferenced, skip logging.\n\t\tconst nodeStateTracker = this.getNodeStateTracker(nodeUsageProps.id);\n\t\tif (!nodeStateTracker || nodeUsageProps.currentReferenceTimestampMs === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We log these events once per event per node. A unique id is generated by joining node state (inactive / sweep ready),\n\t\t// node's id and usage (loaded / changed / revived).\n\t\tconst uniqueEventId = `${nodeStateTracker.state}-${nodeUsageProps.id}-${nodeUsageProps.usageType}`;\n\t\tconst nodeType = this.getNodeType(nodeUsageProps.id);\n\t\tif (\n\t\t\t!this.shouldLogNonActiveEvent(\n\t\t\t\tnodeUsageProps.id,\n\t\t\t\tnodeType,\n\t\t\t\tnodeUsageProps.usageType,\n\t\t\t\tnodeStateTracker,\n\t\t\t\tuniqueEventId,\n\t\t\t)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Add the unique event id so that we don't generate a log for this event again in this session..\n\t\tthis.loggedUnreferencedEvents.add(uniqueEventId);\n\n\t\tconst state = nodeStateTracker.state;\n\t\tconst { usageType, currentReferenceTimestampMs, packagePath, id, fromId, ...propsToLog } =\n\t\t\tnodeUsageProps;\n\t\tconst eventProps: Omit<IUnreferencedEventProps, \"state\" | \"usageType\"> = {\n\t\t\ttype: nodeType,\n\t\t\tunrefTime: nodeStateTracker.unreferencedTimestampMs,\n\t\t\tage:\n\t\t\t\tnodeUsageProps.currentReferenceTimestampMs -\n\t\t\t\tnodeStateTracker.unreferencedTimestampMs,\n\t\t\ttimeout:\n\t\t\t\tstate === UnreferencedState.Inactive\n\t\t\t\t\t? this.configs.inactiveTimeoutMs\n\t\t\t\t\t: this.configs.sweepTimeoutMs,\n\t\t\t...tagCodeArtifacts({ id, fromId }),\n\t\t\t...propsToLog,\n\t\t\t...this.createContainerMetadata,\n\t\t};\n\n\t\t// This will log the following events:\n\t\t// GC_Tombstone_DataStore_Revived, GC_Tombstone_SubDataStore_Revived, GC_Tombstone_Blob_Revived\n\t\tif (nodeUsageProps.usageType === \"Revived\" && nodeUsageProps.isTombstoned) {\n\t\t\tsendGCUnexpectedUsageEvent(\n\t\t\t\tthis.mc,\n\t\t\t\t{\n\t\t\t\t\teventName: `GC_Tombstone_${nodeType}_Revived`,\n\t\t\t\t\tcategory: \"generic\",\n\t\t\t\t\turl: tagAsCodeArtifact(id),\n\t\t\t\t\tgcTombstoneEnforcementAllowed: this.gcTombstoneEnforcementAllowed,\n\t\t\t\t},\n\t\t\t\tundefined /* packagePath */,\n\t\t\t);\n\t\t}\n\n\t\t// For summarizer client, queue the event so it is logged the next time GC runs if the event is still valid.\n\t\t// For non-summarizer client, log the event now since GC won't run on it. This may result in false positives\n\t\t// but it's a good signal nonetheless and we can consume it with a grain of salt.\n\t\t// Inactive errors are usages of Objects that are unreferenced for at least a period of 7 days.\n\t\t// SweepReady errors are usages of Objects that will be deleted by GC Sweep!\n\t\tif (this.isSummarizerClient) {\n\t\t\tthis.pendingEventsQueue.push({\n\t\t\t\t...eventProps,\n\t\t\t\tusageType: nodeUsageProps.usageType,\n\t\t\t\tstate,\n\t\t\t});\n\t\t} else {\n\t\t\t// For non-summarizer clients, only log \"Loaded\" type events since these objects may not be loaded in the\n\t\t\t// summarizer clients if they are based off of user actions (such as scrolling to content for these objects)\n\t\t\t// Events generated:\n\t\t\t// InactiveObject_Loaded, SweepReadyObject_Loaded\n\t\t\tif (nodeUsageProps.usageType === \"Loaded\") {\n\t\t\t\tconst { id: taggedId, fromId: taggedFromId, ...otherProps } = eventProps;\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${nodeUsageProps.usageType}`,\n\t\t\t\t\tpkg: tagCodeArtifacts({ pkg: nodeUsageProps.packagePath?.join(\"/\") }).pkg,\n\t\t\t\t\tstack: generateStack(),\n\t\t\t\t\tid: taggedId,\n\t\t\t\t\tfromId: taggedFromId,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t...otherProps,\n\t\t\t\t\t}),\n\t\t\t\t};\n\n\t\t\t\t// Do not log the inactive object x events as error events as they are not the best signal for\n\t\t\t\t// detecting something wrong with GC either from the partner or from the runtime itself.\n\t\t\t\tif (state === UnreferencedState.Inactive) {\n\t\t\t\t\tthis.mc.logger.sendTelemetryEvent(event);\n\t\t\t\t} else {\n\t\t\t\t\tthis.mc.logger.sendErrorEvent(event);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Log all new references or outbound routes in the current graph that haven't been explicitly notified to GC.\n\t * The principle is that every new reference or outbound route must be notified to GC via the\n\t * addedOutboundReference method. It it hasn't, its a bug and we want to identify these scenarios.\n\t *\n\t * In more simple terms:\n\t * Missing Explicit References = Current References - Previous References - Explicitly Added References;\n\t *\n\t * @param currentGCData - The GC data (reference graph) from the current GC run.\n\t * @param previousGCData - The GC data (reference graph) from the previous GC run.\n\t * @param explicitReferences - New references added explicity between the previous and the current run.\n\t */\n\tpublic logIfMissingExplicitReferences(\n\t\tcurrentGCData: IGarbageCollectionData,\n\t\tpreviousGCData: IGarbageCollectionData,\n\t\texplicitReferences: Map<string, string[]>,\n\t\tlogger: ITelemetryLoggerExt,\n\t) {\n\t\tfor (const [nodeId, currentOutboundRoutes] of Object.entries(currentGCData.gcNodes)) {\n\t\t\tconst previousRoutes = previousGCData.gcNodes[nodeId] ?? [];\n\t\t\tconst explicitRoutes = explicitReferences.get(nodeId) ?? [];\n\n\t\t\t/**\n\t\t\t * 1. For routes in the current GC data, routes that were not present in previous GC data and did not have\n\t\t\t * explicit references should be added to missing explicit routes list.\n\t\t\t * 2. Only include data store and blob routes since GC only works for these two.\n\t\t\t * Note: Due to a bug with de-duped blobs, only adding data store routes for now.\n\t\t\t * 3. Ignore DDS routes to their parent datastores since those were added implicitly. So, there won't be\n\t\t\t * explicit routes to them.\n\t\t\t */\n\t\t\tconst missingExplicitRoutes: string[] = [];\n\t\t\tfor (const route of currentOutboundRoutes) {\n\t\t\t\tconst nodeType = this.getNodeType(route);\n\t\t\t\tif (\n\t\t\t\t\t(nodeType === GCNodeType.DataStore || nodeType === GCNodeType.Blob) &&\n\t\t\t\t\t!nodeId.startsWith(route) &&\n\t\t\t\t\t!previousRoutes.includes(route) &&\n\t\t\t\t\t!explicitRoutes.includes(route)\n\t\t\t\t) {\n\t\t\t\t\tmissingExplicitRoutes.push(route);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (missingExplicitRoutes.length > 0) {\n\t\t\t\tlogger.sendErrorEvent({\n\t\t\t\t\teventName: \"gcUnknownOutboundReferences\",\n\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\tid: nodeId,\n\t\t\t\t\t\troutes: JSON.stringify(missingExplicitRoutes),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Log events that are pending in pendingEventsQueue. This is called after GC runs in the summarizer client\n\t * so that the state of an unreferenced node is updated.\n\t */\n\tpublic async logPendingEvents(logger: ITelemetryLoggerExt) {\n\t\t// Events sent come only from the summarizer client. In between summaries, events are pushed to a queue and at\n\t\t// summary time they are then logged.\n\t\t// Events generated:\n\t\t// InactiveObject_Loaded, InactiveObject_Changed, InactiveObject_Revived\n\t\t// SweepReadyObject_Loaded, SweepReadyObject_Changed, SweepReadyObject_Revived\n\t\tfor (const eventProps of this.pendingEventsQueue) {\n\t\t\tconst { usageType, state, id, fromId, ...propsToLog } = eventProps;\n\t\t\t/**\n\t\t\t * Revived event is logged only if the node is active. If the node is not active, the reference to it was\n\t\t\t * from another unreferenced node and this scenario is not interesting to log.\n\t\t\t * Loaded and Changed events are logged only if the node is not active. If the node is active, it was\n\t\t\t * revived and a Revived event will be logged for it.\n\t\t\t */\n\t\t\tconst nodeStateTracker = this.getNodeStateTracker(eventProps.id.value);\n\t\t\tconst active =\n\t\t\t\tnodeStateTracker === undefined ||\n\t\t\t\tnodeStateTracker.state === UnreferencedState.Active;\n\t\t\tif ((usageType === \"Revived\") === active) {\n\t\t\t\tconst pkg = await this.getNodePackagePath(eventProps.id.value);\n\t\t\t\tconst fromPkg = eventProps.fromId\n\t\t\t\t\t? await this.getNodePackagePath(eventProps.fromId.value)\n\t\t\t\t\t: undefined;\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${usageType}`,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t...propsToLog,\n\t\t\t\t\t}),\n\t\t\t\t\tid,\n\t\t\t\t\tfromId,\n\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\tpkg: pkg?.join(\"/\"),\n\t\t\t\t\t\tfromPkg: fromPkg?.join(\"/\"),\n\t\t\t\t\t}),\n\t\t\t\t};\n\n\t\t\t\tif (state === UnreferencedState.Inactive) {\n\t\t\t\t\tlogger.sendTelemetryEvent(event);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.sendErrorEvent(event);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.pendingEventsQueue = [];\n\t}\n\n\t/**\n\t * For nodes that are ready to sweep, log an event for now. Until we start running sweep which deletes objects,\n\t * this will give us a view into how much deleted content a container has.\n\t */\n\tpublic logSweepEvents(\n\t\tlogger: ITelemetryLoggerExt,\n\t\tcurrentReferenceTimestampMs: number,\n\t\tunreferencedNodesState: Map<string, UnreferencedStateTracker>,\n\t\tcompletedGCRuns: number,\n\t\tlastSummaryTime?: number,\n\t) {\n\t\tif (\n\t\t\tthis.mc.config.getBoolean(disableSweepLogKey) === true ||\n\t\t\tthis.configs.sweepTimeoutMs === undefined\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst deletedNodeIds: string[] = [];\n\t\tfor (const [nodeId, nodeStateTracker] of unreferencedNodesState) {\n\t\t\tif (nodeStateTracker.state !== UnreferencedState.SweepReady) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst nodeType = this.getNodeType(nodeId);\n\t\t\tif (nodeType !== GCNodeType.DataStore && nodeType !== GCNodeType.Blob) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Log deleted event for each node only once to reduce noise in telemetry.\n\t\t\tconst uniqueEventId = `Deleted-${nodeId}`;\n\t\t\tif (this.loggedUnreferencedEvents.has(uniqueEventId)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.loggedUnreferencedEvents.add(uniqueEventId);\n\t\t\tdeletedNodeIds.push(nodeId);\n\t\t}\n\n\t\tif (deletedNodeIds.length > 0) {\n\t\t\tlogger.sendTelemetryEvent({\n\t\t\t\teventName: \"GC_SweepReadyObjects_Delete\",\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\ttimeout: this.configs.sweepTimeoutMs,\n\t\t\t\t\tcompletedGCRuns,\n\t\t\t\t\tlastSummaryTime,\n\t\t\t\t\t...this.createContainerMetadata,\n\t\t\t\t}),\n\t\t\t\t...tagCodeArtifacts({ id: JSON.stringify(deletedNodeIds) }),\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a\n * tombstoned or deleted object is loaded.\n */\nexport function sendGCUnexpectedUsageEvent(\n\tmc: MonitoringContext,\n\tevent: ITelemetryGenericEvent & {\n\t\tcategory: \"error\" | \"generic\";\n\t\tgcTombstoneEnforcementAllowed: boolean | undefined;\n\t},\n\tpackagePath: readonly string[] | undefined,\n\terror?: unknown,\n) {\n\tevent.pkg = tagCodeArtifacts({ pkg: packagePath?.join(\"/\") })?.pkg;\n\tevent.tombstoneFlags = JSON.stringify({\n\t\tDisableTombstone: mc.config.getBoolean(disableTombstoneKey),\n\t\tThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\tThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadKey),\n\t});\n\tevent.sweepFlags = JSON.stringify({\n\t\tEnableSweepFlag: mc.config.getBoolean(runSweepKey),\n\t});\n\n\tmc.logger.sendTelemetryEvent(event, error);\n}\n"]}
@@ -153,9 +153,8 @@ class IdCompressor {
153
153
  * it is finalized. Ranges must be sent to the server in the order that they are taken via calls to this method.
154
154
  */
155
155
  takeNextCreationRange() {
156
- var _a;
157
156
  const lastLocalInRange = -this.localIdCount;
158
- const lastTakenNormalized = (_a = this.lastTakenLocalId) !== null && _a !== void 0 ? _a : 0;
157
+ const lastTakenNormalized = this.lastTakenLocalId ?? 0;
159
158
  (0, common_utils_1.assert)(lastLocalInRange <= lastTakenNormalized, 0x485 /* Inconsistent local ID state */);
160
159
  let ids;
161
160
  if (lastLocalInRange !== lastTakenNormalized) {
@@ -198,21 +197,20 @@ class IdCompressor {
198
197
  * @param range - the range of session-local IDs to finalize.
199
198
  */
200
199
  finalizeCreationRange(range) {
201
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
202
200
  const { sessionId } = range;
203
201
  const isLocal = sessionId === this.localSessionId;
204
- const session = (_a = this.sessions.get(sessionId)) !== null && _a !== void 0 ? _a : this.createSession(sessionId);
202
+ const session = this.sessions.get(sessionId) ?? this.createSession(sessionId);
205
203
  const ids = (0, idRange_1.getIds)(range);
206
204
  if (ids === undefined) {
207
205
  return;
208
206
  }
209
207
  const { currentClusterDetails } = session;
210
- const { cluster: currentCluster, clusterBase: currentBaseFinalId } = currentClusterDetails !== null && currentClusterDetails !== void 0 ? currentClusterDetails : {
208
+ const { cluster: currentCluster, clusterBase: currentBaseFinalId } = currentClusterDetails ?? {
211
209
  cluster: undefined,
212
210
  clusterBase: undefined,
213
211
  };
214
212
  const currentClusterExists = currentCluster !== undefined && currentBaseFinalId !== undefined;
215
- const normalizedLastFinalizedLocal = (_b = session.lastFinalizedLocalId) !== null && _b !== void 0 ? _b : 0;
213
+ const normalizedLastFinalizedLocal = session.lastFinalizedLocalId ?? 0;
216
214
  const { first: newFirstFinalizedLocal, last: newLastFinalizedLocal } = ids;
217
215
  (0, common_utils_1.assert)(newFirstFinalizedLocal === normalizedLastFinalizedLocal - 1, 0x489 /* Ranges finalized out of order. */);
218
216
  // The total number of session-local IDs to finalize
@@ -224,7 +222,8 @@ class IdCompressor {
224
222
  let newBaseUuid;
225
223
  if (currentClusterExists) {
226
224
  if (isLocal) {
227
- const lastKnownFinal = (_c = this.sessionIdNormalizer.getLastFinalId()) !== null && _c !== void 0 ? _c : (0, utils_1.fail)("Cluster exists but normalizer does not have an entry for it.");
225
+ const lastKnownFinal = this.sessionIdNormalizer.getLastFinalId() ??
226
+ (0, utils_1.fail)("Cluster exists but normalizer does not have an entry for it.");
228
227
  const lastAlignedFinalInCluster = (currentBaseFinalId +
229
228
  Math.min(currentCluster.count + finalizeCount, currentCluster.capacity) -
230
229
  1);
@@ -275,7 +274,7 @@ class IdCompressor {
275
274
  // actually finalized, because total order broadcast guarantees that any usage of those final IDs will be observed after
276
275
  // the finalization of the ranges.
277
276
  this.sessionIdNormalizer.registerFinalIdBlock(finalPivot, expansionAmount, currentCluster);
278
- (_d = this.logger) === null || _d === void 0 ? void 0 : _d.sendTelemetryEvent({
277
+ this.logger?.sendTelemetryEvent({
279
278
  eventName: "RuntimeIdCompressor:ClusterExpansion",
280
279
  sessionId: this.localSessionId,
281
280
  previousCapacity,
@@ -291,7 +290,7 @@ class IdCompressor {
291
290
  newBaseUuid = (0, numericUuid_1.incrementUuid)(currentCluster.baseUuid, currentCluster.capacity);
292
291
  currentCluster.count += remainingCapacity;
293
292
  remainingCount -= remainingCapacity;
294
- (_e = this.logger) === null || _e === void 0 ? void 0 : _e.sendTelemetryEvent({
293
+ this.logger?.sendTelemetryEvent({
295
294
  eventName: "RuntimeIdCompressor:OverfilledCluster",
296
295
  sessionId: this.localSessionId,
297
296
  });
@@ -301,7 +300,7 @@ class IdCompressor {
301
300
  // Session has never made a cluster, form a new one with the session UUID as the baseUuid
302
301
  newBaseUuid = session.sessionUuid;
303
302
  if (isLocal) {
304
- (_f = this.logger) === null || _f === void 0 ? void 0 : _f.sendTelemetryEvent({
303
+ this.logger?.sendTelemetryEvent({
305
304
  eventName: "RuntimeIdCompressor:FirstCluster",
306
305
  sessionId: this.localSessionId,
307
306
  });
@@ -336,7 +335,7 @@ class IdCompressor {
336
335
  const usedCapacity = finalizeCount - remainingCount;
337
336
  localIdPivot = (newFirstFinalizedLocal - usedCapacity);
338
337
  if (isLocal) {
339
- (_g = this.logger) === null || _g === void 0 ? void 0 : _g.sendTelemetryEvent({
338
+ this.logger?.sendTelemetryEvent({
340
339
  eventName: "RuntimeIdCompressor:NewCluster",
341
340
  sessionId: this.localSessionId,
342
341
  clusterCapacity: newCapacity,
@@ -382,7 +381,7 @@ class IdCompressor {
382
381
  (normalizedLastFinalizedLocal - overriddenLocal) -
383
382
  1);
384
383
  }
385
- (_h = cluster.overrides) !== null && _h !== void 0 ? _h : (cluster.overrides = new Map());
384
+ cluster.overrides ?? (cluster.overrides = new Map());
386
385
  const inversionKey = IdCompressor.createInversionKey(override);
387
386
  const existingIds = this.getExistingIdsForNewOverride(inversionKey, true);
388
387
  let overrideForCluster;
@@ -450,11 +449,11 @@ class IdCompressor {
450
449
  }
451
450
  }
452
451
  if (isLocal) {
453
- (_j = this.logger) === null || _j === void 0 ? void 0 : _j.sendTelemetryEvent({
452
+ this.logger?.sendTelemetryEvent({
454
453
  eventName: "RuntimeIdCompressor:IdCompressorStatus",
455
- eagerFinalIdCount: eagerFinalIdCount - ((_k = overrides === null || overrides === void 0 ? void 0 : overrides.length) !== null && _k !== void 0 ? _k : 0),
456
- localIdCount: remainingCount + ((_l = overrides === null || overrides === void 0 ? void 0 : overrides.length) !== null && _l !== void 0 ? _l : 0),
457
- overridesCount: (_m = overrides === null || overrides === void 0 ? void 0 : overrides.length) !== null && _m !== void 0 ? _m : 0,
454
+ eagerFinalIdCount: eagerFinalIdCount - (overrides?.length ?? 0),
455
+ localIdCount: remainingCount + (overrides?.length ?? 0),
456
+ overridesCount: overrides?.length ?? 0,
458
457
  sessionId: this.localSessionId,
459
458
  });
460
459
  }
@@ -499,7 +498,6 @@ class IdCompressor {
499
498
  * Returns an existing ID associated with an override, or undefined if none exists.
500
499
  */
501
500
  getExistingIdsForNewOverride(inversionKey, isFinalOverride) {
502
- var _a;
503
501
  const closestMatch = this.clustersAndOverridesInversion.getPairOrNextLower(inversionKey, reusedArray);
504
502
  let numericOverride;
505
503
  let stableOverride;
@@ -537,7 +535,9 @@ class IdCompressor {
537
535
  }
538
536
  }
539
537
  }
540
- const override = (_a = numericOverride !== null && numericOverride !== void 0 ? numericOverride : stableOverride) !== null && _a !== void 0 ? _a : (IdCompressor.isStableInversionKey(inversionKey) ? inversionKey : undefined);
538
+ const override = numericOverride ??
539
+ stableOverride ??
540
+ (IdCompressor.isStableInversionKey(inversionKey) ? inversionKey : undefined);
541
541
  if (override !== undefined) {
542
542
  const sessionSpaceId = this.getCompressedIdForStableId(override);
543
543
  if (sessionSpaceId !== undefined) {
@@ -565,8 +565,7 @@ class IdCompressor {
565
565
  * Helper for retrieving an override.
566
566
  */
567
567
  static tryGetOverride(cluster, finalId) {
568
- var _a;
569
- const override = (_a = cluster.overrides) === null || _a === void 0 ? void 0 : _a.get(finalId);
568
+ const override = cluster.overrides?.get(finalId);
570
569
  if (override === undefined) {
571
570
  return undefined;
572
571
  }
@@ -611,15 +610,15 @@ class IdCompressor {
611
610
  const registeredLocal = sessionIdNormalizer.addLocalId();
612
611
  (0, common_utils_1.assert)(registeredLocal === newLocalId, 0x496 /* Session ID Normalizer produced unexpected local ID */);
613
612
  if (eagerFinalId !== undefined) {
614
- sessionIdNormalizer.addFinalIds(eagerFinalId, eagerFinalId, cluster !== null && cluster !== void 0 ? cluster : (0, utils_1.fail)("No cluster when generating compressed ID"));
613
+ sessionIdNormalizer.addFinalIds(eagerFinalId, eagerFinalId, cluster ?? (0, utils_1.fail)("No cluster when generating compressed ID"));
615
614
  }
616
- this.localOverrides.append(newLocalId, override !== null && override !== void 0 ? override : (0, utils_1.fail)("Override must be defined"));
615
+ this.localOverrides.append(newLocalId, override ?? (0, utils_1.fail)("Override must be defined"));
617
616
  // Since the local ID was just created, it is in both session and op space
618
617
  const compressionMapping = newLocalId;
619
618
  this.clustersAndOverridesInversion.set(overrideInversionKey, compressionMapping);
620
619
  }
621
620
  else if (eagerFinalId !== undefined) {
622
- sessionIdNormalizer.addFinalIds(eagerFinalId, eagerFinalId, cluster !== null && cluster !== void 0 ? cluster : (0, utils_1.fail)("No cluster when generating compressed ID"));
621
+ sessionIdNormalizer.addFinalIds(eagerFinalId, eagerFinalId, cluster ?? (0, utils_1.fail)("No cluster when generating compressed ID"));
623
622
  return eagerFinalId;
624
623
  }
625
624
  else {
@@ -634,8 +633,7 @@ class IdCompressor {
634
633
  * @returns the UUID or override string associated with the compressed ID. Fails if the ID was not generated by this compressor.
635
634
  */
636
635
  decompress(id) {
637
- var _a;
638
- return (_a = this.tryDecompress(id)) !== null && _a !== void 0 ? _a : (0, utils_1.fail)("Compressed ID was not generated by this compressor");
636
+ return this.tryDecompress(id) ?? (0, utils_1.fail)("Compressed ID was not generated by this compressor");
639
637
  }
640
638
  /**
641
639
  * Attempts to decompress a previously compressed ID into a UUID or override string.
@@ -643,7 +641,6 @@ class IdCompressor {
643
641
  * @returns the UUID or override string associated with the compressed ID, or undefined if the ID was not generated by this compressor.
644
642
  */
645
643
  tryDecompress(id) {
646
- var _a;
647
644
  if (isFinalId(id)) {
648
645
  const possibleCluster = this.getClusterForFinalId(id);
649
646
  if (possibleCluster === undefined) {
@@ -675,7 +672,7 @@ class IdCompressor {
675
672
  // If this is a local ID with an override, then it must have been allocated on this machine and will be contained in
676
673
  // `localOverrides`s. Otherwise, it is a sequential allocation from the session UUID and can simply be negated and
677
674
  // added to that UUID to obtain the stable ID associated with it.
678
- const localOverride = (_a = this.localOverrides) === null || _a === void 0 ? void 0 : _a.get(id);
675
+ const localOverride = this.localOverrides?.get(id);
679
676
  return localOverride !== undefined
680
677
  ? localOverride
681
678
  : (0, numericUuid_1.stableIdFromNumericUuid)(this.localSession.sessionUuid, idOffset - 1);
@@ -687,8 +684,7 @@ class IdCompressor {
687
684
  * @returns the `CompressedId` associated with `uncompressed`. Fails if it has not been previously compressed by this compressor.
688
685
  */
689
686
  recompress(uncompressed) {
690
- var _a;
691
- return (_a = this.tryRecompress(uncompressed)) !== null && _a !== void 0 ? _a : (0, utils_1.fail)("No such string has ever been compressed");
687
+ return this.tryRecompress(uncompressed) ?? (0, utils_1.fail)("No such string has ever been compressed");
692
688
  }
693
689
  /**
694
690
  * Attempts to recompresses a decompressed ID, which could be a UUID or an override string.
@@ -703,7 +699,6 @@ class IdCompressor {
703
699
  * performance optimization.
704
700
  */
705
701
  recompressInternal(uncompressed, uncompressedUuidNumeric) {
706
- var _a, _b;
707
702
  let numericUuid = uncompressedUuidNumeric;
708
703
  const inversionKey = IdCompressor.createInversionKey(uncompressed);
709
704
  const isStable = IdCompressor.isStableInversionKey(inversionKey);
@@ -714,7 +709,8 @@ class IdCompressor {
714
709
  if (key === inversionKey) {
715
710
  return IdCompressor.isUnfinalizedOverride(compressionMapping)
716
711
  ? compressionMapping
717
- : (_a = compressionMapping.associatedLocalId) !== null && _a !== void 0 ? _a : compressionMapping.originalOverridingFinal;
712
+ : compressionMapping.associatedLocalId ??
713
+ compressionMapping.originalOverridingFinal;
718
714
  }
719
715
  }
720
716
  else {
@@ -722,11 +718,11 @@ class IdCompressor {
722
718
  return undefined;
723
719
  }
724
720
  const { clusterBase: closestBaseFinalId, cluster: closestCluster } = compressionMapping;
725
- numericUuid !== null && numericUuid !== void 0 ? numericUuid : (numericUuid = (0, numericUuid_1.numericUuidFromStableId)(inversionKey));
721
+ numericUuid ?? (numericUuid = (0, numericUuid_1.numericUuidFromStableId)(inversionKey));
726
722
  const uuidOffset = (0, numericUuid_1.getPositiveDelta)(numericUuid, closestCluster.baseUuid, closestCluster.count - 1);
727
723
  if (uuidOffset !== undefined) {
728
724
  let targetFinalId = (closestBaseFinalId + uuidOffset);
729
- const override = (_b = closestCluster.overrides) === null || _b === void 0 ? void 0 : _b.get(targetFinalId);
725
+ const override = closestCluster.overrides?.get(targetFinalId);
730
726
  if (typeof override === "object") {
731
727
  if (override.associatedLocalId !== undefined) {
732
728
  return override.associatedLocalId;
@@ -741,7 +737,7 @@ class IdCompressor {
741
737
  }
742
738
  if (isStable) {
743
739
  // May have already computed the numeric UUID, so avoid recomputing if possible
744
- const sessionSpaceId = this.getCompressedIdForStableId(numericUuid !== null && numericUuid !== void 0 ? numericUuid : inversionKey);
740
+ const sessionSpaceId = this.getCompressedIdForStableId(numericUuid ?? inversionKey);
745
741
  if (sessionSpaceId !== undefined) {
746
742
  return sessionSpaceId;
747
743
  }
@@ -754,7 +750,6 @@ class IdCompressor {
754
750
  * @returns the ID in op space.
755
751
  */
756
752
  normalizeToOpSpace(id) {
757
- var _a, _b, _c;
758
753
  if (isFinalId(id)) {
759
754
  return id;
760
755
  }
@@ -773,7 +768,8 @@ class IdCompressor {
773
768
  const override = this.localOverrides.get(id);
774
769
  if (override !== undefined) {
775
770
  const inversionKey = IdCompressor.createInversionKey(override);
776
- const compressionMapping = (_a = this.clustersAndOverridesInversion.get(inversionKey)) !== null && _a !== void 0 ? _a : (0, utils_1.fail)("Bimap is malformed.");
771
+ const compressionMapping = this.clustersAndOverridesInversion.get(inversionKey) ??
772
+ (0, utils_1.fail)("Bimap is malformed.");
777
773
  return !IdCompressor.isClusterInfo(compressionMapping) &&
778
774
  !IdCompressor.isUnfinalizedOverride(compressionMapping) &&
779
775
  compressionMapping.associatedLocalId === id
@@ -781,9 +777,10 @@ class IdCompressor {
781
777
  : id;
782
778
  }
783
779
  const possibleFinal = this.sessionIdNormalizer.getFinalId(id);
784
- return (_b = possibleFinal === null || possibleFinal === void 0 ? void 0 : possibleFinal[0]) !== null && _b !== void 0 ? _b : id;
780
+ return possibleFinal?.[0] ?? id;
785
781
  }
786
- const [correspondingFinal, cluster] = (_c = this.sessionIdNormalizer.getFinalId(id)) !== null && _c !== void 0 ? _c : (0, utils_1.fail)("Locally created cluster should be added to the map when allocated");
782
+ const [correspondingFinal, cluster] = this.sessionIdNormalizer.getFinalId(id) ??
783
+ (0, utils_1.fail)("Locally created cluster should be added to the map when allocated");
787
784
  if (cluster.overrides) {
788
785
  const override = cluster.overrides.get(correspondingFinal);
789
786
  if (typeof override === "object" && override.originalOverridingFinal !== undefined) {
@@ -794,7 +791,6 @@ class IdCompressor {
794
791
  return correspondingFinal;
795
792
  }
796
793
  normalizeToSessionSpace(id, sessionIdIfLocal) {
797
- var _a, _b, _c, _d;
798
794
  if (isLocalId(id)) {
799
795
  if (sessionIdIfLocal === undefined || sessionIdIfLocal === this.localSessionId) {
800
796
  const localIndex = -id;
@@ -804,10 +800,12 @@ class IdCompressor {
804
800
  return id;
805
801
  }
806
802
  else {
807
- const session = (_a = this.sessions.get(sessionIdIfLocal)) !== null && _a !== void 0 ? _a : (0, utils_1.fail)("No IDs have ever been finalized by the supplied session.");
803
+ const session = this.sessions.get(sessionIdIfLocal) ??
804
+ (0, utils_1.fail)("No IDs have ever been finalized by the supplied session.");
808
805
  const localCount = -id;
809
806
  const numericUuid = (0, numericUuid_1.incrementUuid)(session.sessionUuid, localCount - 1);
810
- return ((_b = this.compressNumericUuid(numericUuid)) !== null && _b !== void 0 ? _b : (0, utils_1.fail)("ID is not known to this compressor."));
807
+ return (this.compressNumericUuid(numericUuid) ??
808
+ (0, utils_1.fail)("ID is not known to this compressor."));
811
809
  }
812
810
  }
813
811
  const normalizedId = this.sessionIdNormalizer.getSessionSpaceId(id);
@@ -816,8 +814,9 @@ class IdCompressor {
816
814
  }
817
815
  // Check for a unified override finalized first by another session but to which the local session
818
816
  // still has an associated local ID.
819
- const [_, cluster] = (_c = this.getClusterForFinalId(id)) !== null && _c !== void 0 ? _c : (0, utils_1.fail)("Supplied final ID was not finalized by this compressor.");
820
- const override = (_d = cluster.overrides) === null || _d === void 0 ? void 0 : _d.get(id);
817
+ const [_, cluster] = this.getClusterForFinalId(id) ??
818
+ (0, utils_1.fail)("Supplied final ID was not finalized by this compressor.");
819
+ const override = cluster.overrides?.get(id);
821
820
  if (typeof override === "object" && override.associatedLocalId !== undefined) {
822
821
  return override.associatedLocalId;
823
822
  }
@@ -986,7 +985,6 @@ class IdCompressor {
986
985
  return true;
987
986
  }
988
987
  static idClustersEqual(a, b, checkSessionData = true, compareLocalState = true) {
989
- var _a, _b;
990
988
  const areEqual = (0, numericUuid_1.numericUuidEquals)(a.baseUuid, b.baseUuid) &&
991
989
  a.capacity === b.capacity &&
992
990
  a.count === b.count &&
@@ -994,7 +992,7 @@ class IdCompressor {
994
992
  IdCompressor.sessionDataEqual(a.session, b.session, false, compareLocalState)) &&
995
993
  (a.overrides === undefined) === (b.overrides === undefined) &&
996
994
  (a.overrides === undefined ||
997
- (0, utils_1.compareMaps)((_a = a.overrides) !== null && _a !== void 0 ? _a : (0, utils_1.fail)("Overrides must be defined"), (_b = b.overrides) !== null && _b !== void 0 ? _b : (0, utils_1.fail)("Overrides must be defined"), (overrideA, overrideB) => {
995
+ (0, utils_1.compareMaps)(a.overrides ?? (0, utils_1.fail)("Overrides must be defined"), b.overrides ?? (0, utils_1.fail)("Overrides must be defined"), (overrideA, overrideB) => {
998
996
  if (compareLocalState) {
999
997
  if (typeof overrideA === "string" || typeof overrideB === "string") {
1000
998
  return overrideA === overrideB;
@@ -1018,7 +1016,6 @@ class IdCompressor {
1018
1016
  return areEqual;
1019
1017
  }
1020
1018
  serialize(withSession) {
1021
- var _a, _b;
1022
1019
  const serializedSessions = [];
1023
1020
  const sessionIdToSessionIndex = new Map();
1024
1021
  for (const [sessionId, session] of this.sessions) {
@@ -1036,7 +1033,8 @@ class IdCompressor {
1036
1033
  for (const [baseFinalId, cluster] of this.finalIdToCluster.entries()) {
1037
1034
  const sessionId = (0, numericUuid_1.stableIdFromNumericUuid)(cluster.session.sessionUuid);
1038
1035
  if (sessionId !== reservedSessionId) {
1039
- const sessionIndex = (_a = sessionIdToSessionIndex.get(sessionId)) !== null && _a !== void 0 ? _a : (0, utils_1.fail)("Session object contains wrong session numeric UUID");
1036
+ const sessionIndex = sessionIdToSessionIndex.get(sessionId) ??
1037
+ (0, utils_1.fail)("Session object contains wrong session numeric UUID");
1040
1038
  const serializedCluster = [
1041
1039
  sessionIndex,
1042
1040
  cluster.capacity,
@@ -1088,7 +1086,7 @@ class IdCompressor {
1088
1086
  }
1089
1087
  return serializedWithSession;
1090
1088
  }
1091
- (_b = this.logger) === null || _b === void 0 ? void 0 : _b.sendTelemetryEvent({
1089
+ this.logger?.sendTelemetryEvent({
1092
1090
  eventName: "RuntimeIdCompressor:SerializedIdCompressorSize",
1093
1091
  size: JSON.stringify(serializedIdCompressor).length,
1094
1092
  clusterCount: serializedIdCompressor.clusters.length,
@@ -1149,7 +1147,7 @@ class IdCompressor {
1149
1147
  baseUuid: (0, numericUuid_1.incrementUuid)(sessionUuid, currentIdCount),
1150
1148
  session,
1151
1149
  };
1152
- const lastFinalizedNormalized = lastFinalizedLocalId !== null && lastFinalizedLocalId !== void 0 ? lastFinalizedLocalId : 0;
1150
+ const lastFinalizedNormalized = lastFinalizedLocalId ?? 0;
1153
1151
  const clusterBase = compressor.nextClusterBaseFinalId;
1154
1152
  session.lastFinalizedLocalId = (lastFinalizedNormalized - count);
1155
1153
  session.currentClusterDetails = { clusterBase, cluster };
@@ -1203,8 +1201,8 @@ class IdCompressor {
1203
1201
  }
1204
1202
  if (serializedLocalState !== undefined) {
1205
1203
  compressor.sessionIdNormalizer = sessionIdNormalizer_1.SessionIdNormalizer.deserialize(serializedLocalState.sessionNormalizer, (finalId) => {
1206
- var _a;
1207
- const [_, cluster] = (_a = compressor.finalIdToCluster.getPairOrNextLower(finalId)) !== null && _a !== void 0 ? _a : (0, utils_1.fail)("Final in serialized normalizer was never created.");
1204
+ const [_, cluster] = compressor.finalIdToCluster.getPairOrNextLower(finalId) ??
1205
+ (0, utils_1.fail)("Final in serialized normalizer was never created.");
1208
1206
  return cluster;
1209
1207
  });
1210
1208
  }