@fluid-experimental/tree 2.74.0 → 2.81.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 (116) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/assertTagging.config.mjs +14 -0
  3. package/dist/Checkout.js.map +1 -1
  4. package/dist/Common.d.ts.map +1 -1
  5. package/dist/Common.js.map +1 -1
  6. package/dist/MergeHealth.d.ts.map +1 -1
  7. package/dist/MergeHealth.js.map +1 -1
  8. package/dist/SharedTree.js.map +1 -1
  9. package/dist/SharedTreeEncoder.d.ts.map +1 -1
  10. package/dist/SharedTreeEncoder.js.map +1 -1
  11. package/dist/UndoRedoHandler.d.ts.map +1 -1
  12. package/dist/UndoRedoHandler.js.map +1 -1
  13. package/dist/id-compressor/IdCompressor.js.map +1 -1
  14. package/dist/id-compressor/SessionIdNormalizer.js.map +1 -1
  15. package/dist/migration-shim/migrationDeltaHandler.d.ts +2 -2
  16. package/dist/migration-shim/migrationDeltaHandler.d.ts.map +1 -1
  17. package/dist/migration-shim/migrationDeltaHandler.js.map +1 -1
  18. package/dist/migration-shim/migrationShim.d.ts +5 -5
  19. package/dist/migration-shim/migrationShim.d.ts.map +1 -1
  20. package/dist/migration-shim/migrationShim.js +1 -0
  21. package/dist/migration-shim/migrationShim.js.map +1 -1
  22. package/dist/migration-shim/migrationShimFactory.d.ts +3 -3
  23. package/dist/migration-shim/migrationShimFactory.d.ts.map +1 -1
  24. package/dist/migration-shim/migrationShimFactory.js.map +1 -1
  25. package/dist/migration-shim/sharedTreeDeltaHandler.d.ts +2 -2
  26. package/dist/migration-shim/sharedTreeDeltaHandler.d.ts.map +1 -1
  27. package/dist/migration-shim/sharedTreeDeltaHandler.js.map +1 -1
  28. package/dist/migration-shim/sharedTreeShim.d.ts +5 -5
  29. package/dist/migration-shim/sharedTreeShim.d.ts.map +1 -1
  30. package/dist/migration-shim/sharedTreeShim.js.map +1 -1
  31. package/dist/migration-shim/sharedTreeShimFactory.d.ts +1 -1
  32. package/dist/migration-shim/sharedTreeShimFactory.d.ts.map +1 -1
  33. package/dist/migration-shim/sharedTreeShimFactory.js.map +1 -1
  34. package/dist/migration-shim/shimChannelServices.d.ts +1 -1
  35. package/dist/migration-shim/shimChannelServices.d.ts.map +1 -1
  36. package/dist/migration-shim/shimChannelServices.js.map +1 -1
  37. package/dist/migration-shim/shimDeltaConnection.d.ts +2 -2
  38. package/dist/migration-shim/shimDeltaConnection.d.ts.map +1 -1
  39. package/dist/migration-shim/shimDeltaConnection.js.map +1 -1
  40. package/dist/migration-shim/shimHandle.d.ts +1 -1
  41. package/dist/migration-shim/shimHandle.d.ts.map +1 -1
  42. package/dist/migration-shim/shimHandle.js.map +1 -1
  43. package/dist/migration-shim/types.d.ts +4 -4
  44. package/dist/migration-shim/types.d.ts.map +1 -1
  45. package/dist/migration-shim/types.js.map +1 -1
  46. package/dist/migration-shim/utils.d.ts +3 -3
  47. package/dist/migration-shim/utils.d.ts.map +1 -1
  48. package/dist/migration-shim/utils.js.map +1 -1
  49. package/eslint.config.mts +5 -4
  50. package/lib/Checkout.js.map +1 -1
  51. package/lib/Common.d.ts.map +1 -1
  52. package/lib/Common.js.map +1 -1
  53. package/lib/MergeHealth.d.ts.map +1 -1
  54. package/lib/MergeHealth.js.map +1 -1
  55. package/lib/SharedTree.js.map +1 -1
  56. package/lib/SharedTreeEncoder.d.ts.map +1 -1
  57. package/lib/SharedTreeEncoder.js.map +1 -1
  58. package/lib/UndoRedoHandler.d.ts.map +1 -1
  59. package/lib/UndoRedoHandler.js.map +1 -1
  60. package/lib/id-compressor/IdCompressor.js.map +1 -1
  61. package/lib/id-compressor/SessionIdNormalizer.js.map +1 -1
  62. package/lib/migration-shim/migrationDeltaHandler.d.ts +2 -2
  63. package/lib/migration-shim/migrationDeltaHandler.d.ts.map +1 -1
  64. package/lib/migration-shim/migrationDeltaHandler.js.map +1 -1
  65. package/lib/migration-shim/migrationShim.d.ts +5 -5
  66. package/lib/migration-shim/migrationShim.d.ts.map +1 -1
  67. package/lib/migration-shim/migrationShim.js +1 -0
  68. package/lib/migration-shim/migrationShim.js.map +1 -1
  69. package/lib/migration-shim/migrationShimFactory.d.ts +3 -3
  70. package/lib/migration-shim/migrationShimFactory.d.ts.map +1 -1
  71. package/lib/migration-shim/migrationShimFactory.js.map +1 -1
  72. package/lib/migration-shim/sharedTreeDeltaHandler.d.ts +2 -2
  73. package/lib/migration-shim/sharedTreeDeltaHandler.d.ts.map +1 -1
  74. package/lib/migration-shim/sharedTreeDeltaHandler.js.map +1 -1
  75. package/lib/migration-shim/sharedTreeShim.d.ts +5 -5
  76. package/lib/migration-shim/sharedTreeShim.d.ts.map +1 -1
  77. package/lib/migration-shim/sharedTreeShim.js.map +1 -1
  78. package/lib/migration-shim/sharedTreeShimFactory.d.ts +1 -1
  79. package/lib/migration-shim/sharedTreeShimFactory.d.ts.map +1 -1
  80. package/lib/migration-shim/sharedTreeShimFactory.js.map +1 -1
  81. package/lib/migration-shim/shimChannelServices.d.ts +1 -1
  82. package/lib/migration-shim/shimChannelServices.d.ts.map +1 -1
  83. package/lib/migration-shim/shimChannelServices.js.map +1 -1
  84. package/lib/migration-shim/shimDeltaConnection.d.ts +2 -2
  85. package/lib/migration-shim/shimDeltaConnection.d.ts.map +1 -1
  86. package/lib/migration-shim/shimDeltaConnection.js.map +1 -1
  87. package/lib/migration-shim/shimHandle.d.ts +1 -1
  88. package/lib/migration-shim/shimHandle.d.ts.map +1 -1
  89. package/lib/migration-shim/shimHandle.js.map +1 -1
  90. package/lib/migration-shim/types.d.ts +4 -4
  91. package/lib/migration-shim/types.d.ts.map +1 -1
  92. package/lib/migration-shim/types.js.map +1 -1
  93. package/lib/migration-shim/utils.d.ts +3 -3
  94. package/lib/migration-shim/utils.d.ts.map +1 -1
  95. package/lib/migration-shim/utils.js.map +1 -1
  96. package/package.json +32 -32
  97. package/src/Checkout.ts +1 -1
  98. package/src/Common.ts +5 -1
  99. package/src/MergeHealth.ts +5 -5
  100. package/src/SharedTree.ts +2 -2
  101. package/src/SharedTreeEncoder.ts +9 -2
  102. package/src/UndoRedoHandler.ts +5 -5
  103. package/src/id-compressor/IdCompressor.ts +1 -1
  104. package/src/id-compressor/SessionIdNormalizer.ts +1 -1
  105. package/src/migration-shim/migrationDeltaHandler.ts +2 -2
  106. package/src/migration-shim/migrationShim.ts +11 -13
  107. package/src/migration-shim/migrationShimFactory.ts +7 -10
  108. package/src/migration-shim/sharedTreeDeltaHandler.ts +2 -2
  109. package/src/migration-shim/sharedTreeShim.ts +14 -14
  110. package/src/migration-shim/sharedTreeShimFactory.ts +5 -5
  111. package/src/migration-shim/shimChannelServices.ts +4 -4
  112. package/src/migration-shim/shimDeltaConnection.ts +5 -5
  113. package/src/migration-shim/shimHandle.ts +1 -1
  114. package/src/migration-shim/types.ts +8 -8
  115. package/src/migration-shim/utils.ts +3 -3
  116. package/.eslintrc.cjs +0 -45
@@ -1 +1 @@
1
- {"version":3,"file":"IdCompressor.js","sourceRoot":"","sources":["../../src/id-compressor/IdCompressor.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 { ITelemetryBaseLogger } from '@fluidframework/core-interfaces';\nimport { assert } from '@fluidframework/core-utils/internal';\nimport { ITelemetryLoggerExt, createChildLogger } from '@fluidframework/telemetry-utils/internal';\nimport { BTree } from '@tylerbu/sorted-btree-es6';\n\nimport {\n\tMutable,\n\tassertNotUndefined,\n\tassertWithMessage,\n\tcompareFiniteNumbers,\n\tcompareFiniteNumbersReversed,\n\tcompareMaps,\n\tcompareStrings,\n\tfail,\n\tgetOrCreate,\n\thasLength,\n\tsetPropertyIfDefined,\n} from '../Common.js';\nimport {\n\tAttributionId,\n\tCompressedId,\n\tFinalCompressedId,\n\tLocalCompressedId,\n\tOpSpaceCompressedId,\n\tSessionId,\n\tSessionSpaceCompressedId,\n\tStableId,\n\tUuidString,\n} from '../Identifiers.js';\nimport { assertIsStableId, assertIsUuidString, isStableId } from '../UuidUtilities.js';\n\nimport { AppendOnlySortedMap } from './AppendOnlySortedMap.js';\nimport { getIds } from './IdRange.js';\nimport {\n\tNumericUuid,\n\tensureSessionUuid,\n\tgetPositiveDelta,\n\tincrementUuid,\n\tnumericUuidEquals,\n\tnumericUuidFromStableId,\n\tstableIdFromNumericUuid,\n} from './NumericUuid.js';\nimport { SessionIdNormalizer } from './SessionIdNormalizer.js';\nimport type {\n\tIdCreationRange,\n\tSerializedCluster,\n\tSerializedClusterOverrides,\n\tSerializedIdCompressor,\n\tSerializedIdCompressorWithNoSession,\n\tSerializedIdCompressorWithOngoingSession,\n\tSerializedLocalState,\n\tSerializedSessionData,\n\tUnackedLocalId,\n\tVersionedSerializedIdCompressor,\n} from './persisted-types/index.js';\n\n/**\n * A cluster of final (sequenced via consensus), sequentially allocated compressed IDs.\n * A final ID in a cluster decompresses to a UUID that is one of the following:\n * 1. A sequentially allocated UUID that is the result of adding its offset within the cluster to `baseUuid`.\n * 2. An override string (stored in `overrides`) specified at allocation time.\n */\ninterface IdCluster {\n\t/**\n\t * The UUID corresponding to the first final ID in the cluster.\n\t */\n\treadonly baseUuid: NumericUuid;\n\n\t/**\n\t * The total number of final IDs reserved for allocation in the cluster.\n\t * Clusters are reserved in blocks as a performance optimization.\n\t */\n\tcapacity: number;\n\n\t/**\n\t * The number of final IDs currently allocated in the cluster.\n\t */\n\tcount: number;\n\n\t/**\n\t * The session in which this cluster was created\n\t */\n\treadonly session: Session;\n\n\t/**\n\t * Final IDs assigned override strings within this cluster.\n\t * These are one of the following:\n\t *\n\t * 1. The override string\n\t *\n\t * 2. The override string and external override details. This occurs when local IDs corresponding to the same\n\t * override string are created by different sessions before any have been finalized. This can occur due to\n\t * concurrency or offline. In this case, the string is stored for the final ID that got sequenced first, and that\n\t * final ID is stored associated with all subsequent final IDs with the same override.\n\t *\n\t * When a final ID which is safely reserved via consensus as part of a cluster (but is not yet sequenced) is\n\t * allocated with an override, this collection will be temporarily inaccurate as it will not contain an entry for\n\t * that final ID. This absence indicates the uncertainty about what the final ID associated with that override will\n\t * be after finalizing the range (which could change due to unification of a concurrent duplicate override).\n\t * This table will be adjusted to reflect the override when that final ID is finalized via consensus, and\n\t * decompression will use `clustersAndOverridesInversion` until that point.\n\t */\n\toverrides?: Map<FinalCompressedId, string | UnifiedOverride>;\n}\n\ntype UnifiedOverride = OverrideCompressionDetails & {\n\toverride: string;\n};\n\n/**\n * Data about a SharedTree session.\n * Used to track and allocate identity clusters associated with a particular session ID.\n */\ninterface Session {\n\treadonly sessionUuid: NumericUuid;\n\n\t/**\n\t * `cluster` is undefined if a new cluster must be allocated when the session requests the next final ID allocation.\n\t */\n\tcurrentClusterDetails: { readonly clusterBase: FinalCompressedId; readonly cluster: IdCluster } | undefined;\n\n\t/**\n\t * The last local ID known to be finalized for this session.\n\t */\n\tlastFinalizedLocalId: LocalCompressedId | undefined;\n\n\t/**\n\t * The attribution ID for the session\n\t */\n\treadonly attributionId: AttributionId;\n}\n\n/**\n * Roughly equates to a minimum of 1M sessions before we start allocating 64 bit IDs.\n * This value must *NOT* change without careful consideration to compatibility.\n */\nexport const defaultClusterCapacity = 512;\n\n/**\n * The base UUID for the reserved id cluster.\n * This should not be changed without consideration to compatibility.\n */\nconst reservedSessionId = ensureSessionUuid(assertIsStableId('decaf40b-3c1a-47f8-a7a1-e8461ddb69ce'));\n\n/**\n * The ID override for the initial tree of a SharedTree. An artifact of an unfortunate typo which included an extraneous '6' on the UUID\n * which must be forever preserved for backwards compatibility.\n */\nexport const legacySharedTreeInitialTreeId = `24e26f0b-3c1a-47f8-a7a1-e8461ddb69ce6`;\n\n/**\n * @returns true if the supplied ID is a final ID.\n */\nexport function isFinalId(id: CompressedId): id is FinalCompressedId {\n\treturn id >= 0;\n}\n\n/**\n * @returns true if the supplied ID is a local ID.\n */\nexport function isLocalId(id: CompressedId): id is LocalCompressedId {\n\treturn id < 0;\n}\n\n/**\n * A cluster in `clustersAndOverridesInversion`, which is mapped from the first stable ID in a cluster.\n */\ninterface ClusterInfo {\n\treadonly clusterBase: FinalCompressedId;\n\treadonly cluster: IdCluster;\n}\n\ninterface OverrideCompressionDetails {\n\treadonly originalOverridingFinal: FinalCompressedId;\n\treadonly associatedLocalId?: LocalCompressedId;\n}\n\n/**\n * An override with a final ID associated with it.\n *\n * `associatedLocalId` is present on this type when a local ID in this session is associated with the override.\n *\n * It may be present even when `overriddenFinalId` was created by another session. This occurs when local IDs corresponding to the\n * same override string are created by different sessions before any have been finalized. `overriddenFinalId` will be set to\n * the *first* finalized ID with that string, but `associatedLocal` will be set to the local session's local ID for that string. This is\n * done to preserve the invariant that an override will always compress into the same session-space ID for the lifetime of the session.\n */\ninterface FinalizedOverride extends OverrideCompressionDetails {\n\treadonly cluster: IdCluster;\n}\n\n/**\n * The value of a mapping in `clustersAndOverridesInversion`, which maps an override to the cluster containing it (if finalized) or the\n * local ID corresponding to it (if unfinalized).\n *\n * Override strings associated with local IDs stored in `clustersAndOverridesInversion` are *always* replaced immediately upon finalizing,\n * and thus it is typed as op-space (unacked local).\n */\ntype Override = UnackedLocalId | FinalizedOverride;\n\ntype CompressionMapping = ClusterInfo | Override;\n\n/** Prepended to all keys in {@link IdCompressor.clustersAndOverridesInversion} that are override strings and not valid `StableIds` */\nconst nonStableOverridePrefix = '\\ue15e'; // A character in the Private Use Area of the BMP (https://en.wikipedia.org/wiki/Private_Use_Areas)\n\n/** Keys of {@link IdCompressor.clustersAndOverridesInversion} */\ntype InversionKey = `${typeof nonStableOverridePrefix}${string}` | StableId;\n\n/**\n * A distributed UUID generator and compressor.\n *\n * Generates arbitrary non-colliding v4 UUIDs, called stable IDs, for multiple \"sessions\" (which can be distributed across the network),\n * providing each session with the ability to map these UUIDs to `numbers`.\n *\n * A session is a unique identifier that denotes a single compressor. New IDs are created through a single compressor API\n * which should then sent in ranges to the server for total ordering (and are subsequently relayed to other clients). When a new ID is\n * created it is said to be created by the compressor's \"local\" session.\n *\n * For each stable ID created, two numeric IDs are provided by the compressor:\n *\n * 1. A local ID, which is stable for the lifetime of the session (which could be longer than that of the compressor object, as it may\n * be serialized for offline usage). Available as soon as the stable ID is allocated. Local IDs are session-unique and are thus only\n * publicly usable by the compressor that created the stable ID.\n *\n * 2. A final ID, which is stable across serialization and deserialization of an IdCompressor. Available as soon as the range containing\n * the corresponding local ID is totally ordered (via consensus) with respect to other sessions' allocations.\n * Final IDs are known to and publicly usable by any compressor that has received them.\n *\n * Compressors will allocate UUIDs in non-random ways to reduce entropy allowing for optimized storage of the data needed\n * to map the UUIDs to the numbers.\n *\n * A client may optionally supply an \"override\" for any generated ID, associating an arbitrary string with the local/final ID rather than\n * the UUID that would otherwise be created.\n *\n * The following invariants are upheld by IdCompressor:\n *\n * 1. Local IDs will always decompress to the same UUIDs (or override string) for the lifetime of the session.\n *\n * 2. Final IDs will always decompress to the same UUIDs (or override string).\n *\n * 3. After a server-processed range of local IDs (from any session) is received by a compressor, any of those local IDs may be\n * translated by the compressor into the corresponding final ID. For any given local ID, this translation will always yield the\n * same final ID.\n *\n * 4. A UUID (or override string) will always compress into the same session-space ID for the lifetime of the session.\n *\n * Local IDs are sent across the wire in efficiently-represented ranges. These ranges are created by querying the compressor, and *must*\n * be ordered (i.e. sent to the server) in the order they are created in order to preserve the above invariants.\n *\n * Session-local IDs can be used immediately after creation, but will eventually (after being sequenced) have a corresponding final ID. This\n * could make reasoning about equality of those two forms (the local and final) difficult. For example, if a cache is keyed off of a\n * local ID but is later queried using the final ID (which is semantically equal, as it decompresses to the same UUID/string) it will\n * produce a cache miss. In order to make using collections of both remotely created and locally created IDs easy, regardless of whether the\n * session-local IDs have been finalized, the compressor defines two \"spaces\" of IDs:\n *\n * 1. Session space: in this space, all IDs are normalized to their \"most local form\". This means that all IDs created by the local session\n * will be in local form, regardless of if they have been finalized. Remotely created IDs, which could only have been received after\n * finalizing and will never have a local form for the compressor, will of course be final IDs. This space should be used with consumer APIs\n * and data structures, as the lifetime of the IDs is guaranteed to be the same as the compressor object. Care must be taken to not use\n * these IDs across compressor objects, as the local IDs are specific to the compressor that created them.\n *\n * 2. Op space: in this space, all IDs are normalized to their \"most final form\". This means that all IDs except session-local IDs that\n * have not yet been finalized will be in final ID form. This space is useful for serialization in ops (e.g. references), as other clients\n * that receive them need not do any work to normalize them to *their* session-space in the common case. Note that IDs in op space may move\n * out of Op space over time, namely, when a local ID in this space becomes finalized, and thereafter has a \"more final form\".\n * Consequentially, it may be useful to restrict parameters of a persisted type to this space (to optimize perf), but it is potentially\n * incorrect to use this type for a runtime variable. This is an asymmetry that does not affect session space, as local IDs are always as\n * \"local as possible\".\n *\n * These two spaces naturally define a rule: consumers of compressed IDs should use session-space IDs, but serialized forms such as ops\n * should use op-space IDs.\n *\n */\nexport class IdCompressor {\n\t/**\n\t * Max allowed cluster size\n\t */\n\tpublic static maxClusterSize = 2 ** 20;\n\n\t/**\n\t * Trivially reach consensus on default cluster size and reserved IDs.\n\t * These initial values must *NOT* change without careful consideration to compatibility.\n\t */\n\tprivate newClusterCapacity = defaultClusterCapacity;\n\n\t/**\n\t * The size of each newly created ID cluster.\n\t */\n\tpublic get clusterCapacity(): number {\n\t\treturn this.newClusterCapacity;\n\t}\n\n\t/**\n\t * Must only be set with a value upon which consensus has been reached. Value must be greater than zero and less than\n\t * `IdCompressor.maxClusterSize`.\n\t */\n\tpublic set clusterCapacity(value: number) {\n\t\tassert(value > 0, 0x640 /* Clusters must have a positive capacity */);\n\t\tassert(value <= IdCompressor.maxClusterSize, 0x641 /* Clusters must not exceed max cluster size */);\n\t\tthis.newClusterCapacity = value;\n\t}\n\n\t/**\n\t * The UUID used for attribution of identities created by this compressor\n\t */\n\tpublic get attributionId(): AttributionId {\n\t\treturn this.localSession.attributionId;\n\t}\n\n\t/**\n\t * Session ID -\\> data about the session's current cluster.\n\t * Sessions are mutable, and thus should only be created via `createSession`.\n\t */\n\tprivate readonly sessions = new Map<SessionId, Session>();\n\n\t/**\n\t * The `IdCompressor`'s current local session.\n\t */\n\tprivate readonly localSession: Session;\n\n\t/**\n\t * The base final ID of the next cluster to be created.\n\t */\n\tprivate nextClusterBaseFinalId: FinalCompressedId = 0 as FinalCompressedId;\n\n\t/**\n\t * Total number of IDs created locally during the current session.\n\t */\n\tprivate localIdCount = 0;\n\n\t/**\n\t * The most recent (i.e. smallest, due to being negative) local ID in a range returned by `takeNextCreationRange`.\n\t * Undefined if no non-empty ranges have ever been returned by this compressor.\n\t */\n\tprivate lastTakenLocalId: LocalCompressedId | undefined;\n\n\t/**\n\t * Maps local IDs to override strings. This will contain an entry for every override assigned to a local ID generated during\n\t * the current session, and retains entries for the lifetime of this compressor.\n\t */\n\tprivate readonly localOverrides = new AppendOnlySortedMap<LocalCompressedId, string>(compareFiniteNumbersReversed);\n\n\t/**\n\t * Maps local IDs to the final ID they are associated with (if any), and maps final IDs to the corresponding local ID (if any).\n\t * This is used to efficiently compute normalization. This map can be thought of as mapping ranges of \"optimistic uncertainty\"\n\t * (local IDs) to the result of consensus (reserved ranges of final IDs, a.k.a. clusters). Any given range of local IDs\n\t * does not necessarily span an entire cluster, as some session-space IDs may be allocated *after* a cluster has been allocated\n\t * but before it is full. In this case, there is no uncertainty, as the range of final IDs was reserved when the cluster was created.\n\t * However, there is always a range of local IDs with size \\>= 1 associated with the beginning of every cluster, as clusters are only\n\t * created *after* they are needed and thus there is some period of uncertainty after local IDs have been handed out but before the\n\t * range containing them has been finalized. There may also be ranges of local IDs that do not start at the beginning of a\n\t * cluster; this happens when a cluster is expanded instead of allocating a new one.\n\t * Additionally, session space IDs associated with an override string will also always be local IDs, because there is uncertainty as\n\t * to whether another client simultaneously allocated the same override and could get sequenced first (a.k.a. unification) and its\n\t * final ID would be associated with that override.\n\t * See `SessionIdNormalizer` for more.\n\t */\n\tprivate sessionIdNormalizer = new SessionIdNormalizer<IdCluster>();\n\n\t/**\n\t * Contains entries for cluster base UUIDs and override strings (both local and final).\n\t * As a performance optimization, entries for finalized strings also include the containing cluster object.\n\t * This can be viewed as three separate tables: the inverse table for `localOverrides`, the inverse table for the union of all\n\t * the overrides of the clusters in `finalIdToCluster`, and the inverse lookup of cluster base UUIDs to their clusters.\n\t * This is unified as a performance optimization, as the common case does not have overridden IDs. It is a btree due to the need\n\t * to make range queries.\n\t */\n\tprivate readonly clustersAndOverridesInversion: BTree<InversionKey, CompressionMapping> = new BTree(\n\t\tundefined,\n\t\tcompareStrings\n\t);\n\n\t/**\n\t * Maps the first final ID in a cluster to its owning cluster.\n\t * Can be searched in O(log n) to determine clusters for any final ID.\n\t */\n\tprivate readonly finalIdToCluster: AppendOnlySortedMap<FinalCompressedId, IdCluster> = new AppendOnlySortedMap(\n\t\tcompareFiniteNumbers\n\t);\n\n\tprivate readonly logger: ITelemetryLoggerExt;\n\n\t/**\n\t * @param localSessionId - the `IdCompressor`'s current local session ID.\n\t * @param reservedIdCount - the number of IDs that will be known by this compressor without relying on consensus.\n\t * The reserved ID count for a given session must be constant for any compressor that contains IDs from that session\n\t * (i.e. any DDS that uses the ID compressor must have the same reservedIdCount forever). Compressors with different\n\t * reserved ID counts will fail to synchronize their IDs.\n\t * @param attributionId - a UUID that identifies the user of this instance of the compressor. IDs created by this\n\t * compressor will be associated with this UUID and can be queried later via `attributeID`. If no UUID is provided,\n\t * this compressor will generate its own. An `AttributionId` is an `UuidString` which may be validated via\n\t * {@link isUuidString} or generated via {@link generateStableId}.\n\t */\n\tpublic constructor(\n\t\tpublic readonly localSessionId: SessionId,\n\t\tpublic readonly reservedIdCount: number,\n\t\tattributionId?: AttributionId,\n\t\tlogger?: ITelemetryBaseLogger\n\t) {\n\t\tassert(reservedIdCount >= 0, 0x642 /* reservedIdCount must be non-negative */);\n\t\tif (attributionId !== undefined) {\n\t\t\tassertIsUuidString(attributionId);\n\t\t}\n\t\tthis.localSession = this.createSession(localSessionId, attributionId);\n\t\tif (reservedIdCount > 0) {\n\t\t\tconst clusterCapacity = this.clusterCapacity;\n\t\t\tthis.clusterCapacity = reservedIdCount;\n\t\t\tconst reservedIdRange: IdCreationRange = {\n\t\t\t\tsessionId: reservedSessionId,\n\t\t\t\tids: {\n\t\t\t\t\tlast: -reservedIdCount as UnackedLocalId,\n\t\t\t\t\toverrides: [[-1 as UnackedLocalId, legacySharedTreeInitialTreeId]], // Kludge: see `initialTreeId`\n\t\t\t\t},\n\t\t\t};\n\t\t\t// Reserved final IDs are implicitly finalized and no one locally created them, so finalizing immediately is safe.\n\t\t\tthis.finalizeCreationRange(reservedIdRange);\n\t\t\tthis.clusterCapacity = clusterCapacity;\n\t\t}\n\n\t\tthis.logger = createChildLogger({ logger });\n\t}\n\n\t/**\n\t * Creates a session object for the supplied ID.\n\t * Must only be called once per ID.\n\t * @param sessionId - the ID for the session\n\t * @returns the session object for the supplied ID\n\t */\n\tprivate createSession(sessionId: SessionId, attributionId: AttributionId | undefined): Session {\n\t\tassertWithMessage(!this.clustersAndOverridesInversion.has(sessionId));\n\t\tconst existingSession = this.sessions.get(sessionId);\n\t\tif (existingSession !== undefined) {\n\t\t\tfail('createSession must only be called once for each session ID.');\n\t\t}\n\t\tconst sessionUuid = numericUuidFromStableId(sessionId);\n\t\tconst session: Session = {\n\t\t\tsessionUuid,\n\t\t\tcurrentClusterDetails: undefined,\n\t\t\tlastFinalizedLocalId: undefined,\n\t\t\tattributionId: attributionId ?? sessionId,\n\t\t};\n\t\tthis.sessions.set(sessionId, session);\n\t\treturn session;\n\t}\n\n\t/**\n\t * Return the nth reserved ID.\n\t * @param index - the index of the ID to return\n\t */\n\tpublic getReservedId(index: number): SessionSpaceCompressedId & FinalCompressedId {\n\t\tif (index < 0 || index >= this.reservedIdCount) {\n\t\t\tfail('Reserved Id index out of bounds');\n\t\t}\n\n\t\t// All reserved IDs are contiguous and finalized during the Compressor's construction, therefore they are always the lowest\n\t\t// final IDs, beginning at 0\n\t\treturn index as SessionSpaceCompressedId & FinalCompressedId;\n\t}\n\n\t/**\n\t * Returns an iterable of all IDs created by this compressor.\n\t */\n\tpublic getAllIdsFromLocalSession(): IterableIterator<SessionSpaceCompressedId> {\n\t\treturn this.sessionIdNormalizer[Symbol.iterator]();\n\t}\n\n\t/**\n\t * Returns the attribution ID associated with the compressor that created the ID\n\t */\n\tpublic attributeId(id: SessionSpaceCompressedId): AttributionId {\n\t\tconst opSpaceNormalizedId = this.normalizeToOpSpace(id);\n\t\tif (isLocalId(opSpaceNormalizedId)) {\n\t\t\treturn this.attributionId;\n\t\t}\n\t\tconst closestCluster = this.getClusterForFinalId(opSpaceNormalizedId);\n\t\tif (closestCluster === undefined) {\n\t\t\tif (this.sessionIdNormalizer.getCreationIndex(opSpaceNormalizedId) !== undefined) {\n\t\t\t\treturn this.attributionId;\n\t\t\t} else {\n\t\t\t\tfail('Cluster does not exist for final ID');\n\t\t\t}\n\t\t}\n\t\tconst [_, cluster] = closestCluster;\n\t\treturn cluster.session.attributionId;\n\t}\n\n\t/**\n\t * Returns a range of local IDs created by this session in a format for sending to the server for finalizing.\n\t * The range will include all local IDs generated via calls to `generateCompressedId` since the last time this method was called.\n\t * @returns the range of session-local IDs, which may be empty. This range must be sent to the server for ordering before\n\t * it is finalized. Ranges must be sent to the server in the order that they are taken via calls to this method.\n\t */\n\tpublic takeNextCreationRange(): IdCreationRange {\n\t\tconst lastLocalInRange = -this.localIdCount as UnackedLocalId;\n\t\tconst lastTakenNormalized = this.lastTakenLocalId ?? 0;\n\t\tassertWithMessage(lastLocalInRange <= lastTakenNormalized);\n\n\t\t// The attribution ID is sent with each range, but it can be elided after the first IDs are allocated.\n\t\tconst sendAttributionId = this.lastTakenLocalId === undefined;\n\n\t\tlet ids: IdCreationRange.Ids | undefined;\n\t\tif (lastLocalInRange !== lastTakenNormalized) {\n\t\t\tconst firstLocalInRange = (lastTakenNormalized - 1) as UnackedLocalId;\n\t\t\tconst overrides = [\n\t\t\t\t...this.localOverrides.getRange(\n\t\t\t\t\t(lastTakenNormalized - 1) as LocalCompressedId,\n\t\t\t\t\tlastLocalInRange as LocalCompressedId\n\t\t\t\t),\n\t\t\t] as (readonly [UnackedLocalId, string])[];\n\t\t\tif (hasLength(overrides, 1)) {\n\t\t\t\tassertWithMessage(overrides[0][0] <= firstLocalInRange);\n\t\t\t\tassertWithMessage(overrides[overrides.length - 1][0] >= lastLocalInRange);\n\t\t\t\tids = {\n\t\t\t\t\toverrides,\n\t\t\t\t};\n\t\t\t\tconst first = firstLocalInRange === overrides[0][0] ? undefined : firstLocalInRange;\n\t\t\t\tconst last = lastLocalInRange === overrides[overrides.length - 1][0] ? undefined : lastLocalInRange;\n\t\t\t\tsetPropertyIfDefined(first, ids, 'first');\n\t\t\t\tsetPropertyIfDefined(last, ids, 'last');\n\t\t\t} else {\n\t\t\t\tids = {\n\t\t\t\t\tfirst: firstLocalInRange,\n\t\t\t\t\tlast: lastLocalInRange,\n\t\t\t\t};\n\t\t\t}\n\t\t\tthis.lastTakenLocalId = lastLocalInRange;\n\t\t}\n\n\t\tconst range: Mutable<IdCreationRange> = { sessionId: this.localSessionId };\n\t\tif (this.attributionId !== this.localSessionId && sendAttributionId) {\n\t\t\trange.attributionId = this.attributionId;\n\t\t}\n\n\t\tif (ids === undefined) {\n\t\t\treturn range;\n\t\t}\n\n\t\tassert(\n\t\t\tthis.lastTakenLocalId === -this.localIdCount && this.lastTakenLocalId !== lastTakenNormalized,\n\t\t\t0x643 /* Non-empty range must properly consume local IDs */\n\t\t);\n\n\t\trange.ids = ids;\n\t\treturn range;\n\t}\n\n\t/**\n\t * Finalizes the supplied range of IDs (which may be from either a remote or local session).\n\t * @param range - the range of session-local IDs to finalize.\n\t */\n\tpublic finalizeCreationRange(range: IdCreationRange): void {\n\t\tconst { sessionId, attributionId } = range;\n\n\t\tconst isLocal = sessionId === this.localSessionId;\n\t\tconst session = this.sessions.get(sessionId) ?? this.createSession(sessionId, attributionId);\n\t\tassert(\n\t\t\trange.attributionId === undefined || range.attributionId === session.attributionId,\n\t\t\t0x644 /* A session's attribution ID may never be modified. */\n\t\t);\n\n\t\tconst ids = getIds(range);\n\t\tif (ids === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { currentClusterDetails } = session;\n\t\tconst { cluster: currentCluster, clusterBase: currentBaseFinalId } = currentClusterDetails ?? {\n\t\t\tcluster: undefined,\n\t\t\tclusterBase: undefined,\n\t\t};\n\t\tconst currentClusterExists = currentCluster !== undefined && currentBaseFinalId !== undefined;\n\n\t\tconst normalizedLastFinalizedLocal = session.lastFinalizedLocalId ?? 0;\n\t\tconst { first: newFirstFinalizedLocal, last: newLastFinalizedLocal } = ids;\n\t\tassert(newFirstFinalizedLocal === normalizedLastFinalizedLocal - 1, 0x645 /* Ranges finalized out of order. */);\n\n\t\t// The total number of session-local IDs to finalize\n\t\tconst finalizeCount = normalizedLastFinalizedLocal - newLastFinalizedLocal;\n\t\tassert(finalizeCount >= 1, 0x646 /* Cannot finalize an empty range. */);\n\n\t\tlet eagerFinalIdCount = 0;\n\t\tlet initialClusterCount = 0;\n\t\tlet remainingCount = finalizeCount;\n\t\tlet newBaseUuid: NumericUuid | undefined;\n\t\tif (currentClusterExists) {\n\t\t\tif (isLocal) {\n\t\t\t\tconst lastKnownFinal =\n\t\t\t\t\tthis.sessionIdNormalizer.getLastFinalId() ??\n\t\t\t\t\tfail('Cluster exists but normalizer does not have an entry for it.');\n\t\t\t\tconst lastAlignedFinalInCluster = (currentBaseFinalId +\n\t\t\t\t\tMath.min(currentCluster.count + finalizeCount, currentCluster.capacity) -\n\t\t\t\t\t1) as FinalCompressedId;\n\t\t\t\tif (lastAlignedFinalInCluster > lastKnownFinal) {\n\t\t\t\t\tthis.sessionIdNormalizer.addFinalIds(\n\t\t\t\t\t\t(lastKnownFinal + 1) as FinalCompressedId,\n\t\t\t\t\t\tlastAlignedFinalInCluster,\n\t\t\t\t\t\tcurrentCluster\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tinitialClusterCount = currentCluster.count;\n\t\t\tconst remainingCapacity = currentCluster.capacity - initialClusterCount;\n\t\t\tconst overflow = remainingCount - remainingCapacity;\n\t\t\tconst hasRoom = overflow <= 0;\n\t\t\tif (hasRoom || currentBaseFinalId === this.finalIdToCluster.maxKey()) {\n\t\t\t\tcurrentCluster.count += remainingCount;\n\t\t\t\teagerFinalIdCount = remainingCount;\n\t\t\t\tremainingCount = 0;\n\t\t\t\t// The common case is that there is room in the cluster, and the new final IDs can simply be added to it\n\t\t\t\tif (!hasRoom) {\n\t\t\t\t\t// The cluster is full but is the last in the list of clusters.\n\t\t\t\t\t// This allows it to be expanded instead of allocating a new one.\n\t\t\t\t\tconst expansionAmount = this.newClusterCapacity + overflow;\n\t\t\t\t\tconst previousCapacity = currentCluster.capacity;\n\t\t\t\t\tcurrentCluster.capacity += expansionAmount;\n\t\t\t\t\tthis.nextClusterBaseFinalId = (this.nextClusterBaseFinalId + expansionAmount) as FinalCompressedId;\n\t\t\t\t\tassert(\n\t\t\t\t\t\tthis.nextClusterBaseFinalId < Number.MAX_SAFE_INTEGER,\n\t\t\t\t\t\t0x647 /* The number of allocated final IDs must not exceed the JS maximum safe integer. */\n\t\t\t\t\t);\n\t\t\t\t\tthis.checkClusterForCollision(currentCluster);\n\t\t\t\t\tif (isLocal) {\n\t\t\t\t\t\t// Example with cluster size of 3:\n\t\t\t\t\t\t// Ids generated so far: -1 1 2 -4 -5 <-- note positive numbers are eager finals\n\t\t\t\t\t\t// Cluster: [ 0 1 2 ]\n\t\t\t\t\t\t// ~ finalizing happens, causing expansion of 2 (overflow) + 3 (cluster capacity) ~\n\t\t\t\t\t\t// Cluster: [ 0 1 2 3 4 _ _ _ ]\n\t\t\t\t\t\t// corresponding locals: -1 -4 -5\n\t\t\t\t\t\t// lastFinalizedLocalId^ ^newLastFinalizedLocalId = -5\n\t\t\t\t\t\t// overflow = 2: ----\n\t\t\t\t\t\t// localIdPivot^\n\t\t\t\t\t\t// lastFinalizedFinal^\n\t\t\t\t\t\tconst newLastFinalizedFinal = (currentBaseFinalId + currentCluster.count - 1) as FinalCompressedId;\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\tsession.lastFinalizedLocalId !== undefined,\n\t\t\t\t\t\t\t0x648 /* Cluster already exists for session but there is no finalized local ID */\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst finalPivot = (newLastFinalizedFinal - overflow + 1) as FinalCompressedId;\n\t\t\t\t\t\t// Inform the normalizer of all IDs that we now know will end up being finalized into this cluster, including the ones\n\t\t\t\t\t\t// that were given out as locals (non-eager) because they exceeded the bounds of the current cluster before it was expanded.\n\t\t\t\t\t\t// It is safe to associate the unfinalized locals with their future final IDs even before the ranges for those locals are\n\t\t\t\t\t\t// actually finalized, because total order broadcast guarantees that any usage of those final IDs will be observed after\n\t\t\t\t\t\t// the finalization of the ranges.\n\t\t\t\t\t\tthis.sessionIdNormalizer.registerFinalIdBlock(finalPivot, expansionAmount, currentCluster);\n\t\t\t\t\t\tthis.logger?.sendTelemetryEvent({\n\t\t\t\t\t\t\teventName: 'SharedTreeIdCompressor:ClusterExpansion',\n\t\t\t\t\t\t\tsessionId: this.localSessionId,\n\t\t\t\t\t\t\tpreviousCapacity,\n\t\t\t\t\t\t\tnewCapacity: currentCluster.capacity,\n\t\t\t\t\t\t\toverflow,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// The range cannot be fully allocated in the existing cluster, so allocate any space left in it and\n\t\t\t\t// form a new one by incrementing the previous baseUuid\n\t\t\t\tnewBaseUuid = incrementUuid(currentCluster.baseUuid, currentCluster.capacity);\n\t\t\t\tcurrentCluster.count += remainingCapacity;\n\t\t\t\teagerFinalIdCount = remainingCapacity;\n\t\t\t\tremainingCount -= remainingCapacity;\n\t\t\t\tthis.logger?.sendTelemetryEvent({\n\t\t\t\t\teventName: 'SharedTreeIdCompressor:OverfilledCluster',\n\t\t\t\t\tsessionId: this.localSessionId,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\t// Session has never made a cluster, form a new one with the session UUID as the baseUuid\n\t\t\tnewBaseUuid = session.sessionUuid;\n\t\t\tif (isLocal) {\n\t\t\t\tthis.logger?.sendTelemetryEvent({\n\t\t\t\t\teventName: 'SharedTreeIdCompressor:FirstCluster',\n\t\t\t\t\tsessionId: this.localSessionId,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Finalizing a range results in one of three cases:\n\t\t// 1. All local IDs are finalized into a new cluster (because there was either never a cluster for that session, or the current\n\t\t//\t\tcluster for the session was full).\n\t\t// 2. All local IDs are finalized into the existing (current) cluster for the session.\n\t\t// 3. Local IDs are finalized into both the current cluster and a new one, as the current cluster did not have enough room.\n\t\tlet newCluster: IdCluster | undefined;\n\t\tlet newBaseFinalId: FinalCompressedId | undefined;\n\t\t// The first local ID that will be finalized into a new cluster, if there is one.\n\t\t// This lets us quickly compare which cluster an override string will go into.\n\t\tlet localIdPivot: LocalCompressedId | undefined;\n\n\t\t// Need to make a new cluster\n\t\tif (newBaseUuid !== undefined) {\n\t\t\tif (remainingCount <= 0) {\n\t\t\t\tfail('Should not create an empty cluster.');\n\t\t\t}\n\t\t\tif (currentCluster !== undefined && currentCluster.capacity !== currentCluster.count) {\n\t\t\t\tfail('Cluster must be filled before another is allocated.');\n\t\t\t}\n\n\t\t\tnewBaseFinalId = this.nextClusterBaseFinalId;\n\t\t\tconst newCapacity = Math.max(this.newClusterCapacity, remainingCount);\n\t\t\tnewCluster = {\n\t\t\t\tbaseUuid: newBaseUuid,\n\t\t\t\tcapacity: newCapacity,\n\t\t\t\tcount: remainingCount,\n\t\t\t\tsession,\n\t\t\t};\n\n\t\t\tconst usedCapacity = finalizeCount - remainingCount;\n\t\t\tlocalIdPivot = (newFirstFinalizedLocal - usedCapacity) as LocalCompressedId;\n\n\t\t\tif (isLocal) {\n\t\t\t\tthis.logger?.sendTelemetryEvent({\n\t\t\t\t\teventName: 'SharedTreeIdCompressor:NewCluster',\n\t\t\t\t\tsessionId: this.localSessionId,\n\t\t\t\t\tclusterCapacity: newCapacity,\n\t\t\t\t\tclusterCount: remainingCount,\n\t\t\t\t});\n\t\t\t\tthis.sessionIdNormalizer.registerFinalIdBlock(newBaseFinalId, newCluster.capacity, newCluster);\n\t\t\t}\n\n\t\t\tthis.checkClusterForCollision(newCluster);\n\t\t\tthis.clustersAndOverridesInversion.set(stableIdFromNumericUuid(newCluster.baseUuid), {\n\t\t\t\tclusterBase: newBaseFinalId,\n\t\t\t\tcluster: newCluster,\n\t\t\t});\n\t\t\tsession.currentClusterDetails = { cluster: newCluster, clusterBase: newBaseFinalId };\n\t\t\tthis.nextClusterBaseFinalId = (this.nextClusterBaseFinalId + newCluster.capacity) as FinalCompressedId;\n\t\t\tassert(\n\t\t\t\tthis.nextClusterBaseFinalId < Number.MAX_SAFE_INTEGER,\n\t\t\t\t0x649 /* The number of allocated final IDs must not exceed the JS maximum safe integer. */\n\t\t\t);\n\t\t\tthis.finalIdToCluster.append(newBaseFinalId, newCluster);\n\t\t}\n\n\t\t// If there are overrides, we must determine which cluster object (current or overflow) each belongs to and add it.\n\t\tconst overrides = ids.overrides;\n\t\tif (overrides !== undefined) {\n\t\t\tfor (let i = 0; i < overrides.length; i++) {\n\t\t\t\tconst [overriddenLocal, override] = overrides[i];\n\t\t\t\t// Note: recall that local IDs are negative\n\t\t\t\tassert(i === 0 || overriddenLocal < overrides[i - 1][0], 0x64a /* Override IDs must be in sorted order. */);\n\t\t\t\tassert(overriddenLocal < normalizedLastFinalizedLocal, 0x64b /* Ranges finalized out of order. */);\n\t\t\t\tassert(\n\t\t\t\t\toverriddenLocal >= newLastFinalizedLocal,\n\t\t\t\t\t0x64c /* Malformed range: override ID ahead of range start. */\n\t\t\t\t);\n\t\t\t\tlet cluster: IdCluster;\n\t\t\t\tlet overriddenFinal: FinalCompressedId;\n\t\t\t\tif (localIdPivot !== undefined && overriddenLocal <= localIdPivot) {\n\t\t\t\t\t// Override is at or past the pivot, so it is in a new cluster.\n\t\t\t\t\tassert(\n\t\t\t\t\t\tnewCluster !== undefined && newBaseFinalId !== undefined,\n\t\t\t\t\t\t0x64d /* No cluster was created when overflow occurred. */\n\t\t\t\t\t);\n\t\t\t\t\tcluster = newCluster;\n\t\t\t\t\toverriddenFinal = (newBaseFinalId + (localIdPivot - overriddenLocal)) as FinalCompressedId;\n\t\t\t\t} else {\n\t\t\t\t\t// Override was finalized into an existing cluster\n\t\t\t\t\tassert(\n\t\t\t\t\t\tcurrentCluster !== undefined && currentBaseFinalId !== undefined,\n\t\t\t\t\t\t0x64e /* No cluster exists but IDs were finalized. */\n\t\t\t\t\t);\n\t\t\t\t\tcluster = currentCluster;\n\t\t\t\t\toverriddenFinal = (currentBaseFinalId +\n\t\t\t\t\t\tinitialClusterCount +\n\t\t\t\t\t\t(normalizedLastFinalizedLocal - overriddenLocal) -\n\t\t\t\t\t\t1) as FinalCompressedId;\n\t\t\t\t}\n\t\t\t\tcluster.overrides ??= new Map();\n\n\t\t\t\tconst inversionKey = IdCompressor.createInversionKey(override);\n\t\t\t\tconst existingIds = this.getExistingIdsForNewOverride(inversionKey, true);\n\t\t\t\tlet overrideForCluster: string | FinalCompressedId;\n\t\t\t\tlet associatedLocal: LocalCompressedId | undefined;\n\t\t\t\tif (existingIds !== undefined) {\n\t\t\t\t\tlet mostFinalExistingOverride: CompressedId;\n\t\t\t\t\tif (typeof existingIds === 'number') {\n\t\t\t\t\t\tmostFinalExistingOverride = existingIds;\n\t\t\t\t\t\tif (isLocalId(mostFinalExistingOverride)) {\n\t\t\t\t\t\t\tassociatedLocal = mostFinalExistingOverride;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t[associatedLocal, mostFinalExistingOverride] = existingIds;\n\t\t\t\t\t}\n\t\t\t\t\tif (isFinalId(mostFinalExistingOverride)) {\n\t\t\t\t\t\t// A previous range already finalized an ID with this override. See `IdCluster` for more.\n\t\t\t\t\t\toverrideForCluster = mostFinalExistingOverride;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\t!isLocal || mostFinalExistingOverride === overriddenLocal,\n\t\t\t\t\t\t\t0x64f /* Cannot have multiple local IDs with identical overrides. */\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// This session has created an ID with this override before, but has not finalized it yet. The incoming\n\t\t\t\t\t\t// range \"wins\" and will contain the final ID associated with that override, regardless of if that range was\n\t\t\t\t\t\t// made by this session or not.\n\t\t\t\t\t\toverrideForCluster = override;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// This is the first time this override has been associated with any ID\n\t\t\t\t\toverrideForCluster = override;\n\t\t\t\t}\n\n\t\t\t\tassert(!cluster.overrides.has(overriddenFinal), 0x650 /* Cannot add a second override for final id */);\n\t\t\t\tif (typeof overrideForCluster === 'string') {\n\t\t\t\t\tif (isLocal || associatedLocal === undefined) {\n\t\t\t\t\t\tcluster.overrides.set(overriddenFinal, override);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcluster.overrides.set(overriddenFinal, {\n\t\t\t\t\t\t\toverride,\n\t\t\t\t\t\t\toriginalOverridingFinal: overriddenFinal,\n\t\t\t\t\t\t\tassociatedLocalId: associatedLocal,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst unifiedOverride: UnifiedOverride = {\n\t\t\t\t\t\toverride,\n\t\t\t\t\t\toriginalOverridingFinal: overrideForCluster,\n\t\t\t\t\t};\n\t\t\t\t\tsetPropertyIfDefined(associatedLocal, unifiedOverride, 'associatedLocalId');\n\t\t\t\t\tcluster.overrides.set(overriddenFinal, unifiedOverride);\n\t\t\t\t}\n\t\t\t\tconst finalizedOverride: Mutable<FinalizedOverride> = {\n\t\t\t\t\tcluster,\n\t\t\t\t\toriginalOverridingFinal: overriddenFinal,\n\t\t\t\t};\n\t\t\t\tsetPropertyIfDefined(associatedLocal, finalizedOverride, 'associatedLocalId');\n\t\t\t\tconst currentOverride = this.clustersAndOverridesInversion.get(inversionKey);\n\t\t\t\tif (currentOverride === undefined || IdCompressor.isUnfinalizedOverride(currentOverride)) {\n\t\t\t\t\t// Update the map to contain a finalized override, but never update it with future finalized overrides with\n\t\t\t\t\t// the same string; those should decompress to the first final ID with that override.\n\t\t\t\t\tthis.clustersAndOverridesInversion.set(inversionKey, finalizedOverride);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\tthis.logger?.sendTelemetryEvent({\n\t\t\t\teventName: 'SharedTreeIdCompressor:IdCompressorStatus',\n\t\t\t\teagerFinalIdCount: eagerFinalIdCount - (overrides?.length ?? 0),\n\t\t\t\tlocalIdCount: remainingCount + (overrides?.length ?? 0),\n\t\t\t\toverridesCount: overrides?.length ?? 0,\n\t\t\t\tsessionId: this.localSessionId,\n\t\t\t});\n\t\t}\n\n\t\tsession.lastFinalizedLocalId = newLastFinalizedLocal;\n\t}\n\n\tprivate checkClusterForCollision(cluster: IdCluster): void {\n\t\tconst maxClusterUuid = incrementUuid(cluster.baseUuid, cluster.capacity - 1);\n\t\tconst maxClusterStableId = stableIdFromNumericUuid(maxClusterUuid);\n\t\tconst closestMatch = this.clustersAndOverridesInversion.getPairOrNextLower(maxClusterStableId);\n\t\tif (closestMatch !== undefined) {\n\t\t\tconst [inversionKey, compressionMapping] = closestMatch;\n\t\t\tif (!IdCompressor.isClusterInfo(compressionMapping)) {\n\t\t\t\tif (\n\t\t\t\t\tisStableId(inversionKey) &&\n\t\t\t\t\tIdCompressor.uuidsMightCollide(inversionKey, maxClusterStableId, cluster.capacity)\n\t\t\t\t) {\n\t\t\t\t\tconst numericOverride = numericUuidFromStableId(inversionKey);\n\t\t\t\t\tconst delta = getPositiveDelta(maxClusterUuid, numericOverride, cluster.capacity - 1);\n\t\t\t\t\tif (delta !== undefined) {\n\t\t\t\t\t\tIdCompressor.failWithCollidingOverride(inversionKey);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static failWithCollidingOverride(override: string): void {\n\t\tfail(`Override '${override}' collides with another allocated UUID.`);\n\t}\n\n\tprivate static isClusterInfo(compressionMapping: CompressionMapping): compressionMapping is ClusterInfo {\n\t\treturn (compressionMapping as ClusterInfo).clusterBase !== undefined;\n\t}\n\n\tprivate static isUnfinalizedOverride(compressionMapping: CompressionMapping): compressionMapping is UnackedLocalId {\n\t\treturn typeof compressionMapping === 'number';\n\t}\n\n\tprivate static createInversionKey(inversionKey: string): InversionKey {\n\t\treturn isStableId(inversionKey) ? inversionKey : `${nonStableOverridePrefix}${inversionKey}`;\n\t}\n\n\tprivate static isStableInversionKey(inversionKey: InversionKey): inversionKey is StableId {\n\t\treturn !inversionKey.startsWith(nonStableOverridePrefix);\n\t}\n\n\t/**\n\t * Returns an existing ID associated with an override, or undefined if none exists.\n\t */\n\tprivate getExistingIdsForNewOverride(\n\t\tinversionKey: InversionKey,\n\t\tisFinalOverride: boolean\n\t): SessionSpaceCompressedId | [LocalCompressedId, FinalCompressedId] | undefined {\n\t\tconst closestMatch = this.clustersAndOverridesInversion.getPairOrNextLower(inversionKey, reusedArray);\n\t\tlet numericOverride: NumericUuid | undefined;\n\t\tlet stableOverride: StableId | undefined;\n\t\tif (closestMatch !== undefined) {\n\t\t\tconst [key, compressionMapping] = closestMatch;\n\t\t\tif (!IdCompressor.isClusterInfo(compressionMapping)) {\n\t\t\t\tif (key === inversionKey) {\n\t\t\t\t\tif (IdCompressor.isUnfinalizedOverride(compressionMapping)) {\n\t\t\t\t\t\treturn compressionMapping;\n\t\t\t\t\t}\n\t\t\t\t\tconst finalizedOverride = compressionMapping;\n\t\t\t\t\treturn finalizedOverride.associatedLocalId !== undefined\n\t\t\t\t\t\t? [finalizedOverride.associatedLocalId, finalizedOverride.originalOverridingFinal]\n\t\t\t\t\t\t: (finalizedOverride.originalOverridingFinal as SessionSpaceCompressedId);\n\t\t\t\t}\n\t\t\t} else if (IdCompressor.isStableInversionKey(inversionKey)) {\n\t\t\t\tstableOverride = inversionKey;\n\t\t\t\tconst cluster = compressionMapping.cluster;\n\t\t\t\tif (IdCompressor.uuidsMightCollide(inversionKey, key as StableId, cluster.capacity)) {\n\t\t\t\t\tnumericOverride = numericUuidFromStableId(stableOverride);\n\t\t\t\t\tconst delta = getPositiveDelta(numericOverride, cluster.baseUuid, cluster.capacity - 1);\n\t\t\t\t\tif (delta !== undefined) {\n\t\t\t\t\t\tif (!isFinalOverride) {\n\t\t\t\t\t\t\tif (delta >= cluster.count) {\n\t\t\t\t\t\t\t\t// TODO:#283: Properly implement unification\n\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn this.normalizeToSessionSpace((compressionMapping.clusterBase + delta) as FinalCompressedId);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst override =\n\t\t\tnumericOverride ?? stableOverride ?? (IdCompressor.isStableInversionKey(inversionKey) ? inversionKey : undefined);\n\n\t\tif (override !== undefined) {\n\t\t\tconst sessionSpaceId = this.getCompressedIdForStableId(override);\n\t\t\tif (sessionSpaceId !== undefined) {\n\t\t\t\treturn sessionSpaceId;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Check if `a` might be within `range` of `b`, where both are treated as hex numbers.\n\t * @param range - an integer\n\t */\n\tprivate static uuidsMightCollide(a: StableId, b: StableId, range: number): boolean {\n\t\t// Check if any of the UUIDs in the cluster collide (i.e. any in [base, base + capacity)).\n\t\t// Optimization: All UUIDs in a cluster are the same string up until the last few characters which encode the offset from\n\t\t// the cluster base. So, first compute the length of that shared string, and early out if it is different from the override\n\t\t// UUID. This way we usually need not do the more expensive check below.\n\t\tconst hexDigitsToCheck = 32 - Math.ceil(Math.log2(range) / 2);\n\t\tif (a.startsWith(b.slice(0, hexDigitsToCheck))) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Helper for retrieving an override.\n\t */\n\tprivate static tryGetOverride(cluster: IdCluster, finalId: FinalCompressedId): string | undefined {\n\t\tconst override = cluster.overrides?.get(finalId);\n\t\tif (override === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (typeof override === 'string') {\n\t\t\treturn override;\n\t\t}\n\t\treturn override.override;\n\t}\n\n\t/**\n\t * Generates a new compressed ID or returns an existing one.\n\t * This should ONLY be called to generate IDs for local operations.\n\t * @param override - Specifies a specific string to be associated with the returned compressed ID.\n\t * Performance note: assigning override strings incurs a performance overhead.\n\t * @returns an existing ID if one already exists for `override`, and a new local ID otherwise. The returned ID is in session space.\n\t */\n\tpublic generateCompressedId(override?: string): SessionSpaceCompressedId {\n\t\tlet overrideInversionKey: InversionKey | undefined;\n\t\tif (override !== undefined) {\n\t\t\toverrideInversionKey = IdCompressor.createInversionKey(override);\n\t\t\tconst existingIds = this.getExistingIdsForNewOverride(overrideInversionKey, false);\n\t\t\tif (existingIds !== undefined) {\n\t\t\t\treturn typeof existingIds === 'number' ? existingIds : existingIds[0];\n\t\t\t}\n\t\t}\n\n\t\t// Bump local counter regardless, then attempt to optimistically return a final ID.\n\t\t// If the local session has reserved a cluster range via consensus, it is safe to hand out final IDs prior to\n\t\t// finalizing the range that includes these locals.\n\t\tconst newLocalId = -++this.localIdCount as LocalCompressedId;\n\t\tconst { currentClusterDetails } = this.localSession;\n\t\tconst { sessionIdNormalizer } = this;\n\t\tlet eagerFinalId: (FinalCompressedId & SessionSpaceCompressedId) | undefined;\n\t\tlet cluster: IdCluster | undefined;\n\t\tif (currentClusterDetails !== undefined) {\n\t\t\tcluster = currentClusterDetails.cluster;\n\t\t\tconst lastFinalKnown = sessionIdNormalizer.getLastFinalId();\n\t\t\tif (lastFinalKnown !== undefined && lastFinalKnown - currentClusterDetails.clusterBase + 1 < cluster.capacity) {\n\t\t\t\teagerFinalId = (lastFinalKnown + 1) as FinalCompressedId & SessionSpaceCompressedId;\n\t\t\t}\n\t\t}\n\n\t\tif (overrideInversionKey !== undefined) {\n\t\t\tconst registeredLocal = sessionIdNormalizer.addLocalId();\n\t\t\tassert(registeredLocal === newLocalId, 0x651 /* Session ID Normalizer produced unexpected local ID */);\n\t\t\tif (eagerFinalId !== undefined) {\n\t\t\t\tsessionIdNormalizer.addFinalIds(eagerFinalId, eagerFinalId, cluster ?? fail());\n\t\t\t}\n\t\t\tthis.localOverrides.append(newLocalId, override ?? fail());\n\t\t\t// Since the local ID was just created, it is in both session and op space\n\t\t\tconst compressionMapping = newLocalId as UnackedLocalId;\n\t\t\tthis.clustersAndOverridesInversion.set(overrideInversionKey, compressionMapping);\n\t\t} else if (eagerFinalId !== undefined) {\n\t\t\tsessionIdNormalizer.addFinalIds(eagerFinalId, eagerFinalId, cluster ?? fail());\n\t\t\treturn eagerFinalId;\n\t\t} else {\n\t\t\tconst registeredLocal = sessionIdNormalizer.addLocalId();\n\t\t\tassert(registeredLocal === newLocalId, 0x652 /* Session ID Normalizer produced unexpected local ID */);\n\t\t}\n\n\t\treturn newLocalId;\n\t}\n\n\t/**\n\t * Decompresses a previously compressed ID into a UUID or override string.\n\t * @param id - the compressed ID to be decompressed.\n\t * @returns the UUID or override string associated with the compressed ID. Fails if the ID was not generated by this compressor.\n\t */\n\tpublic decompress(id: SessionSpaceCompressedId | FinalCompressedId): StableId | string {\n\t\treturn this.tryDecompress(id) ?? fail('Compressed ID was not generated by this compressor');\n\t}\n\n\t/**\n\t * Attempts to decompress a previously compressed ID into a UUID or override string.\n\t * @param id - the compressed ID to be decompressed.\n\t * @returns the UUID or override string associated with the compressed ID, or undefined if the ID was not generated by this compressor.\n\t */\n\tpublic tryDecompress(id: SessionSpaceCompressedId | FinalCompressedId): StableId | string | undefined {\n\t\tif (isFinalId(id)) {\n\t\t\tconst possibleCluster = this.getClusterForFinalId(id);\n\t\t\tif (possibleCluster === undefined) {\n\t\t\t\t// It may be an unfinalized eager final ID, so check with normalizer to get the offset from the session UUID\n\t\t\t\tconst creationIndex = this.sessionIdNormalizer.getCreationIndex(id);\n\t\t\t\tif (creationIndex !== undefined) {\n\t\t\t\t\treturn stableIdFromNumericUuid(this.localSession.sessionUuid, creationIndex);\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t} else {\n\t\t\t\tconst [baseFinalId, cluster] = possibleCluster;\n\t\t\t\tconst override = IdCompressor.tryGetOverride(cluster, id);\n\t\t\t\tif (override !== undefined) {\n\t\t\t\t\treturn override;\n\t\t\t\t} else {\n\t\t\t\t\tconst offsetInCluster = id - baseFinalId;\n\t\t\t\t\treturn stableIdFromNumericUuid(cluster.baseUuid, offsetInCluster);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\t\tconst idOffset = -id; // Convert to a positive number\n\t\t\tif (idOffset > this.localIdCount) {\n\t\t\t\t// This local ID was never allocated.\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// If this is a local ID with an override, then it must have been allocated on this machine and will be contained in\n\t\t\t// `localOverrides`s. Otherwise, it is a sequential allocation from the session UUID and can simply be negated and\n\t\t\t// added to that UUID to obtain the stable ID associated with it.\n\t\t\tconst localOverride = this.localOverrides?.get(id);\n\t\t\treturn localOverride ?? stableIdFromNumericUuid(this.localSession.sessionUuid, idOffset - 1);\n\t\t}\n\t}\n\n\t/**\n\t * Recompresses a decompressed ID, which could be a UUID or an override string.\n\t * @param uncompressed - the UUID or override string to recompress.\n\t * @returns the `CompressedId` associated with `uncompressed`. Fails if it has not been previously compressed by this compressor.\n\t */\n\tpublic recompress(uncompressed: string): SessionSpaceCompressedId {\n\t\treturn this.tryRecompress(uncompressed) ?? fail('No such string has ever been compressed');\n\t}\n\n\t/**\n\t * Attempts to recompresses a decompressed ID, which could be a UUID or an override string.\n\t * @param uncompressed - the UUID or override string to recompress,\n\t * @returns the `CompressedId` associated with `uncompressed` or undefined if it has not been previously compressed by this compressor.\n\t */\n\tpublic tryRecompress(uncompressed: string): SessionSpaceCompressedId | undefined {\n\t\treturn this.recompressInternal(uncompressed);\n\t}\n\n\t/**\n\t * Helper to compress an uncompressed UUID. It can optionally be supplied with the numeric form of `uncompressedUuid` as a\n\t * performance optimization.\n\t */\n\tprivate recompressInternal(\n\t\tuncompressed: string,\n\t\tuncompressedUuidNumeric?: NumericUuid\n\t): SessionSpaceCompressedId | undefined {\n\t\tlet numericUuid = uncompressedUuidNumeric;\n\t\tconst inversionKey = IdCompressor.createInversionKey(uncompressed);\n\t\tconst isStable = IdCompressor.isStableInversionKey(inversionKey);\n\t\tconst closestMatch = this.clustersAndOverridesInversion.getPairOrNextLower(inversionKey, reusedArray);\n\t\tif (closestMatch !== undefined) {\n\t\t\tconst [key, compressionMapping] = closestMatch;\n\t\t\tif (!IdCompressor.isClusterInfo(compressionMapping)) {\n\t\t\t\tif (key === inversionKey) {\n\t\t\t\t\treturn IdCompressor.isUnfinalizedOverride(compressionMapping)\n\t\t\t\t\t\t? compressionMapping\n\t\t\t\t\t\t: (compressionMapping.associatedLocalId ??\n\t\t\t\t\t\t\t\t(compressionMapping.originalOverridingFinal as SessionSpaceCompressedId));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (!isStable) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\tconst { clusterBase: closestBaseFinalId, cluster: closestCluster } = compressionMapping;\n\t\t\t\tnumericUuid ??= numericUuidFromStableId(inversionKey);\n\t\t\t\tconst uuidOffset = getPositiveDelta(numericUuid, closestCluster.baseUuid, closestCluster.count - 1);\n\t\t\t\tif (uuidOffset !== undefined) {\n\t\t\t\t\tlet targetFinalId = (closestBaseFinalId + uuidOffset) as FinalCompressedId;\n\t\t\t\t\tconst override = closestCluster.overrides?.get(targetFinalId);\n\t\t\t\t\tif (typeof override === 'object') {\n\t\t\t\t\t\tif (override.associatedLocalId !== undefined) {\n\t\t\t\t\t\t\treturn override.associatedLocalId;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// This may be a UUID that should actually compress into a different final ID that it aligns with, due to\n\t\t\t\t\t\t// another session having an identical override (see `IdCluster` for more).\n\t\t\t\t\t\ttargetFinalId = override.originalOverridingFinal;\n\t\t\t\t\t}\n\t\t\t\t\treturn this.normalizeToSessionSpace(targetFinalId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (isStable) {\n\t\t\t// May have already computed the numeric UUID, so avoid recomputing if possible\n\t\t\tconst sessionSpaceId = this.getCompressedIdForStableId(numericUuid ?? inversionKey);\n\t\t\tif (sessionSpaceId !== undefined) {\n\t\t\t\treturn sessionSpaceId;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Normalizes a session space ID into op space.\n\t * @param id - the local ID to normalize.\n\t * @returns the ID in op space.\n\t */\n\tpublic normalizeToOpSpace(id: SessionSpaceCompressedId): OpSpaceCompressedId {\n\t\tif (isFinalId(id)) {\n\t\t\treturn id;\n\t\t}\n\n\t\t// Check if this local ID has not been allocated yet\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\tif (-id > this.localIdCount) {\n\t\t\tfail('Supplied local ID was not created by this compressor.');\n\t\t}\n\n\t\t// Check if this local ID has not been finalized yet.\n\t\t// Comparing lastFinalizedLocalId is a safe check for eager final IDs because the local IDs corresponding to them\n\t\t// are never handed out to a consumer, and thus could not be passed into this method.\n\t\tconst { lastFinalizedLocalId } = this.localSession;\n\t\tif (lastFinalizedLocalId === undefined || id < lastFinalizedLocalId) {\n\t\t\t// Eager final IDs do not have overrides in the cluster until finalizing\n\t\t\t// This means that using the normalizer to get the final/cluster associated would succeed but would not have the override,\n\t\t\t// so checking localOverrides first is necessary.\n\t\t\tconst override = this.localOverrides.get(id);\n\t\t\tif (override !== undefined) {\n\t\t\t\tconst inversionKey = IdCompressor.createInversionKey(override);\n\t\t\t\tconst compressionMapping = this.clustersAndOverridesInversion.get(inversionKey) ?? fail('Bimap is malformed.');\n\t\t\t\treturn !IdCompressor.isClusterInfo(compressionMapping) &&\n\t\t\t\t\t!IdCompressor.isUnfinalizedOverride(compressionMapping) &&\n\t\t\t\t\tcompressionMapping.associatedLocalId === id\n\t\t\t\t\t? compressionMapping.originalOverridingFinal\n\t\t\t\t\t: (id as OpSpaceCompressedId);\n\t\t\t}\n\t\t\tconst possibleFinal = this.sessionIdNormalizer.getFinalId(id);\n\t\t\treturn possibleFinal?.[0] ?? (id as OpSpaceCompressedId);\n\t\t}\n\t\tconst [correspondingFinal, cluster] =\n\t\t\tthis.sessionIdNormalizer.getFinalId(id) ??\n\t\t\tfail('Locally created cluster should be added to the map when allocated');\n\t\tif (cluster.overrides) {\n\t\t\tconst override = cluster.overrides.get(correspondingFinal);\n\t\t\tif (typeof override === 'object' && override.originalOverridingFinal !== undefined) {\n\t\t\t\t// Rare case of two local IDs with same overrides are created concurrently. See `IdCluster` for more.\n\t\t\t\treturn override.originalOverridingFinal;\n\t\t\t}\n\t\t}\n\t\treturn correspondingFinal;\n\t}\n\n\t/**\n\t * Normalizes an ID into session space.\n\t * @param id - the ID to normalize. If it is a local ID, it is assumed to have been created by the session corresponding\n\t * to `sessionId`.\n\t * @param originSessionId - the session from which `id` originated\n\t * @returns the session-space ID corresponding to `id`, which might not have been a final ID if the client that created it had not yet\n\t * finalized it. This can occur when a client references an ID during the window of time in which it is waiting to receive the ordered\n\t * range that contained it from the server.\n\t */\n\tpublic normalizeToSessionSpace(id: OpSpaceCompressedId, originSessionId: SessionId): SessionSpaceCompressedId;\n\n\t/**\n\t * Normalizes a final ID into session space.\n\t * @param id - the final ID to normalize.\n\t * @returns the session-space ID corresponding to `id`.\n\t */\n\tpublic normalizeToSessionSpace(id: FinalCompressedId): SessionSpaceCompressedId;\n\n\tpublic normalizeToSessionSpace(id: OpSpaceCompressedId, sessionIdIfLocal?: SessionId): SessionSpaceCompressedId {\n\t\tif (isLocalId(id)) {\n\t\t\tif (sessionIdIfLocal === undefined || sessionIdIfLocal === this.localSessionId) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\t\t\tconst localIndex = -id;\n\t\t\t\tif (localIndex > this.localIdCount) {\n\t\t\t\t\tfail('Supplied local ID was not created by this compressor.');\n\t\t\t\t}\n\t\t\t\treturn id;\n\t\t\t} else {\n\t\t\t\tconst session =\n\t\t\t\t\tthis.sessions.get(sessionIdIfLocal) ?? fail('No IDs have ever been finalized by the supplied session.');\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\t\t\tconst localCount = -id;\n\t\t\t\tconst numericUuid = incrementUuid(session.sessionUuid, localCount - 1);\n\t\t\t\treturn this.compressNumericUuid(numericUuid) ?? fail('ID is not known to this compressor.');\n\t\t\t}\n\t\t}\n\n\t\tconst normalizedId = this.sessionIdNormalizer.getSessionSpaceId(id);\n\t\tif (normalizedId !== undefined) {\n\t\t\treturn normalizedId;\n\t\t}\n\n\t\t// Check for a unified override finalized first by another session but to which the local session\n\t\t// still has an associated local ID.\n\t\tconst [_, cluster] =\n\t\t\tthis.getClusterForFinalId(id) ?? fail('Supplied final ID was not finalized by this compressor.');\n\t\tconst override = cluster.overrides?.get(id);\n\t\tif (typeof override === 'object' && override.associatedLocalId !== undefined) {\n\t\t\treturn override.associatedLocalId;\n\t\t}\n\t\treturn id as SessionSpaceCompressedId;\n\t}\n\n\t/**\n\t * Returns the session-space compressed ID corresponding to the numeric UUID, or undefined if it is not known to this compressor.\n\t * Typically, it will return the session-space ID sequentially aligned with it (which will be local if `numericUuid` was made by\n\t * the local session, or final otherwise). However, in the event that the aligned session-space ID was overridden with a UUID\n\t * *and* that override UUID was concurrently used in an older ID (earlier, w.r.t. sequencing), this method can return the first\n\t * ID to correspond to that override.\n\t *\n\t * As an example, consider the following two clients:\n\t * ClientA, session UUID: A0000000-0000-0000-0000-000000000000\n\t * ClientB, session UUID: B0000000-0000-0000-0000-000000000000\n\t *\n\t * If concurrently, two clients performed:\n\t * ClientA: generateCompressedId(override: 'X0000000-0000-0000-0000-000000000000') // aligned with A0000000-0000-0000-0000-000000000000\n\t *\n\t * ClientB: generateCompressedId() // aligned with B0000000-0000-0000-0000-000000000000\n\t * ClientB: generateCompressedId(override: 'X0000000-0000-0000-0000-000000000000') // aligned with B0000000-0000-0000-0000-000000000001\n\t *\n\t * After sequencing, calling this method and passing the numeric UUID for B0000000-0000-0000-0000-000000000001 would return the\n\t * session-space ID corresponding to A0000000-0000-0000-0000-000000000000 (with override X0000000-0000-0000-0000-000000000000).\n\t */\n\tprivate compressNumericUuid(numericUuid: NumericUuid): SessionSpaceCompressedId | undefined {\n\t\tconst stableId = stableIdFromNumericUuid(numericUuid);\n\t\tconst sessionSpaceId = this.recompressInternal(stableId, numericUuid);\n\t\tif (sessionSpaceId === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn sessionSpaceId;\n\t}\n\n\t/**\n\t * Returns a compressed ID for the supplied stable ID if it was created by the local session, and undefined otherwise.\n\t */\n\tprivate getCompressedIdForStableId(stableId: StableId | NumericUuid): SessionSpaceCompressedId | undefined {\n\t\tconst numericUuid = typeof stableId === 'string' ? numericUuidFromStableId(stableId) : stableId;\n\t\tconst creationIndex = getPositiveDelta(numericUuid, this.localSession.sessionUuid, this.localIdCount - 1);\n\t\tif (creationIndex !== undefined) {\n\t\t\tconst sessionSpaceId = this.sessionIdNormalizer.getIdByCreationIndex(creationIndex);\n\t\t\tif (sessionSpaceId !== undefined) {\n\t\t\t\treturn sessionSpaceId;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate getClusterForFinalId(\n\t\tfinalId: FinalCompressedId\n\t): readonly [baseFinalId: FinalCompressedId, cluster: IdCluster] | undefined {\n\t\tconst possibleCluster = this.finalIdToCluster.getPairOrNextLower(finalId);\n\t\tif (possibleCluster === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst [clusterBase, cluster] = possibleCluster;\n\t\tif (finalId - clusterBase >= cluster.count) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn possibleCluster;\n\t}\n\n\t/**\n\t * @returns if `other` is equal to this `IdCompressor`. The equality check includes local session state only if specified.\n\t * \\@testOnly\n\t */\n\tpublic equals(other: IdCompressor, compareLocalState: boolean): boolean {\n\t\tif (compareLocalState) {\n\t\t\tif (\n\t\t\t\tthis.localIdCount !== other.localIdCount ||\n\t\t\t\tthis.localSessionId !== other.localSessionId ||\n\t\t\t\tthis.lastTakenLocalId !== other.lastTakenLocalId ||\n\t\t\t\tthis.attributionId !== other.attributionId\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!this.localOverrides.equals(other.localOverrides, (a, b) => a === b)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!compareMaps(this.sessions, other.sessions, (a, b) =>\n\t\t\t\t\tIdCompressor.sessionDataEqual(a, b, true, compareLocalState)\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!this.sessionIdNormalizer.equals(other.sessionIdNormalizer, (a, b) =>\n\t\t\t\t\tIdCompressor.idClustersEqual(a, b, false, compareLocalState)\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [keyA, valueA] of this.sessions) {\n\t\t\t\tconst valueB = other.sessions.get(keyA);\n\t\t\t\tif (valueB === undefined) {\n\t\t\t\t\tif (valueA.lastFinalizedLocalId !== undefined) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} else if (!IdCompressor.sessionDataEqual(valueA, valueB, true, compareLocalState)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const [keyB, valueB] of other.sessions) {\n\t\t\t\tconst valueA = this.sessions.get(keyB);\n\t\t\t\tif (valueA === undefined) {\n\t\t\t\t\tif (valueB.lastFinalizedLocalId !== undefined) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\tthis.nextClusterBaseFinalId !== other.nextClusterBaseFinalId ||\n\t\t\tthis.newClusterCapacity !== other.newClusterCapacity\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tif (\n\t\t\t!this.finalIdToCluster.equals(other.finalIdToCluster, (a, b) =>\n\t\t\t\tIdCompressor.idClustersEqual(a, b, true, compareLocalState)\n\t\t\t)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst missingInOne = (_: string, value: CompressionMapping): { break: boolean } | undefined => {\n\t\t\tif (!compareLocalState && IdCompressor.isUnfinalizedOverride(value)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn { break: true };\n\t\t};\n\n\t\tconst compareCompressionMappings = (a, b) => {\n\t\t\tconst unfinalizedA = IdCompressor.isUnfinalizedOverride(a);\n\t\t\tconst unfinalizedB = IdCompressor.isUnfinalizedOverride(b);\n\t\t\tif (unfinalizedA) {\n\t\t\t\tif (unfinalizedB) {\n\t\t\t\t\treturn a === b;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t} else if (unfinalizedB) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (IdCompressor.isClusterInfo(a)) {\n\t\t\t\tif (!IdCompressor.isClusterInfo(b) || a.clusterBase !== b.clusterBase) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (\n\t\t\t\t\tIdCompressor.isClusterInfo(b) ||\n\t\t\t\t\t(compareLocalState && a.associatedLocalId !== b.associatedLocalId) ||\n\t\t\t\t\ta.originalOverridingFinal !== b.originalOverridingFinal\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!IdCompressor.idClustersEqual(a.cluster, b.cluster, true, compareLocalState)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tconst diff = this.clustersAndOverridesInversion.diffAgainst(\n\t\t\tother.clustersAndOverridesInversion,\n\t\t\tmissingInOne,\n\t\t\tmissingInOne,\n\t\t\t(_, valA, valB) => {\n\t\t\t\tif (!compareCompressionMappings(valA, valB)) {\n\t\t\t\t\treturn { break: true };\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t);\n\n\t\treturn diff === undefined;\n\t}\n\n\tprivate static sessionDataEqual(a: Session, b: Session, checkCluster = true, compareLocalState = true): boolean {\n\t\tif (\n\t\t\ta.attributionId !== b.attributionId ||\n\t\t\t!numericUuidEquals(a.sessionUuid, b.sessionUuid) ||\n\t\t\ta.lastFinalizedLocalId !== b.lastFinalizedLocalId\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tif (a.currentClusterDetails === undefined || b.currentClusterDetails === undefined) {\n\t\t\tif (a.currentClusterDetails !== b.currentClusterDetails) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tif (\n\t\t\tcheckCluster &&\n\t\t\t!IdCompressor.idClustersEqual(\n\t\t\t\ta.currentClusterDetails.cluster,\n\t\t\t\tb.currentClusterDetails.cluster,\n\t\t\t\tfalse,\n\t\t\t\tcompareLocalState\n\t\t\t)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate static idClustersEqual(\n\t\ta: IdCluster,\n\t\tb: IdCluster,\n\t\tcheckSessionData = true,\n\t\tcompareLocalState = true\n\t): boolean {\n\t\tconst areEqual =\n\t\t\tnumericUuidEquals(a.baseUuid, b.baseUuid) &&\n\t\t\ta.capacity === b.capacity &&\n\t\t\ta.count === b.count &&\n\t\t\t(!checkSessionData || IdCompressor.sessionDataEqual(a.session, b.session, false, compareLocalState)) &&\n\t\t\t(a.overrides === undefined) === (b.overrides === undefined) &&\n\t\t\t(a.overrides === undefined ||\n\t\t\t\tcompareMaps(assertNotUndefined(a.overrides), assertNotUndefined(b.overrides), (a, b) => {\n\t\t\t\t\tif (compareLocalState) {\n\t\t\t\t\t\tif (typeof a === 'string' || typeof b === 'string') {\n\t\t\t\t\t\t\treturn a === b;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst overridesEqual =\n\t\t\t\t\t\t\ta.override === b.override &&\n\t\t\t\t\t\t\ta.originalOverridingFinal === b.originalOverridingFinal &&\n\t\t\t\t\t\t\t(!compareLocalState || a.associatedLocalId === b.associatedLocalId);\n\t\t\t\t\t\treturn overridesEqual;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst uuidA = typeof a === 'string' ? a : a.override;\n\t\t\t\t\tconst uuidB = typeof b === 'string' ? b : b.override;\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof a !== 'string' &&\n\t\t\t\t\t\ttypeof b !== 'string' &&\n\t\t\t\t\t\ta.originalOverridingFinal !== b.originalOverridingFinal\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn uuidA === uuidB;\n\t\t\t\t}));\n\t\treturn areEqual;\n\t}\n\n\t/**\n\t * Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.\n\t * This includes finalized state as well as un-finalized state and is therefore suitable for use in offline scenarios.\n\t */\n\tpublic serialize(\n\t\twithSession: boolean\n\t): SerializedIdCompressorWithOngoingSession | SerializedIdCompressorWithNoSession;\n\n\t/**\n\t * Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.\n\t * This includes finalized state as well as un-finalized state and is therefore suitable for use in offline scenarios.\n\t */\n\tpublic serialize(withSession: true): SerializedIdCompressorWithOngoingSession;\n\n\t/**\n\t * Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.\n\t * This only includes finalized state and is therefore suitable for use in summaries.\n\t */\n\tpublic serialize(withSession: false): SerializedIdCompressorWithNoSession;\n\n\tpublic serialize(withSession: boolean): SerializedIdCompressor {\n\t\tconst serializedSessions: SerializedSessionData[] = [];\n\t\tconst sessionIdToSessionIndex = new Map<SessionId, number>();\n\t\tconst attributionIdToAttributionIndex = new Map<AttributionId, number>();\n\t\tlet serializedAttributionIds: UuidString[] | undefined;\n\n\t\tfor (const [sessionId, session] of this.sessions) {\n\t\t\tconst isLocalSession = sessionId === this.localSessionId;\n\t\t\tconst includeSession =\n\t\t\t\tsessionId !== reservedSessionId && // Ignore reserved clusters, but\n\t\t\t\t(session.lastFinalizedLocalId !== undefined || // always serialize sessions that made final IDs,\n\t\t\t\t\t(isLocalSession && withSession)); // include the un-acked local session if requested\n\n\t\t\tif (includeSession) {\n\t\t\t\tconst sessionData: Mutable<SerializedSessionData> = [sessionId];\n\t\t\t\tif (session.attributionId !== sessionId) {\n\t\t\t\t\t// As an optimization, don't include the attributionId if it is its default (the sessionId)\n\t\t\t\t\t// Get the index into the array for the given attribution ID. If it doesn't exist, push it onto the array and update the map.\n\t\t\t\t\tsessionData.push(\n\t\t\t\t\t\tgetOrCreate(\n\t\t\t\t\t\t\tattributionIdToAttributionIndex,\n\t\t\t\t\t\t\tsession.attributionId,\n\t\t\t\t\t\t\t(id) => (serializedAttributionIds ??= []).push(id) - 1\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tsessionIdToSessionIndex.set(sessionId, serializedSessions.length);\n\t\t\t\tserializedSessions.push(sessionData);\n\t\t\t}\n\t\t}\n\n\t\tconst serializedClusters: SerializedCluster[] = [];\n\t\tfor (const [baseFinalId, cluster] of this.finalIdToCluster.entries()) {\n\t\t\tconst sessionId = stableIdFromNumericUuid(cluster.session.sessionUuid) as SessionId;\n\t\t\tif (sessionId !== reservedSessionId) {\n\t\t\t\tconst sessionIndex =\n\t\t\t\t\tsessionIdToSessionIndex.get(sessionId) ?? fail('Session object contains wrong session numeric UUID');\n\n\t\t\t\tconst serializedCluster: Mutable<SerializedCluster> = [sessionIndex, cluster.capacity];\n\t\t\t\tif (cluster.count !== cluster.capacity) {\n\t\t\t\t\tserializedCluster.push(cluster.count);\n\t\t\t\t}\n\n\t\t\t\tif (cluster.overrides !== undefined) {\n\t\t\t\t\tconst serializedOverrides: Mutable<SerializedClusterOverrides> = [];\n\t\t\t\t\tfor (const [finalId, override] of cluster.overrides) {\n\t\t\t\t\t\tconst finalIdIndex = finalId - baseFinalId;\n\t\t\t\t\t\tif (typeof override === 'string') {\n\t\t\t\t\t\t\tserializedOverrides.push([finalIdIndex, override]);\n\t\t\t\t\t\t} else if (override.originalOverridingFinal === finalId) {\n\t\t\t\t\t\t\tserializedOverrides.push([finalIdIndex, override.override]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tserializedOverrides.push([finalIdIndex, override.override, override.originalOverridingFinal]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tserializedCluster.push(serializedOverrides);\n\t\t\t\t}\n\n\t\t\t\tserializedClusters.push(serializedCluster);\n\t\t\t}\n\t\t}\n\n\t\t// Reserved session not serialized, and local session is present but may not make IDs\n\t\tassert(serializedSessions.length - this.sessions.size <= 2, 0x653 /* session not serialized */);\n\n\t\tconst serializedIdCompressor: Omit<SerializedIdCompressor, '_versionedSerializedIdCompressor'> = {\n\t\t\tversion: currentWrittenVersion,\n\t\t\treservedIdCount: this.reservedIdCount,\n\t\t\tclusterCapacity: this.clusterCapacity,\n\t\t\tsessions: serializedSessions,\n\t\t\tclusters: serializedClusters,\n\t\t};\n\t\tsetPropertyIfDefined(serializedAttributionIds, serializedIdCompressor, 'attributionIds');\n\n\t\tif (withSession) {\n\t\t\tconst serializedWithSession = serializedIdCompressor as Mutable<SerializedIdCompressorWithOngoingSession>;\n\t\t\tserializedWithSession.localSessionIndex = serializedWithSession.sessions.findIndex(\n\t\t\t\t([sessionId]) => sessionId === this.localSessionId\n\t\t\t);\n\t\t\tif (this.localIdCount > 0) {\n\t\t\t\tserializedWithSession.localState = {\n\t\t\t\t\tlocalIdCount: this.localIdCount,\n\t\t\t\t\toverrides: [...this.localOverrides.entries()].map((entry) => [...entry]),\n\t\t\t\t\tlastTakenLocalId: this.lastTakenLocalId,\n\t\t\t\t\tsessionNormalizer: this.sessionIdNormalizer.serialize(),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn serializedWithSession;\n\t\t}\n\n\t\tthis.logger?.sendTelemetryEvent({\n\t\t\teventName: 'SharedTreeIdCompressor:SerializedIdCompressorSize',\n\t\t\tsize: JSON.stringify(serializedIdCompressor).length,\n\t\t\tclusterCount: serializedIdCompressor.clusters.length,\n\t\t\tsessionCount: serializedIdCompressor.sessions.length,\n\t\t});\n\n\t\treturn serializedIdCompressor as SerializedIdCompressor;\n\t}\n\n\t/**\n\t * Deserialize an serialized IdCompressor that is part of an ongoing session, thereby resuming that session.\n\t */\n\tpublic static deserialize(serialized: SerializedIdCompressorWithOngoingSession): IdCompressor;\n\n\t/**\n\t * Deserialize a serialized IdCompressor with a new session.\n\t * @param serialized - the serialized compressor state\n\t * @param newSessionId - the session ID for the new compressor.\n\t * @param attributionId - information used by other clients to attribute IDs made by this client\n\t */\n\tpublic static deserialize(\n\t\tserialized: SerializedIdCompressorWithNoSession,\n\t\tnewSessionId: SessionId,\n\t\tattributionId?: AttributionId\n\t): IdCompressor;\n\n\tpublic static deserialize(\n\t\t...args:\n\t\t\t| [\n\t\t\t\t\tserialized: SerializedIdCompressorWithNoSession,\n\t\t\t\t\tnewSessionIdMaybe: SessionId,\n\t\t\t\t\tattributionIdMaybe?: AttributionId,\n\t\t\t ]\n\t\t\t| [\n\t\t\t\t\tserialized: SerializedIdCompressorWithOngoingSession,\n\t\t\t\t\tnewSessionIdMaybe?: undefined,\n\t\t\t\t\tattributionIdMaybe?: undefined,\n\t\t\t ]\n\t): IdCompressor {\n\t\tconst [serialized, newSessionIdMaybe, attributionIdMaybe] = args;\n\n\t\tconst {\n\t\t\tclusterCapacity,\n\t\t\treservedIdCount,\n\t\t\tsessions: serializedSessions,\n\t\t\tclusters: serializedClusters,\n\t\t\tattributionIds: serializedAttributionIds,\n\t\t} = serialized;\n\n\t\tlet localSessionId: SessionId;\n\t\tlet attributionId: AttributionId | undefined;\n\t\tlet serializedLocalState: SerializedLocalState | undefined;\n\t\tif (newSessionIdMaybe === undefined) {\n\t\t\t// Alias of serialized, but known to be a SerializedIdCompressorWithOngoingSession\n\t\t\tconst [serializedWithSession] = args;\n\t\t\tconst serializedSessionData = serializedSessions[serializedWithSession.localSessionIndex];\n\t\t\tlocalSessionId = serializedSessionData[0];\n\t\t\tconst attributionIndex = serializedSessionData[1];\n\t\t\tif (attributionIndex !== undefined) {\n\t\t\t\tassertWithMessage(serializedAttributionIds !== undefined && serializedAttributionIds.length > attributionIndex);\n\t\t\t\tattributionId = serializedAttributionIds[attributionIndex];\n\t\t\t}\n\t\t\tserializedLocalState = serializedWithSession.localState;\n\t\t} else {\n\t\t\tlocalSessionId = newSessionIdMaybe;\n\t\t\tattributionId = attributionIdMaybe;\n\t\t}\n\n\t\tconst compressor = new IdCompressor(localSessionId, reservedIdCount, attributionId);\n\t\tcompressor.clusterCapacity = clusterCapacity;\n\n\t\tconst localOverridesInverse = new Map<string, LocalCompressedId>();\n\t\tif (serializedLocalState !== undefined) {\n\t\t\t// Do this part of local rehydration first since the cluster map population needs to query to local overrides\n\t\t\tcompressor.localIdCount = serializedLocalState.localIdCount;\n\t\t\tcompressor.lastTakenLocalId = serializedLocalState.lastTakenLocalId;\n\t\t\tif (serializedLocalState.overrides !== undefined) {\n\t\t\t\tfor (const [localId, override] of serializedLocalState.overrides) {\n\t\t\t\t\tcompressor.localOverrides.append(localId, override);\n\t\t\t\t\tlocalOverridesInverse.set(override, localId);\n\t\t\t\t\tcompressor.clustersAndOverridesInversion.set(\n\t\t\t\t\t\tIdCompressor.createInversionKey(override),\n\t\t\t\t\t\tlocalId as UnackedLocalId\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst sessionInfos: {\n\t\t\treadonly session: Session;\n\t\t\treadonly sessionId: SessionId;\n\t\t}[] = [];\n\t\tfor (const serializedSession of serializedSessions) {\n\t\t\tconst [sessionId, attributionIndex] = serializedSession;\n\t\t\tif (sessionId === localSessionId) {\n\t\t\t\tassert(hasOngoingSession(serialized), 0x654 /* Cannot resume existing session. */);\n\t\t\t\tsessionInfos.push({ session: compressor.localSession, sessionId });\n\t\t\t} else {\n\t\t\t\tlet attributionId: AttributionId | undefined;\n\t\t\t\tif (attributionIndex !== undefined) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tserializedAttributionIds !== undefined && serializedAttributionIds.length > attributionIndex,\n\t\t\t\t\t\t0x655 /* AttributionId index out of bounds */\n\t\t\t\t\t);\n\t\t\t\t\tattributionId = serializedAttributionIds[attributionIndex];\n\t\t\t\t}\n\t\t\t\tconst session = compressor.createSession(sessionId, attributionId);\n\t\t\t\tsessionInfos.push({ session, sessionId });\n\t\t\t}\n\t\t}\n\n\t\tfor (const serializedCluster of serializedClusters) {\n\t\t\tconst { sessionIndex, capacity, count, overrides } = deserializeCluster(serializedCluster);\n\t\t\tconst { session, sessionId } = sessionInfos[sessionIndex];\n\t\t\tconst { lastFinalizedLocalId, sessionUuid } = session;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\t\tconst currentIdCount = lastFinalizedLocalId === undefined ? 0 : -lastFinalizedLocalId;\n\n\t\t\tconst cluster: Mutable<IdCluster> = {\n\t\t\t\tcapacity,\n\t\t\t\tcount,\n\t\t\t\tbaseUuid: incrementUuid(sessionUuid, currentIdCount),\n\t\t\t\tsession,\n\t\t\t};\n\n\t\t\tconst lastFinalizedNormalized = lastFinalizedLocalId ?? 0;\n\t\t\tconst clusterBase = compressor.nextClusterBaseFinalId;\n\n\t\t\tsession.lastFinalizedLocalId = (lastFinalizedNormalized - count) as LocalCompressedId;\n\t\t\tsession.currentClusterDetails = { clusterBase, cluster };\n\t\t\tcompressor.nextClusterBaseFinalId = (compressor.nextClusterBaseFinalId + capacity) as FinalCompressedId;\n\t\t\tcompressor.finalIdToCluster.append(clusterBase, cluster);\n\t\t\tcompressor.clustersAndOverridesInversion.set(stableIdFromNumericUuid(cluster.baseUuid), {\n\t\t\t\tclusterBase,\n\t\t\t\tcluster,\n\t\t\t});\n\n\t\t\tif (overrides !== undefined) {\n\t\t\t\tcluster.overrides = new Map();\n\t\t\t\tfor (const [finalIdIndex, override, originalOverridingFinal] of overrides) {\n\t\t\t\t\tconst finalId = (clusterBase + finalIdIndex) as FinalCompressedId;\n\t\t\t\t\tif (originalOverridingFinal !== undefined) {\n\t\t\t\t\t\tconst unifiedOverride: Mutable<UnifiedOverride> = {\n\t\t\t\t\t\t\toverride,\n\t\t\t\t\t\t\toriginalOverridingFinal,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (serializedLocalState !== undefined) {\n\t\t\t\t\t\t\tsetPropertyIfDefined(localOverridesInverse.get(override), unifiedOverride, 'associatedLocalId');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcluster.overrides.set(finalId, unifiedOverride);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst associatedLocal = localOverridesInverse.get(override);\n\t\t\t\t\t\tif (associatedLocal !== undefined && sessionId !== localSessionId) {\n\t\t\t\t\t\t\t// In this case, there is a local ID associated with this override, but this is the first cluster to contain\n\t\t\t\t\t\t\t// that override (because only the first cluster will have the string serialized). In this case, the override\n\t\t\t\t\t\t\t// needs to hold that local value.\n\t\t\t\t\t\t\tcluster.overrides.set(finalId, {\n\t\t\t\t\t\t\t\toverride,\n\t\t\t\t\t\t\t\toriginalOverridingFinal: finalId,\n\t\t\t\t\t\t\t\tassociatedLocalId: associatedLocal,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcluster.overrides.set(finalId, override);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst finalizedOverride: Mutable<FinalizedOverride> = {\n\t\t\t\t\t\t\tcluster,\n\t\t\t\t\t\t\toriginalOverridingFinal: finalId,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (serializedLocalState !== undefined) {\n\t\t\t\t\t\t\tsetPropertyIfDefined(associatedLocal, finalizedOverride, 'associatedLocalId');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcompressor.clustersAndOverridesInversion.set(IdCompressor.createInversionKey(override), finalizedOverride);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (serializedLocalState !== undefined) {\n\t\t\tcompressor.sessionIdNormalizer = SessionIdNormalizer.deserialize(\n\t\t\t\tserializedLocalState.sessionNormalizer,\n\t\t\t\t(finalId) => {\n\t\t\t\t\tconst [_, cluster] =\n\t\t\t\t\t\tcompressor.finalIdToCluster.getPairOrNextLower(finalId) ??\n\t\t\t\t\t\tfail('Final in serialized normalizer was never created.');\n\t\t\t\t\treturn cluster;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\tassertWithMessage(\n\t\t\tcompressor.localSession.lastFinalizedLocalId === undefined ||\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\t\t\tcompressor.localIdCount >= -compressor.localSession.lastFinalizedLocalId\n\t\t);\n\n\t\treturn compressor;\n\t}\n\n\t/**\n\t * Converts the given serialized compressor to the current version.\n\t * @param serializedCompressor - the serialized compressor to convert. Must not have been serialized with an ongoing session.\n\t * @returns a serialized compressor with no ongoing session.\n\t */\n\tpublic static convertToCurrentVersion(\n\t\tserializedCompressor: VersionedSerializedIdCompressor,\n\t\thasSession: false\n\t): SerializedIdCompressorWithNoSession;\n\n\t/**\n\t * Converts the given serialized compressor to the current version.\n\t * @param serializedCompressor - the serialized compressor to convert. Must have been serialized with an ongoing session.\n\t * @returns a serialized compressor with the same ongoing session.\n\t */\n\tpublic static convertToCurrentVersion(\n\t\tserializedCompressor: VersionedSerializedIdCompressor,\n\t\thasSession: true\n\t): SerializedIdCompressorWithOngoingSession;\n\n\tpublic static convertToCurrentVersion(\n\t\tserializedCompressor: VersionedSerializedIdCompressor,\n\t\thasSession: boolean\n\t): SerializedIdCompressor | undefined {\n\t\tif (serializedCompressor.version !== currentWrittenVersion) {\n\t\t\tfail('Unknown SerializedIdCompressor version number');\n\t\t}\n\t\tconst serialized = serializedCompressor as SerializedIdCompressorWithOngoingSession;\n\t\tif (hasSession !== hasOngoingSession(serialized)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn serialized;\n\t}\n}\n\n/**\n * The version of `IdCompressor` that is currently persisted.\n */\nconst currentWrittenVersion = '0.0.1';\n\n/**\n * @returns whether or not the given serialized ID compressor has an ongoing session.\n */\nexport function hasOngoingSession(\n\tserialized: SerializedIdCompressorWithNoSession | SerializedIdCompressorWithOngoingSession\n): serialized is SerializedIdCompressorWithOngoingSession {\n\treturn (serialized as Partial<SerializedIdCompressorWithOngoingSession>).localSessionIndex !== undefined;\n}\n\nfunction deserializeCluster(serializedCluster: SerializedCluster): {\n\tsessionIndex: number;\n\tcapacity: number;\n\tcount: number;\n\toverrides?: SerializedClusterOverrides;\n} {\n\tconst [sessionIndex, capacity, countOrOverrides, overrides] = serializedCluster;\n\tconst hasCount = typeof countOrOverrides === 'number';\n\n\treturn {\n\t\tsessionIndex,\n\t\tcapacity,\n\t\tcount: hasCount ? countOrOverrides : capacity,\n\t\toverrides: hasCount ? overrides : countOrOverrides,\n\t};\n}\n\n/**\n * Optimization used by the sorted-btree library to avoid allocating tuples every time a lookup method is called.\n * Lookup methods on BTree accept a pre-allocated array that it populates with the result of the lookup and retains no ownership\n * of after the call, so this array may be supplied to any of them. References to this array should not be retained elsewhere and\n * lookup results should be extracted from the tuple immediately after invocation.\n */\nconst reusedArray: [any, any] = [] as unknown as [any, any];\n"]}
1
+ {"version":3,"file":"IdCompressor.js","sourceRoot":"","sources":["../../src/id-compressor/IdCompressor.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 { ITelemetryBaseLogger } from '@fluidframework/core-interfaces';\nimport { assert } from '@fluidframework/core-utils/internal';\nimport { ITelemetryLoggerExt, createChildLogger } from '@fluidframework/telemetry-utils/internal';\nimport { BTree } from '@tylerbu/sorted-btree-es6';\n\nimport {\n\tMutable,\n\tassertNotUndefined,\n\tassertWithMessage,\n\tcompareFiniteNumbers,\n\tcompareFiniteNumbersReversed,\n\tcompareMaps,\n\tcompareStrings,\n\tfail,\n\tgetOrCreate,\n\thasLength,\n\tsetPropertyIfDefined,\n} from '../Common.js';\nimport {\n\tAttributionId,\n\tCompressedId,\n\tFinalCompressedId,\n\tLocalCompressedId,\n\tOpSpaceCompressedId,\n\tSessionId,\n\tSessionSpaceCompressedId,\n\tStableId,\n\tUuidString,\n} from '../Identifiers.js';\nimport { assertIsStableId, assertIsUuidString, isStableId } from '../UuidUtilities.js';\n\nimport { AppendOnlySortedMap } from './AppendOnlySortedMap.js';\nimport { getIds } from './IdRange.js';\nimport {\n\tNumericUuid,\n\tensureSessionUuid,\n\tgetPositiveDelta,\n\tincrementUuid,\n\tnumericUuidEquals,\n\tnumericUuidFromStableId,\n\tstableIdFromNumericUuid,\n} from './NumericUuid.js';\nimport { SessionIdNormalizer } from './SessionIdNormalizer.js';\nimport type {\n\tIdCreationRange,\n\tSerializedCluster,\n\tSerializedClusterOverrides,\n\tSerializedIdCompressor,\n\tSerializedIdCompressorWithNoSession,\n\tSerializedIdCompressorWithOngoingSession,\n\tSerializedLocalState,\n\tSerializedSessionData,\n\tUnackedLocalId,\n\tVersionedSerializedIdCompressor,\n} from './persisted-types/index.js';\n\n/**\n * A cluster of final (sequenced via consensus), sequentially allocated compressed IDs.\n * A final ID in a cluster decompresses to a UUID that is one of the following:\n * 1. A sequentially allocated UUID that is the result of adding its offset within the cluster to `baseUuid`.\n * 2. An override string (stored in `overrides`) specified at allocation time.\n */\ninterface IdCluster {\n\t/**\n\t * The UUID corresponding to the first final ID in the cluster.\n\t */\n\treadonly baseUuid: NumericUuid;\n\n\t/**\n\t * The total number of final IDs reserved for allocation in the cluster.\n\t * Clusters are reserved in blocks as a performance optimization.\n\t */\n\tcapacity: number;\n\n\t/**\n\t * The number of final IDs currently allocated in the cluster.\n\t */\n\tcount: number;\n\n\t/**\n\t * The session in which this cluster was created\n\t */\n\treadonly session: Session;\n\n\t/**\n\t * Final IDs assigned override strings within this cluster.\n\t * These are one of the following:\n\t *\n\t * 1. The override string\n\t *\n\t * 2. The override string and external override details. This occurs when local IDs corresponding to the same\n\t * override string are created by different sessions before any have been finalized. This can occur due to\n\t * concurrency or offline. In this case, the string is stored for the final ID that got sequenced first, and that\n\t * final ID is stored associated with all subsequent final IDs with the same override.\n\t *\n\t * When a final ID which is safely reserved via consensus as part of a cluster (but is not yet sequenced) is\n\t * allocated with an override, this collection will be temporarily inaccurate as it will not contain an entry for\n\t * that final ID. This absence indicates the uncertainty about what the final ID associated with that override will\n\t * be after finalizing the range (which could change due to unification of a concurrent duplicate override).\n\t * This table will be adjusted to reflect the override when that final ID is finalized via consensus, and\n\t * decompression will use `clustersAndOverridesInversion` until that point.\n\t */\n\toverrides?: Map<FinalCompressedId, string | UnifiedOverride>;\n}\n\ntype UnifiedOverride = OverrideCompressionDetails & {\n\toverride: string;\n};\n\n/**\n * Data about a SharedTree session.\n * Used to track and allocate identity clusters associated with a particular session ID.\n */\ninterface Session {\n\treadonly sessionUuid: NumericUuid;\n\n\t/**\n\t * `cluster` is undefined if a new cluster must be allocated when the session requests the next final ID allocation.\n\t */\n\tcurrentClusterDetails: { readonly clusterBase: FinalCompressedId; readonly cluster: IdCluster } | undefined;\n\n\t/**\n\t * The last local ID known to be finalized for this session.\n\t */\n\tlastFinalizedLocalId: LocalCompressedId | undefined;\n\n\t/**\n\t * The attribution ID for the session\n\t */\n\treadonly attributionId: AttributionId;\n}\n\n/**\n * Roughly equates to a minimum of 1M sessions before we start allocating 64 bit IDs.\n * This value must *NOT* change without careful consideration to compatibility.\n */\nexport const defaultClusterCapacity = 512;\n\n/**\n * The base UUID for the reserved id cluster.\n * This should not be changed without consideration to compatibility.\n */\nconst reservedSessionId = ensureSessionUuid(assertIsStableId('decaf40b-3c1a-47f8-a7a1-e8461ddb69ce'));\n\n/**\n * The ID override for the initial tree of a SharedTree. An artifact of an unfortunate typo which included an extraneous '6' on the UUID\n * which must be forever preserved for backwards compatibility.\n */\nexport const legacySharedTreeInitialTreeId = `24e26f0b-3c1a-47f8-a7a1-e8461ddb69ce6`;\n\n/**\n * @returns true if the supplied ID is a final ID.\n */\nexport function isFinalId(id: CompressedId): id is FinalCompressedId {\n\treturn id >= 0;\n}\n\n/**\n * @returns true if the supplied ID is a local ID.\n */\nexport function isLocalId(id: CompressedId): id is LocalCompressedId {\n\treturn id < 0;\n}\n\n/**\n * A cluster in `clustersAndOverridesInversion`, which is mapped from the first stable ID in a cluster.\n */\ninterface ClusterInfo {\n\treadonly clusterBase: FinalCompressedId;\n\treadonly cluster: IdCluster;\n}\n\ninterface OverrideCompressionDetails {\n\treadonly originalOverridingFinal: FinalCompressedId;\n\treadonly associatedLocalId?: LocalCompressedId;\n}\n\n/**\n * An override with a final ID associated with it.\n *\n * `associatedLocalId` is present on this type when a local ID in this session is associated with the override.\n *\n * It may be present even when `overriddenFinalId` was created by another session. This occurs when local IDs corresponding to the\n * same override string are created by different sessions before any have been finalized. `overriddenFinalId` will be set to\n * the *first* finalized ID with that string, but `associatedLocal` will be set to the local session's local ID for that string. This is\n * done to preserve the invariant that an override will always compress into the same session-space ID for the lifetime of the session.\n */\ninterface FinalizedOverride extends OverrideCompressionDetails {\n\treadonly cluster: IdCluster;\n}\n\n/**\n * The value of a mapping in `clustersAndOverridesInversion`, which maps an override to the cluster containing it (if finalized) or the\n * local ID corresponding to it (if unfinalized).\n *\n * Override strings associated with local IDs stored in `clustersAndOverridesInversion` are *always* replaced immediately upon finalizing,\n * and thus it is typed as op-space (unacked local).\n */\ntype Override = UnackedLocalId | FinalizedOverride;\n\ntype CompressionMapping = ClusterInfo | Override;\n\n/** Prepended to all keys in {@link IdCompressor.clustersAndOverridesInversion} that are override strings and not valid `StableIds` */\nconst nonStableOverridePrefix = '\\ue15e'; // A character in the Private Use Area of the BMP (https://en.wikipedia.org/wiki/Private_Use_Areas)\n\n/** Keys of {@link IdCompressor.clustersAndOverridesInversion} */\ntype InversionKey = `${typeof nonStableOverridePrefix}${string}` | StableId;\n\n/**\n * A distributed UUID generator and compressor.\n *\n * Generates arbitrary non-colliding v4 UUIDs, called stable IDs, for multiple \"sessions\" (which can be distributed across the network),\n * providing each session with the ability to map these UUIDs to `numbers`.\n *\n * A session is a unique identifier that denotes a single compressor. New IDs are created through a single compressor API\n * which should then sent in ranges to the server for total ordering (and are subsequently relayed to other clients). When a new ID is\n * created it is said to be created by the compressor's \"local\" session.\n *\n * For each stable ID created, two numeric IDs are provided by the compressor:\n *\n * 1. A local ID, which is stable for the lifetime of the session (which could be longer than that of the compressor object, as it may\n * be serialized for offline usage). Available as soon as the stable ID is allocated. Local IDs are session-unique and are thus only\n * publicly usable by the compressor that created the stable ID.\n *\n * 2. A final ID, which is stable across serialization and deserialization of an IdCompressor. Available as soon as the range containing\n * the corresponding local ID is totally ordered (via consensus) with respect to other sessions' allocations.\n * Final IDs are known to and publicly usable by any compressor that has received them.\n *\n * Compressors will allocate UUIDs in non-random ways to reduce entropy allowing for optimized storage of the data needed\n * to map the UUIDs to the numbers.\n *\n * A client may optionally supply an \"override\" for any generated ID, associating an arbitrary string with the local/final ID rather than\n * the UUID that would otherwise be created.\n *\n * The following invariants are upheld by IdCompressor:\n *\n * 1. Local IDs will always decompress to the same UUIDs (or override string) for the lifetime of the session.\n *\n * 2. Final IDs will always decompress to the same UUIDs (or override string).\n *\n * 3. After a server-processed range of local IDs (from any session) is received by a compressor, any of those local IDs may be\n * translated by the compressor into the corresponding final ID. For any given local ID, this translation will always yield the\n * same final ID.\n *\n * 4. A UUID (or override string) will always compress into the same session-space ID for the lifetime of the session.\n *\n * Local IDs are sent across the wire in efficiently-represented ranges. These ranges are created by querying the compressor, and *must*\n * be ordered (i.e. sent to the server) in the order they are created in order to preserve the above invariants.\n *\n * Session-local IDs can be used immediately after creation, but will eventually (after being sequenced) have a corresponding final ID. This\n * could make reasoning about equality of those two forms (the local and final) difficult. For example, if a cache is keyed off of a\n * local ID but is later queried using the final ID (which is semantically equal, as it decompresses to the same UUID/string) it will\n * produce a cache miss. In order to make using collections of both remotely created and locally created IDs easy, regardless of whether the\n * session-local IDs have been finalized, the compressor defines two \"spaces\" of IDs:\n *\n * 1. Session space: in this space, all IDs are normalized to their \"most local form\". This means that all IDs created by the local session\n * will be in local form, regardless of if they have been finalized. Remotely created IDs, which could only have been received after\n * finalizing and will never have a local form for the compressor, will of course be final IDs. This space should be used with consumer APIs\n * and data structures, as the lifetime of the IDs is guaranteed to be the same as the compressor object. Care must be taken to not use\n * these IDs across compressor objects, as the local IDs are specific to the compressor that created them.\n *\n * 2. Op space: in this space, all IDs are normalized to their \"most final form\". This means that all IDs except session-local IDs that\n * have not yet been finalized will be in final ID form. This space is useful for serialization in ops (e.g. references), as other clients\n * that receive them need not do any work to normalize them to *their* session-space in the common case. Note that IDs in op space may move\n * out of Op space over time, namely, when a local ID in this space becomes finalized, and thereafter has a \"more final form\".\n * Consequentially, it may be useful to restrict parameters of a persisted type to this space (to optimize perf), but it is potentially\n * incorrect to use this type for a runtime variable. This is an asymmetry that does not affect session space, as local IDs are always as\n * \"local as possible\".\n *\n * These two spaces naturally define a rule: consumers of compressed IDs should use session-space IDs, but serialized forms such as ops\n * should use op-space IDs.\n *\n */\nexport class IdCompressor {\n\t/**\n\t * Max allowed cluster size\n\t */\n\tpublic static maxClusterSize = 2 ** 20;\n\n\t/**\n\t * Trivially reach consensus on default cluster size and reserved IDs.\n\t * These initial values must *NOT* change without careful consideration to compatibility.\n\t */\n\tprivate newClusterCapacity = defaultClusterCapacity;\n\n\t/**\n\t * The size of each newly created ID cluster.\n\t */\n\tpublic get clusterCapacity(): number {\n\t\treturn this.newClusterCapacity;\n\t}\n\n\t/**\n\t * Must only be set with a value upon which consensus has been reached. Value must be greater than zero and less than\n\t * `IdCompressor.maxClusterSize`.\n\t */\n\tpublic set clusterCapacity(value: number) {\n\t\tassert(value > 0, 0x640 /* Clusters must have a positive capacity */);\n\t\tassert(value <= IdCompressor.maxClusterSize, 0x641 /* Clusters must not exceed max cluster size */);\n\t\tthis.newClusterCapacity = value;\n\t}\n\n\t/**\n\t * The UUID used for attribution of identities created by this compressor\n\t */\n\tpublic get attributionId(): AttributionId {\n\t\treturn this.localSession.attributionId;\n\t}\n\n\t/**\n\t * Session ID -\\> data about the session's current cluster.\n\t * Sessions are mutable, and thus should only be created via `createSession`.\n\t */\n\tprivate readonly sessions = new Map<SessionId, Session>();\n\n\t/**\n\t * The `IdCompressor`'s current local session.\n\t */\n\tprivate readonly localSession: Session;\n\n\t/**\n\t * The base final ID of the next cluster to be created.\n\t */\n\tprivate nextClusterBaseFinalId: FinalCompressedId = 0 as FinalCompressedId;\n\n\t/**\n\t * Total number of IDs created locally during the current session.\n\t */\n\tprivate localIdCount = 0;\n\n\t/**\n\t * The most recent (i.e. smallest, due to being negative) local ID in a range returned by `takeNextCreationRange`.\n\t * Undefined if no non-empty ranges have ever been returned by this compressor.\n\t */\n\tprivate lastTakenLocalId: LocalCompressedId | undefined;\n\n\t/**\n\t * Maps local IDs to override strings. This will contain an entry for every override assigned to a local ID generated during\n\t * the current session, and retains entries for the lifetime of this compressor.\n\t */\n\tprivate readonly localOverrides = new AppendOnlySortedMap<LocalCompressedId, string>(compareFiniteNumbersReversed);\n\n\t/**\n\t * Maps local IDs to the final ID they are associated with (if any), and maps final IDs to the corresponding local ID (if any).\n\t * This is used to efficiently compute normalization. This map can be thought of as mapping ranges of \"optimistic uncertainty\"\n\t * (local IDs) to the result of consensus (reserved ranges of final IDs, a.k.a. clusters). Any given range of local IDs\n\t * does not necessarily span an entire cluster, as some session-space IDs may be allocated *after* a cluster has been allocated\n\t * but before it is full. In this case, there is no uncertainty, as the range of final IDs was reserved when the cluster was created.\n\t * However, there is always a range of local IDs with size \\>= 1 associated with the beginning of every cluster, as clusters are only\n\t * created *after* they are needed and thus there is some period of uncertainty after local IDs have been handed out but before the\n\t * range containing them has been finalized. There may also be ranges of local IDs that do not start at the beginning of a\n\t * cluster; this happens when a cluster is expanded instead of allocating a new one.\n\t * Additionally, session space IDs associated with an override string will also always be local IDs, because there is uncertainty as\n\t * to whether another client simultaneously allocated the same override and could get sequenced first (a.k.a. unification) and its\n\t * final ID would be associated with that override.\n\t * See `SessionIdNormalizer` for more.\n\t */\n\tprivate sessionIdNormalizer = new SessionIdNormalizer<IdCluster>();\n\n\t/**\n\t * Contains entries for cluster base UUIDs and override strings (both local and final).\n\t * As a performance optimization, entries for finalized strings also include the containing cluster object.\n\t * This can be viewed as three separate tables: the inverse table for `localOverrides`, the inverse table for the union of all\n\t * the overrides of the clusters in `finalIdToCluster`, and the inverse lookup of cluster base UUIDs to their clusters.\n\t * This is unified as a performance optimization, as the common case does not have overridden IDs. It is a btree due to the need\n\t * to make range queries.\n\t */\n\tprivate readonly clustersAndOverridesInversion: BTree<InversionKey, CompressionMapping> = new BTree(\n\t\tundefined,\n\t\tcompareStrings\n\t);\n\n\t/**\n\t * Maps the first final ID in a cluster to its owning cluster.\n\t * Can be searched in O(log n) to determine clusters for any final ID.\n\t */\n\tprivate readonly finalIdToCluster: AppendOnlySortedMap<FinalCompressedId, IdCluster> = new AppendOnlySortedMap(\n\t\tcompareFiniteNumbers\n\t);\n\n\tprivate readonly logger: ITelemetryLoggerExt;\n\n\t/**\n\t * @param localSessionId - the `IdCompressor`'s current local session ID.\n\t * @param reservedIdCount - the number of IDs that will be known by this compressor without relying on consensus.\n\t * The reserved ID count for a given session must be constant for any compressor that contains IDs from that session\n\t * (i.e. any DDS that uses the ID compressor must have the same reservedIdCount forever). Compressors with different\n\t * reserved ID counts will fail to synchronize their IDs.\n\t * @param attributionId - a UUID that identifies the user of this instance of the compressor. IDs created by this\n\t * compressor will be associated with this UUID and can be queried later via `attributeID`. If no UUID is provided,\n\t * this compressor will generate its own. An `AttributionId` is an `UuidString` which may be validated via\n\t * {@link isUuidString} or generated via {@link generateStableId}.\n\t */\n\tpublic constructor(\n\t\tpublic readonly localSessionId: SessionId,\n\t\tpublic readonly reservedIdCount: number,\n\t\tattributionId?: AttributionId,\n\t\tlogger?: ITelemetryBaseLogger\n\t) {\n\t\tassert(reservedIdCount >= 0, 0x642 /* reservedIdCount must be non-negative */);\n\t\tif (attributionId !== undefined) {\n\t\t\tassertIsUuidString(attributionId);\n\t\t}\n\t\tthis.localSession = this.createSession(localSessionId, attributionId);\n\t\tif (reservedIdCount > 0) {\n\t\t\tconst clusterCapacity = this.clusterCapacity;\n\t\t\tthis.clusterCapacity = reservedIdCount;\n\t\t\tconst reservedIdRange: IdCreationRange = {\n\t\t\t\tsessionId: reservedSessionId,\n\t\t\t\tids: {\n\t\t\t\t\tlast: -reservedIdCount as UnackedLocalId,\n\t\t\t\t\toverrides: [[-1 as UnackedLocalId, legacySharedTreeInitialTreeId]], // Kludge: see `initialTreeId`\n\t\t\t\t},\n\t\t\t};\n\t\t\t// Reserved final IDs are implicitly finalized and no one locally created them, so finalizing immediately is safe.\n\t\t\tthis.finalizeCreationRange(reservedIdRange);\n\t\t\tthis.clusterCapacity = clusterCapacity;\n\t\t}\n\n\t\tthis.logger = createChildLogger({ logger });\n\t}\n\n\t/**\n\t * Creates a session object for the supplied ID.\n\t * Must only be called once per ID.\n\t * @param sessionId - the ID for the session\n\t * @returns the session object for the supplied ID\n\t */\n\tprivate createSession(sessionId: SessionId, attributionId: AttributionId | undefined): Session {\n\t\tassertWithMessage(!this.clustersAndOverridesInversion.has(sessionId));\n\t\tconst existingSession = this.sessions.get(sessionId);\n\t\tif (existingSession !== undefined) {\n\t\t\tfail('createSession must only be called once for each session ID.');\n\t\t}\n\t\tconst sessionUuid = numericUuidFromStableId(sessionId);\n\t\tconst session: Session = {\n\t\t\tsessionUuid,\n\t\t\tcurrentClusterDetails: undefined,\n\t\t\tlastFinalizedLocalId: undefined,\n\t\t\tattributionId: attributionId ?? sessionId,\n\t\t};\n\t\tthis.sessions.set(sessionId, session);\n\t\treturn session;\n\t}\n\n\t/**\n\t * Return the nth reserved ID.\n\t * @param index - the index of the ID to return\n\t */\n\tpublic getReservedId(index: number): SessionSpaceCompressedId & FinalCompressedId {\n\t\tif (index < 0 || index >= this.reservedIdCount) {\n\t\t\tfail('Reserved Id index out of bounds');\n\t\t}\n\n\t\t// All reserved IDs are contiguous and finalized during the Compressor's construction, therefore they are always the lowest\n\t\t// final IDs, beginning at 0\n\t\treturn index as SessionSpaceCompressedId & FinalCompressedId;\n\t}\n\n\t/**\n\t * Returns an iterable of all IDs created by this compressor.\n\t */\n\tpublic getAllIdsFromLocalSession(): IterableIterator<SessionSpaceCompressedId> {\n\t\treturn this.sessionIdNormalizer[Symbol.iterator]();\n\t}\n\n\t/**\n\t * Returns the attribution ID associated with the compressor that created the ID\n\t */\n\tpublic attributeId(id: SessionSpaceCompressedId): AttributionId {\n\t\tconst opSpaceNormalizedId = this.normalizeToOpSpace(id);\n\t\tif (isLocalId(opSpaceNormalizedId)) {\n\t\t\treturn this.attributionId;\n\t\t}\n\t\tconst closestCluster = this.getClusterForFinalId(opSpaceNormalizedId);\n\t\tif (closestCluster === undefined) {\n\t\t\tif (this.sessionIdNormalizer.getCreationIndex(opSpaceNormalizedId) !== undefined) {\n\t\t\t\treturn this.attributionId;\n\t\t\t} else {\n\t\t\t\tfail('Cluster does not exist for final ID');\n\t\t\t}\n\t\t}\n\t\tconst [_, cluster] = closestCluster;\n\t\treturn cluster.session.attributionId;\n\t}\n\n\t/**\n\t * Returns a range of local IDs created by this session in a format for sending to the server for finalizing.\n\t * The range will include all local IDs generated via calls to `generateCompressedId` since the last time this method was called.\n\t * @returns the range of session-local IDs, which may be empty. This range must be sent to the server for ordering before\n\t * it is finalized. Ranges must be sent to the server in the order that they are taken via calls to this method.\n\t */\n\tpublic takeNextCreationRange(): IdCreationRange {\n\t\tconst lastLocalInRange = -this.localIdCount as UnackedLocalId;\n\t\tconst lastTakenNormalized = this.lastTakenLocalId ?? 0;\n\t\tassertWithMessage(lastLocalInRange <= lastTakenNormalized);\n\n\t\t// The attribution ID is sent with each range, but it can be elided after the first IDs are allocated.\n\t\tconst sendAttributionId = this.lastTakenLocalId === undefined;\n\n\t\tlet ids: IdCreationRange.Ids | undefined;\n\t\tif (lastLocalInRange !== lastTakenNormalized) {\n\t\t\tconst firstLocalInRange = (lastTakenNormalized - 1) as UnackedLocalId;\n\t\t\tconst overrides = [\n\t\t\t\t...this.localOverrides.getRange(\n\t\t\t\t\t(lastTakenNormalized - 1) as LocalCompressedId,\n\t\t\t\t\tlastLocalInRange as LocalCompressedId\n\t\t\t\t),\n\t\t\t] as (readonly [UnackedLocalId, string])[];\n\t\t\tif (hasLength(overrides, 1)) {\n\t\t\t\tassertWithMessage(overrides[0][0] <= firstLocalInRange);\n\t\t\t\tassertWithMessage(overrides[overrides.length - 1][0] >= lastLocalInRange);\n\t\t\t\tids = {\n\t\t\t\t\toverrides,\n\t\t\t\t};\n\t\t\t\tconst first = firstLocalInRange === overrides[0][0] ? undefined : firstLocalInRange;\n\t\t\t\tconst last = lastLocalInRange === overrides[overrides.length - 1][0] ? undefined : lastLocalInRange;\n\t\t\t\tsetPropertyIfDefined(first, ids, 'first');\n\t\t\t\tsetPropertyIfDefined(last, ids, 'last');\n\t\t\t} else {\n\t\t\t\tids = {\n\t\t\t\t\tfirst: firstLocalInRange,\n\t\t\t\t\tlast: lastLocalInRange,\n\t\t\t\t};\n\t\t\t}\n\t\t\tthis.lastTakenLocalId = lastLocalInRange;\n\t\t}\n\n\t\tconst range: Mutable<IdCreationRange> = { sessionId: this.localSessionId };\n\t\tif (this.attributionId !== this.localSessionId && sendAttributionId) {\n\t\t\trange.attributionId = this.attributionId;\n\t\t}\n\n\t\tif (ids === undefined) {\n\t\t\treturn range;\n\t\t}\n\n\t\tassert(\n\t\t\tthis.lastTakenLocalId === -this.localIdCount && this.lastTakenLocalId !== lastTakenNormalized,\n\t\t\t0x643 /* Non-empty range must properly consume local IDs */\n\t\t);\n\n\t\trange.ids = ids;\n\t\treturn range;\n\t}\n\n\t/**\n\t * Finalizes the supplied range of IDs (which may be from either a remote or local session).\n\t * @param range - the range of session-local IDs to finalize.\n\t */\n\tpublic finalizeCreationRange(range: IdCreationRange): void {\n\t\tconst { sessionId, attributionId } = range;\n\n\t\tconst isLocal = sessionId === this.localSessionId;\n\t\tconst session = this.sessions.get(sessionId) ?? this.createSession(sessionId, attributionId);\n\t\tassert(\n\t\t\trange.attributionId === undefined || range.attributionId === session.attributionId,\n\t\t\t0x644 /* A session's attribution ID may never be modified. */\n\t\t);\n\n\t\tconst ids = getIds(range);\n\t\tif (ids === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { currentClusterDetails } = session;\n\t\tconst { cluster: currentCluster, clusterBase: currentBaseFinalId } = currentClusterDetails ?? {\n\t\t\tcluster: undefined,\n\t\t\tclusterBase: undefined,\n\t\t};\n\t\tconst currentClusterExists = currentCluster !== undefined && currentBaseFinalId !== undefined;\n\n\t\tconst normalizedLastFinalizedLocal = session.lastFinalizedLocalId ?? 0;\n\t\tconst { first: newFirstFinalizedLocal, last: newLastFinalizedLocal } = ids;\n\t\tassert(newFirstFinalizedLocal === normalizedLastFinalizedLocal - 1, 0x645 /* Ranges finalized out of order. */);\n\n\t\t// The total number of session-local IDs to finalize\n\t\tconst finalizeCount = normalizedLastFinalizedLocal - newLastFinalizedLocal;\n\t\tassert(finalizeCount >= 1, 0x646 /* Cannot finalize an empty range. */);\n\n\t\tlet eagerFinalIdCount = 0;\n\t\tlet initialClusterCount = 0;\n\t\tlet remainingCount = finalizeCount;\n\t\tlet newBaseUuid: NumericUuid | undefined;\n\t\tif (currentClusterExists) {\n\t\t\tif (isLocal) {\n\t\t\t\tconst lastKnownFinal =\n\t\t\t\t\tthis.sessionIdNormalizer.getLastFinalId() ??\n\t\t\t\t\tfail('Cluster exists but normalizer does not have an entry for it.');\n\t\t\t\tconst lastAlignedFinalInCluster = (currentBaseFinalId +\n\t\t\t\t\tMath.min(currentCluster.count + finalizeCount, currentCluster.capacity) -\n\t\t\t\t\t1) as FinalCompressedId;\n\t\t\t\tif (lastAlignedFinalInCluster > lastKnownFinal) {\n\t\t\t\t\tthis.sessionIdNormalizer.addFinalIds(\n\t\t\t\t\t\t(lastKnownFinal + 1) as FinalCompressedId,\n\t\t\t\t\t\tlastAlignedFinalInCluster,\n\t\t\t\t\t\tcurrentCluster\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tinitialClusterCount = currentCluster.count;\n\t\t\tconst remainingCapacity = currentCluster.capacity - initialClusterCount;\n\t\t\tconst overflow = remainingCount - remainingCapacity;\n\t\t\tconst hasRoom = overflow <= 0;\n\t\t\tif (hasRoom || currentBaseFinalId === this.finalIdToCluster.maxKey()) {\n\t\t\t\tcurrentCluster.count += remainingCount;\n\t\t\t\teagerFinalIdCount = remainingCount;\n\t\t\t\tremainingCount = 0;\n\t\t\t\t// The common case is that there is room in the cluster, and the new final IDs can simply be added to it\n\t\t\t\tif (!hasRoom) {\n\t\t\t\t\t// The cluster is full but is the last in the list of clusters.\n\t\t\t\t\t// This allows it to be expanded instead of allocating a new one.\n\t\t\t\t\tconst expansionAmount = this.newClusterCapacity + overflow;\n\t\t\t\t\tconst previousCapacity = currentCluster.capacity;\n\t\t\t\t\tcurrentCluster.capacity += expansionAmount;\n\t\t\t\t\tthis.nextClusterBaseFinalId = (this.nextClusterBaseFinalId + expansionAmount) as FinalCompressedId;\n\t\t\t\t\tassert(\n\t\t\t\t\t\tthis.nextClusterBaseFinalId < Number.MAX_SAFE_INTEGER,\n\t\t\t\t\t\t0x647 /* The number of allocated final IDs must not exceed the JS maximum safe integer. */\n\t\t\t\t\t);\n\t\t\t\t\tthis.checkClusterForCollision(currentCluster);\n\t\t\t\t\tif (isLocal) {\n\t\t\t\t\t\t// Example with cluster size of 3:\n\t\t\t\t\t\t// Ids generated so far: -1 1 2 -4 -5 <-- note positive numbers are eager finals\n\t\t\t\t\t\t// Cluster: [ 0 1 2 ]\n\t\t\t\t\t\t// ~ finalizing happens, causing expansion of 2 (overflow) + 3 (cluster capacity) ~\n\t\t\t\t\t\t// Cluster: [ 0 1 2 3 4 _ _ _ ]\n\t\t\t\t\t\t// corresponding locals: -1 -4 -5\n\t\t\t\t\t\t// lastFinalizedLocalId^ ^newLastFinalizedLocalId = -5\n\t\t\t\t\t\t// overflow = 2: ----\n\t\t\t\t\t\t// localIdPivot^\n\t\t\t\t\t\t// lastFinalizedFinal^\n\t\t\t\t\t\tconst newLastFinalizedFinal = (currentBaseFinalId + currentCluster.count - 1) as FinalCompressedId;\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\tsession.lastFinalizedLocalId !== undefined,\n\t\t\t\t\t\t\t0x648 /* Cluster already exists for session but there is no finalized local ID */\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst finalPivot = (newLastFinalizedFinal - overflow + 1) as FinalCompressedId;\n\t\t\t\t\t\t// Inform the normalizer of all IDs that we now know will end up being finalized into this cluster, including the ones\n\t\t\t\t\t\t// that were given out as locals (non-eager) because they exceeded the bounds of the current cluster before it was expanded.\n\t\t\t\t\t\t// It is safe to associate the unfinalized locals with their future final IDs even before the ranges for those locals are\n\t\t\t\t\t\t// actually finalized, because total order broadcast guarantees that any usage of those final IDs will be observed after\n\t\t\t\t\t\t// the finalization of the ranges.\n\t\t\t\t\t\tthis.sessionIdNormalizer.registerFinalIdBlock(finalPivot, expansionAmount, currentCluster);\n\t\t\t\t\t\tthis.logger?.sendTelemetryEvent({\n\t\t\t\t\t\t\teventName: 'SharedTreeIdCompressor:ClusterExpansion',\n\t\t\t\t\t\t\tsessionId: this.localSessionId,\n\t\t\t\t\t\t\tpreviousCapacity,\n\t\t\t\t\t\t\tnewCapacity: currentCluster.capacity,\n\t\t\t\t\t\t\toverflow,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// The range cannot be fully allocated in the existing cluster, so allocate any space left in it and\n\t\t\t\t// form a new one by incrementing the previous baseUuid\n\t\t\t\tnewBaseUuid = incrementUuid(currentCluster.baseUuid, currentCluster.capacity);\n\t\t\t\tcurrentCluster.count += remainingCapacity;\n\t\t\t\teagerFinalIdCount = remainingCapacity;\n\t\t\t\tremainingCount -= remainingCapacity;\n\t\t\t\tthis.logger?.sendTelemetryEvent({\n\t\t\t\t\teventName: 'SharedTreeIdCompressor:OverfilledCluster',\n\t\t\t\t\tsessionId: this.localSessionId,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\t// Session has never made a cluster, form a new one with the session UUID as the baseUuid\n\t\t\tnewBaseUuid = session.sessionUuid;\n\t\t\tif (isLocal) {\n\t\t\t\tthis.logger?.sendTelemetryEvent({\n\t\t\t\t\teventName: 'SharedTreeIdCompressor:FirstCluster',\n\t\t\t\t\tsessionId: this.localSessionId,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Finalizing a range results in one of three cases:\n\t\t// 1. All local IDs are finalized into a new cluster (because there was either never a cluster for that session, or the current\n\t\t//\t\tcluster for the session was full).\n\t\t// 2. All local IDs are finalized into the existing (current) cluster for the session.\n\t\t// 3. Local IDs are finalized into both the current cluster and a new one, as the current cluster did not have enough room.\n\t\tlet newCluster: IdCluster | undefined;\n\t\tlet newBaseFinalId: FinalCompressedId | undefined;\n\t\t// The first local ID that will be finalized into a new cluster, if there is one.\n\t\t// This lets us quickly compare which cluster an override string will go into.\n\t\tlet localIdPivot: LocalCompressedId | undefined;\n\n\t\t// Need to make a new cluster\n\t\tif (newBaseUuid !== undefined) {\n\t\t\tif (remainingCount <= 0) {\n\t\t\t\tfail('Should not create an empty cluster.');\n\t\t\t}\n\t\t\tif (currentCluster !== undefined && currentCluster.capacity !== currentCluster.count) {\n\t\t\t\tfail('Cluster must be filled before another is allocated.');\n\t\t\t}\n\n\t\t\tnewBaseFinalId = this.nextClusterBaseFinalId;\n\t\t\tconst newCapacity = Math.max(this.newClusterCapacity, remainingCount);\n\t\t\tnewCluster = {\n\t\t\t\tbaseUuid: newBaseUuid,\n\t\t\t\tcapacity: newCapacity,\n\t\t\t\tcount: remainingCount,\n\t\t\t\tsession,\n\t\t\t};\n\n\t\t\tconst usedCapacity = finalizeCount - remainingCount;\n\t\t\tlocalIdPivot = (newFirstFinalizedLocal - usedCapacity) as LocalCompressedId;\n\n\t\t\tif (isLocal) {\n\t\t\t\tthis.logger?.sendTelemetryEvent({\n\t\t\t\t\teventName: 'SharedTreeIdCompressor:NewCluster',\n\t\t\t\t\tsessionId: this.localSessionId,\n\t\t\t\t\tclusterCapacity: newCapacity,\n\t\t\t\t\tclusterCount: remainingCount,\n\t\t\t\t});\n\t\t\t\tthis.sessionIdNormalizer.registerFinalIdBlock(newBaseFinalId, newCluster.capacity, newCluster);\n\t\t\t}\n\n\t\t\tthis.checkClusterForCollision(newCluster);\n\t\t\tthis.clustersAndOverridesInversion.set(stableIdFromNumericUuid(newCluster.baseUuid), {\n\t\t\t\tclusterBase: newBaseFinalId,\n\t\t\t\tcluster: newCluster,\n\t\t\t});\n\t\t\tsession.currentClusterDetails = { cluster: newCluster, clusterBase: newBaseFinalId };\n\t\t\tthis.nextClusterBaseFinalId = (this.nextClusterBaseFinalId + newCluster.capacity) as FinalCompressedId;\n\t\t\tassert(\n\t\t\t\tthis.nextClusterBaseFinalId < Number.MAX_SAFE_INTEGER,\n\t\t\t\t0x649 /* The number of allocated final IDs must not exceed the JS maximum safe integer. */\n\t\t\t);\n\t\t\tthis.finalIdToCluster.append(newBaseFinalId, newCluster);\n\t\t}\n\n\t\t// If there are overrides, we must determine which cluster object (current or overflow) each belongs to and add it.\n\t\tconst overrides = ids.overrides;\n\t\tif (overrides !== undefined) {\n\t\t\tfor (let i = 0; i < overrides.length; i++) {\n\t\t\t\tconst [overriddenLocal, override] = overrides[i];\n\t\t\t\t// Note: recall that local IDs are negative\n\t\t\t\tassert(i === 0 || overriddenLocal < overrides[i - 1][0], 0x64a /* Override IDs must be in sorted order. */);\n\t\t\t\tassert(overriddenLocal < normalizedLastFinalizedLocal, 0x64b /* Ranges finalized out of order. */);\n\t\t\t\tassert(\n\t\t\t\t\toverriddenLocal >= newLastFinalizedLocal,\n\t\t\t\t\t0x64c /* Malformed range: override ID ahead of range start. */\n\t\t\t\t);\n\t\t\t\tlet cluster: IdCluster;\n\t\t\t\tlet overriddenFinal: FinalCompressedId;\n\t\t\t\tif (localIdPivot !== undefined && overriddenLocal <= localIdPivot) {\n\t\t\t\t\t// Override is at or past the pivot, so it is in a new cluster.\n\t\t\t\t\tassert(\n\t\t\t\t\t\tnewCluster !== undefined && newBaseFinalId !== undefined,\n\t\t\t\t\t\t0x64d /* No cluster was created when overflow occurred. */\n\t\t\t\t\t);\n\t\t\t\t\tcluster = newCluster;\n\t\t\t\t\toverriddenFinal = (newBaseFinalId + (localIdPivot - overriddenLocal)) as FinalCompressedId;\n\t\t\t\t} else {\n\t\t\t\t\t// Override was finalized into an existing cluster\n\t\t\t\t\tassert(\n\t\t\t\t\t\tcurrentCluster !== undefined && currentBaseFinalId !== undefined,\n\t\t\t\t\t\t0x64e /* No cluster exists but IDs were finalized. */\n\t\t\t\t\t);\n\t\t\t\t\tcluster = currentCluster;\n\t\t\t\t\toverriddenFinal = (currentBaseFinalId +\n\t\t\t\t\t\tinitialClusterCount +\n\t\t\t\t\t\t(normalizedLastFinalizedLocal - overriddenLocal) -\n\t\t\t\t\t\t1) as FinalCompressedId;\n\t\t\t\t}\n\t\t\t\tcluster.overrides ??= new Map();\n\n\t\t\t\tconst inversionKey = IdCompressor.createInversionKey(override);\n\t\t\t\tconst existingIds = this.getExistingIdsForNewOverride(inversionKey, true);\n\t\t\t\tlet overrideForCluster: string | FinalCompressedId;\n\t\t\t\tlet associatedLocal: LocalCompressedId | undefined;\n\t\t\t\tif (existingIds !== undefined) {\n\t\t\t\t\tlet mostFinalExistingOverride: CompressedId;\n\t\t\t\t\tif (typeof existingIds === 'number') {\n\t\t\t\t\t\tmostFinalExistingOverride = existingIds;\n\t\t\t\t\t\tif (isLocalId(mostFinalExistingOverride)) {\n\t\t\t\t\t\t\tassociatedLocal = mostFinalExistingOverride;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t[associatedLocal, mostFinalExistingOverride] = existingIds;\n\t\t\t\t\t}\n\t\t\t\t\tif (isFinalId(mostFinalExistingOverride)) {\n\t\t\t\t\t\t// A previous range already finalized an ID with this override. See `IdCluster` for more.\n\t\t\t\t\t\toverrideForCluster = mostFinalExistingOverride;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\t!isLocal || mostFinalExistingOverride === overriddenLocal,\n\t\t\t\t\t\t\t0x64f /* Cannot have multiple local IDs with identical overrides. */\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// This session has created an ID with this override before, but has not finalized it yet. The incoming\n\t\t\t\t\t\t// range \"wins\" and will contain the final ID associated with that override, regardless of if that range was\n\t\t\t\t\t\t// made by this session or not.\n\t\t\t\t\t\toverrideForCluster = override;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// This is the first time this override has been associated with any ID\n\t\t\t\t\toverrideForCluster = override;\n\t\t\t\t}\n\n\t\t\t\tassert(!cluster.overrides.has(overriddenFinal), 0x650 /* Cannot add a second override for final id */);\n\t\t\t\tif (typeof overrideForCluster === 'string') {\n\t\t\t\t\tif (isLocal || associatedLocal === undefined) {\n\t\t\t\t\t\tcluster.overrides.set(overriddenFinal, override);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcluster.overrides.set(overriddenFinal, {\n\t\t\t\t\t\t\toverride,\n\t\t\t\t\t\t\toriginalOverridingFinal: overriddenFinal,\n\t\t\t\t\t\t\tassociatedLocalId: associatedLocal,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst unifiedOverride: UnifiedOverride = {\n\t\t\t\t\t\toverride,\n\t\t\t\t\t\toriginalOverridingFinal: overrideForCluster,\n\t\t\t\t\t};\n\t\t\t\t\tsetPropertyIfDefined(associatedLocal, unifiedOverride, 'associatedLocalId');\n\t\t\t\t\tcluster.overrides.set(overriddenFinal, unifiedOverride);\n\t\t\t\t}\n\t\t\t\tconst finalizedOverride: Mutable<FinalizedOverride> = {\n\t\t\t\t\tcluster,\n\t\t\t\t\toriginalOverridingFinal: overriddenFinal,\n\t\t\t\t};\n\t\t\t\tsetPropertyIfDefined(associatedLocal, finalizedOverride, 'associatedLocalId');\n\t\t\t\tconst currentOverride = this.clustersAndOverridesInversion.get(inversionKey);\n\t\t\t\tif (currentOverride === undefined || IdCompressor.isUnfinalizedOverride(currentOverride)) {\n\t\t\t\t\t// Update the map to contain a finalized override, but never update it with future finalized overrides with\n\t\t\t\t\t// the same string; those should decompress to the first final ID with that override.\n\t\t\t\t\tthis.clustersAndOverridesInversion.set(inversionKey, finalizedOverride);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\tthis.logger?.sendTelemetryEvent({\n\t\t\t\teventName: 'SharedTreeIdCompressor:IdCompressorStatus',\n\t\t\t\teagerFinalIdCount: eagerFinalIdCount - (overrides?.length ?? 0),\n\t\t\t\tlocalIdCount: remainingCount + (overrides?.length ?? 0),\n\t\t\t\toverridesCount: overrides?.length ?? 0,\n\t\t\t\tsessionId: this.localSessionId,\n\t\t\t});\n\t\t}\n\n\t\tsession.lastFinalizedLocalId = newLastFinalizedLocal;\n\t}\n\n\tprivate checkClusterForCollision(cluster: IdCluster): void {\n\t\tconst maxClusterUuid = incrementUuid(cluster.baseUuid, cluster.capacity - 1);\n\t\tconst maxClusterStableId = stableIdFromNumericUuid(maxClusterUuid);\n\t\tconst closestMatch = this.clustersAndOverridesInversion.getPairOrNextLower(maxClusterStableId);\n\t\tif (closestMatch !== undefined) {\n\t\t\tconst [inversionKey, compressionMapping] = closestMatch;\n\t\t\tif (!IdCompressor.isClusterInfo(compressionMapping)) {\n\t\t\t\tif (\n\t\t\t\t\tisStableId(inversionKey) &&\n\t\t\t\t\tIdCompressor.uuidsMightCollide(inversionKey, maxClusterStableId, cluster.capacity)\n\t\t\t\t) {\n\t\t\t\t\tconst numericOverride = numericUuidFromStableId(inversionKey);\n\t\t\t\t\tconst delta = getPositiveDelta(maxClusterUuid, numericOverride, cluster.capacity - 1);\n\t\t\t\t\tif (delta !== undefined) {\n\t\t\t\t\t\tIdCompressor.failWithCollidingOverride(inversionKey);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static failWithCollidingOverride(override: string): void {\n\t\tfail(`Override '${override}' collides with another allocated UUID.`);\n\t}\n\n\tprivate static isClusterInfo(compressionMapping: CompressionMapping): compressionMapping is ClusterInfo {\n\t\treturn (compressionMapping as ClusterInfo).clusterBase !== undefined;\n\t}\n\n\tprivate static isUnfinalizedOverride(compressionMapping: CompressionMapping): compressionMapping is UnackedLocalId {\n\t\treturn typeof compressionMapping === 'number';\n\t}\n\n\tprivate static createInversionKey(inversionKey: string): InversionKey {\n\t\treturn isStableId(inversionKey) ? inversionKey : `${nonStableOverridePrefix}${inversionKey}`;\n\t}\n\n\tprivate static isStableInversionKey(inversionKey: InversionKey): inversionKey is StableId {\n\t\treturn !inversionKey.startsWith(nonStableOverridePrefix);\n\t}\n\n\t/**\n\t * Returns an existing ID associated with an override, or undefined if none exists.\n\t */\n\tprivate getExistingIdsForNewOverride(\n\t\tinversionKey: InversionKey,\n\t\tisFinalOverride: boolean\n\t): SessionSpaceCompressedId | [LocalCompressedId, FinalCompressedId] | undefined {\n\t\tconst closestMatch = this.clustersAndOverridesInversion.getPairOrNextLower(inversionKey, reusedArray);\n\t\tlet numericOverride: NumericUuid | undefined;\n\t\tlet stableOverride: StableId | undefined;\n\t\tif (closestMatch !== undefined) {\n\t\t\tconst [key, compressionMapping] = closestMatch;\n\t\t\tif (!IdCompressor.isClusterInfo(compressionMapping)) {\n\t\t\t\tif (key === inversionKey) {\n\t\t\t\t\tif (IdCompressor.isUnfinalizedOverride(compressionMapping)) {\n\t\t\t\t\t\treturn compressionMapping;\n\t\t\t\t\t}\n\t\t\t\t\tconst finalizedOverride = compressionMapping;\n\t\t\t\t\treturn finalizedOverride.associatedLocalId !== undefined\n\t\t\t\t\t\t? [finalizedOverride.associatedLocalId, finalizedOverride.originalOverridingFinal]\n\t\t\t\t\t\t: (finalizedOverride.originalOverridingFinal as SessionSpaceCompressedId);\n\t\t\t\t}\n\t\t\t} else if (IdCompressor.isStableInversionKey(inversionKey)) {\n\t\t\t\tstableOverride = inversionKey;\n\t\t\t\tconst cluster = compressionMapping.cluster;\n\t\t\t\tif (IdCompressor.uuidsMightCollide(inversionKey, key as StableId, cluster.capacity)) {\n\t\t\t\t\tnumericOverride = numericUuidFromStableId(stableOverride);\n\t\t\t\t\tconst delta = getPositiveDelta(numericOverride, cluster.baseUuid, cluster.capacity - 1);\n\t\t\t\t\tif (delta !== undefined) {\n\t\t\t\t\t\tif (!isFinalOverride) {\n\t\t\t\t\t\t\tif (delta >= cluster.count) {\n\t\t\t\t\t\t\t\t// TODO:#283: Properly implement unification\n\t\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn this.normalizeToSessionSpace((compressionMapping.clusterBase + delta) as FinalCompressedId);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst override =\n\t\t\tnumericOverride ?? stableOverride ?? (IdCompressor.isStableInversionKey(inversionKey) ? inversionKey : undefined);\n\n\t\tif (override !== undefined) {\n\t\t\tconst sessionSpaceId = this.getCompressedIdForStableId(override);\n\t\t\tif (sessionSpaceId !== undefined) {\n\t\t\t\treturn sessionSpaceId;\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Check if `a` might be within `range` of `b`, where both are treated as hex numbers.\n\t * @param range - an integer\n\t */\n\tprivate static uuidsMightCollide(a: StableId, b: StableId, range: number): boolean {\n\t\t// Check if any of the UUIDs in the cluster collide (i.e. any in [base, base + capacity)).\n\t\t// Optimization: All UUIDs in a cluster are the same string up until the last few characters which encode the offset from\n\t\t// the cluster base. So, first compute the length of that shared string, and early out if it is different from the override\n\t\t// UUID. This way we usually need not do the more expensive check below.\n\t\tconst hexDigitsToCheck = 32 - Math.ceil(Math.log2(range) / 2);\n\t\tif (a.startsWith(b.slice(0, hexDigitsToCheck))) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Helper for retrieving an override.\n\t */\n\tprivate static tryGetOverride(cluster: IdCluster, finalId: FinalCompressedId): string | undefined {\n\t\tconst override = cluster.overrides?.get(finalId);\n\t\tif (override === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (typeof override === 'string') {\n\t\t\treturn override;\n\t\t}\n\t\treturn override.override;\n\t}\n\n\t/**\n\t * Generates a new compressed ID or returns an existing one.\n\t * This should ONLY be called to generate IDs for local operations.\n\t * @param override - Specifies a specific string to be associated with the returned compressed ID.\n\t * Performance note: assigning override strings incurs a performance overhead.\n\t * @returns an existing ID if one already exists for `override`, and a new local ID otherwise. The returned ID is in session space.\n\t */\n\tpublic generateCompressedId(override?: string): SessionSpaceCompressedId {\n\t\tlet overrideInversionKey: InversionKey | undefined;\n\t\tif (override !== undefined) {\n\t\t\toverrideInversionKey = IdCompressor.createInversionKey(override);\n\t\t\tconst existingIds = this.getExistingIdsForNewOverride(overrideInversionKey, false);\n\t\t\tif (existingIds !== undefined) {\n\t\t\t\treturn typeof existingIds === 'number' ? existingIds : existingIds[0];\n\t\t\t}\n\t\t}\n\n\t\t// Bump local counter regardless, then attempt to optimistically return a final ID.\n\t\t// If the local session has reserved a cluster range via consensus, it is safe to hand out final IDs prior to\n\t\t// finalizing the range that includes these locals.\n\t\tconst newLocalId = -++this.localIdCount as LocalCompressedId;\n\t\tconst { currentClusterDetails } = this.localSession;\n\t\tconst { sessionIdNormalizer } = this;\n\t\tlet eagerFinalId: (FinalCompressedId & SessionSpaceCompressedId) | undefined;\n\t\tlet cluster: IdCluster | undefined;\n\t\tif (currentClusterDetails !== undefined) {\n\t\t\tcluster = currentClusterDetails.cluster;\n\t\t\tconst lastFinalKnown = sessionIdNormalizer.getLastFinalId();\n\t\t\tif (lastFinalKnown !== undefined && lastFinalKnown - currentClusterDetails.clusterBase + 1 < cluster.capacity) {\n\t\t\t\teagerFinalId = (lastFinalKnown + 1) as FinalCompressedId & SessionSpaceCompressedId;\n\t\t\t}\n\t\t}\n\n\t\tif (overrideInversionKey !== undefined) {\n\t\t\tconst registeredLocal = sessionIdNormalizer.addLocalId();\n\t\t\tassert(registeredLocal === newLocalId, 0x651 /* Session ID Normalizer produced unexpected local ID */);\n\t\t\tif (eagerFinalId !== undefined) {\n\t\t\t\tsessionIdNormalizer.addFinalIds(eagerFinalId, eagerFinalId, cluster ?? fail());\n\t\t\t}\n\t\t\tthis.localOverrides.append(newLocalId, override ?? fail());\n\t\t\t// Since the local ID was just created, it is in both session and op space\n\t\t\tconst compressionMapping = newLocalId as UnackedLocalId;\n\t\t\tthis.clustersAndOverridesInversion.set(overrideInversionKey, compressionMapping);\n\t\t} else if (eagerFinalId !== undefined) {\n\t\t\tsessionIdNormalizer.addFinalIds(eagerFinalId, eagerFinalId, cluster ?? fail());\n\t\t\treturn eagerFinalId;\n\t\t} else {\n\t\t\tconst registeredLocal = sessionIdNormalizer.addLocalId();\n\t\t\tassert(registeredLocal === newLocalId, 0x652 /* Session ID Normalizer produced unexpected local ID */);\n\t\t}\n\n\t\treturn newLocalId;\n\t}\n\n\t/**\n\t * Decompresses a previously compressed ID into a UUID or override string.\n\t * @param id - the compressed ID to be decompressed.\n\t * @returns the UUID or override string associated with the compressed ID. Fails if the ID was not generated by this compressor.\n\t */\n\tpublic decompress(id: SessionSpaceCompressedId | FinalCompressedId): StableId | string {\n\t\treturn this.tryDecompress(id) ?? fail('Compressed ID was not generated by this compressor');\n\t}\n\n\t/**\n\t * Attempts to decompress a previously compressed ID into a UUID or override string.\n\t * @param id - the compressed ID to be decompressed.\n\t * @returns the UUID or override string associated with the compressed ID, or undefined if the ID was not generated by this compressor.\n\t */\n\tpublic tryDecompress(id: SessionSpaceCompressedId | FinalCompressedId): StableId | string | undefined {\n\t\tif (isFinalId(id)) {\n\t\t\tconst possibleCluster = this.getClusterForFinalId(id);\n\t\t\tif (possibleCluster === undefined) {\n\t\t\t\t// It may be an unfinalized eager final ID, so check with normalizer to get the offset from the session UUID\n\t\t\t\tconst creationIndex = this.sessionIdNormalizer.getCreationIndex(id);\n\t\t\t\tif (creationIndex !== undefined) {\n\t\t\t\t\treturn stableIdFromNumericUuid(this.localSession.sessionUuid, creationIndex);\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t} else {\n\t\t\t\tconst [baseFinalId, cluster] = possibleCluster;\n\t\t\t\tconst override = IdCompressor.tryGetOverride(cluster, id);\n\t\t\t\tif (override !== undefined) {\n\t\t\t\t\treturn override;\n\t\t\t\t} else {\n\t\t\t\t\tconst offsetInCluster = id - baseFinalId;\n\t\t\t\t\treturn stableIdFromNumericUuid(cluster.baseUuid, offsetInCluster);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\t\tconst idOffset = -id; // Convert to a positive number\n\t\t\tif (idOffset > this.localIdCount) {\n\t\t\t\t// This local ID was never allocated.\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// If this is a local ID with an override, then it must have been allocated on this machine and will be contained in\n\t\t\t// `localOverrides`s. Otherwise, it is a sequential allocation from the session UUID and can simply be negated and\n\t\t\t// added to that UUID to obtain the stable ID associated with it.\n\t\t\tconst localOverride = this.localOverrides?.get(id);\n\t\t\treturn localOverride ?? stableIdFromNumericUuid(this.localSession.sessionUuid, idOffset - 1);\n\t\t}\n\t}\n\n\t/**\n\t * Recompresses a decompressed ID, which could be a UUID or an override string.\n\t * @param uncompressed - the UUID or override string to recompress.\n\t * @returns the `CompressedId` associated with `uncompressed`. Fails if it has not been previously compressed by this compressor.\n\t */\n\tpublic recompress(uncompressed: string): SessionSpaceCompressedId {\n\t\treturn this.tryRecompress(uncompressed) ?? fail('No such string has ever been compressed');\n\t}\n\n\t/**\n\t * Attempts to recompresses a decompressed ID, which could be a UUID or an override string.\n\t * @param uncompressed - the UUID or override string to recompress,\n\t * @returns the `CompressedId` associated with `uncompressed` or undefined if it has not been previously compressed by this compressor.\n\t */\n\tpublic tryRecompress(uncompressed: string): SessionSpaceCompressedId | undefined {\n\t\treturn this.recompressInternal(uncompressed);\n\t}\n\n\t/**\n\t * Helper to compress an uncompressed UUID. It can optionally be supplied with the numeric form of `uncompressedUuid` as a\n\t * performance optimization.\n\t */\n\tprivate recompressInternal(\n\t\tuncompressed: string,\n\t\tuncompressedUuidNumeric?: NumericUuid\n\t): SessionSpaceCompressedId | undefined {\n\t\tlet numericUuid = uncompressedUuidNumeric;\n\t\tconst inversionKey = IdCompressor.createInversionKey(uncompressed);\n\t\tconst isStable = IdCompressor.isStableInversionKey(inversionKey);\n\t\tconst closestMatch = this.clustersAndOverridesInversion.getPairOrNextLower(inversionKey, reusedArray);\n\t\tif (closestMatch !== undefined) {\n\t\t\tconst [key, compressionMapping] = closestMatch;\n\t\t\tif (!IdCompressor.isClusterInfo(compressionMapping)) {\n\t\t\t\tif (key === inversionKey) {\n\t\t\t\t\treturn IdCompressor.isUnfinalizedOverride(compressionMapping)\n\t\t\t\t\t\t? compressionMapping\n\t\t\t\t\t\t: (compressionMapping.associatedLocalId ??\n\t\t\t\t\t\t\t\t(compressionMapping.originalOverridingFinal as SessionSpaceCompressedId));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (!isStable) {\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\t\t\t\tconst { clusterBase: closestBaseFinalId, cluster: closestCluster } = compressionMapping;\n\t\t\t\tnumericUuid ??= numericUuidFromStableId(inversionKey);\n\t\t\t\tconst uuidOffset = getPositiveDelta(numericUuid, closestCluster.baseUuid, closestCluster.count - 1);\n\t\t\t\tif (uuidOffset !== undefined) {\n\t\t\t\t\tlet targetFinalId = (closestBaseFinalId + uuidOffset) as FinalCompressedId;\n\t\t\t\t\tconst override = closestCluster.overrides?.get(targetFinalId);\n\t\t\t\t\tif (typeof override === 'object') {\n\t\t\t\t\t\tif (override.associatedLocalId !== undefined) {\n\t\t\t\t\t\t\treturn override.associatedLocalId;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// This may be a UUID that should actually compress into a different final ID that it aligns with, due to\n\t\t\t\t\t\t// another session having an identical override (see `IdCluster` for more).\n\t\t\t\t\t\ttargetFinalId = override.originalOverridingFinal;\n\t\t\t\t\t}\n\t\t\t\t\treturn this.normalizeToSessionSpace(targetFinalId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (isStable) {\n\t\t\t// May have already computed the numeric UUID, so avoid recomputing if possible\n\t\t\tconst sessionSpaceId = this.getCompressedIdForStableId(numericUuid ?? inversionKey);\n\t\t\tif (sessionSpaceId !== undefined) {\n\t\t\t\treturn sessionSpaceId;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Normalizes a session space ID into op space.\n\t * @param id - the local ID to normalize.\n\t * @returns the ID in op space.\n\t */\n\tpublic normalizeToOpSpace(id: SessionSpaceCompressedId): OpSpaceCompressedId {\n\t\tif (isFinalId(id)) {\n\t\t\treturn id;\n\t\t}\n\n\t\t// Check if this local ID has not been allocated yet\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\tif (-id > this.localIdCount) {\n\t\t\tfail('Supplied local ID was not created by this compressor.');\n\t\t}\n\n\t\t// Check if this local ID has not been finalized yet.\n\t\t// Comparing lastFinalizedLocalId is a safe check for eager final IDs because the local IDs corresponding to them\n\t\t// are never handed out to a consumer, and thus could not be passed into this method.\n\t\tconst { lastFinalizedLocalId } = this.localSession;\n\t\tif (lastFinalizedLocalId === undefined || id < lastFinalizedLocalId) {\n\t\t\t// Eager final IDs do not have overrides in the cluster until finalizing\n\t\t\t// This means that using the normalizer to get the final/cluster associated would succeed but would not have the override,\n\t\t\t// so checking localOverrides first is necessary.\n\t\t\tconst override = this.localOverrides.get(id);\n\t\t\tif (override !== undefined) {\n\t\t\t\tconst inversionKey = IdCompressor.createInversionKey(override);\n\t\t\t\tconst compressionMapping = this.clustersAndOverridesInversion.get(inversionKey) ?? fail('Bimap is malformed.');\n\t\t\t\treturn !IdCompressor.isClusterInfo(compressionMapping) &&\n\t\t\t\t\t!IdCompressor.isUnfinalizedOverride(compressionMapping) &&\n\t\t\t\t\tcompressionMapping.associatedLocalId === id\n\t\t\t\t\t? compressionMapping.originalOverridingFinal\n\t\t\t\t\t: (id as OpSpaceCompressedId);\n\t\t\t}\n\t\t\tconst possibleFinal = this.sessionIdNormalizer.getFinalId(id);\n\t\t\treturn possibleFinal?.[0] ?? (id as OpSpaceCompressedId);\n\t\t}\n\t\tconst [correspondingFinal, cluster] =\n\t\t\tthis.sessionIdNormalizer.getFinalId(id) ??\n\t\t\tfail('Locally created cluster should be added to the map when allocated');\n\t\tif (cluster.overrides) {\n\t\t\tconst override = cluster.overrides.get(correspondingFinal);\n\t\t\tif (typeof override === 'object' && override.originalOverridingFinal !== undefined) {\n\t\t\t\t// Rare case of two local IDs with same overrides are created concurrently. See `IdCluster` for more.\n\t\t\t\treturn override.originalOverridingFinal;\n\t\t\t}\n\t\t}\n\t\treturn correspondingFinal;\n\t}\n\n\t/**\n\t * Normalizes an ID into session space.\n\t * @param id - the ID to normalize. If it is a local ID, it is assumed to have been created by the session corresponding\n\t * to `sessionId`.\n\t * @param originSessionId - the session from which `id` originated\n\t * @returns the session-space ID corresponding to `id`, which might not have been a final ID if the client that created it had not yet\n\t * finalized it. This can occur when a client references an ID during the window of time in which it is waiting to receive the ordered\n\t * range that contained it from the server.\n\t */\n\tpublic normalizeToSessionSpace(id: OpSpaceCompressedId, originSessionId: SessionId): SessionSpaceCompressedId;\n\n\t/**\n\t * Normalizes a final ID into session space.\n\t * @param id - the final ID to normalize.\n\t * @returns the session-space ID corresponding to `id`.\n\t */\n\tpublic normalizeToSessionSpace(id: FinalCompressedId): SessionSpaceCompressedId;\n\n\tpublic normalizeToSessionSpace(id: OpSpaceCompressedId, sessionIdIfLocal?: SessionId): SessionSpaceCompressedId {\n\t\tif (isLocalId(id)) {\n\t\t\tif (sessionIdIfLocal === undefined || sessionIdIfLocal === this.localSessionId) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\t\t\tconst localIndex = -id;\n\t\t\t\tif (localIndex > this.localIdCount) {\n\t\t\t\t\tfail('Supplied local ID was not created by this compressor.');\n\t\t\t\t}\n\t\t\t\treturn id;\n\t\t\t} else {\n\t\t\t\tconst session =\n\t\t\t\t\tthis.sessions.get(sessionIdIfLocal) ?? fail('No IDs have ever been finalized by the supplied session.');\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\t\t\tconst localCount = -id;\n\t\t\t\tconst numericUuid = incrementUuid(session.sessionUuid, localCount - 1);\n\t\t\t\treturn this.compressNumericUuid(numericUuid) ?? fail('ID is not known to this compressor.');\n\t\t\t}\n\t\t}\n\n\t\tconst normalizedId = this.sessionIdNormalizer.getSessionSpaceId(id);\n\t\tif (normalizedId !== undefined) {\n\t\t\treturn normalizedId;\n\t\t}\n\n\t\t// Check for a unified override finalized first by another session but to which the local session\n\t\t// still has an associated local ID.\n\t\tconst [_, cluster] =\n\t\t\tthis.getClusterForFinalId(id) ?? fail('Supplied final ID was not finalized by this compressor.');\n\t\tconst override = cluster.overrides?.get(id);\n\t\tif (typeof override === 'object' && override.associatedLocalId !== undefined) {\n\t\t\treturn override.associatedLocalId;\n\t\t}\n\t\treturn id as SessionSpaceCompressedId;\n\t}\n\n\t/**\n\t * Returns the session-space compressed ID corresponding to the numeric UUID, or undefined if it is not known to this compressor.\n\t * Typically, it will return the session-space ID sequentially aligned with it (which will be local if `numericUuid` was made by\n\t * the local session, or final otherwise). However, in the event that the aligned session-space ID was overridden with a UUID\n\t * *and* that override UUID was concurrently used in an older ID (earlier, w.r.t. sequencing), this method can return the first\n\t * ID to correspond to that override.\n\t *\n\t * As an example, consider the following two clients:\n\t * ClientA, session UUID: A0000000-0000-0000-0000-000000000000\n\t * ClientB, session UUID: B0000000-0000-0000-0000-000000000000\n\t *\n\t * If concurrently, two clients performed:\n\t * ClientA: generateCompressedId(override: 'X0000000-0000-0000-0000-000000000000') // aligned with A0000000-0000-0000-0000-000000000000\n\t *\n\t * ClientB: generateCompressedId() // aligned with B0000000-0000-0000-0000-000000000000\n\t * ClientB: generateCompressedId(override: 'X0000000-0000-0000-0000-000000000000') // aligned with B0000000-0000-0000-0000-000000000001\n\t *\n\t * After sequencing, calling this method and passing the numeric UUID for B0000000-0000-0000-0000-000000000001 would return the\n\t * session-space ID corresponding to A0000000-0000-0000-0000-000000000000 (with override X0000000-0000-0000-0000-000000000000).\n\t */\n\tprivate compressNumericUuid(numericUuid: NumericUuid): SessionSpaceCompressedId | undefined {\n\t\tconst stableId = stableIdFromNumericUuid(numericUuid);\n\t\tconst sessionSpaceId = this.recompressInternal(stableId, numericUuid);\n\t\tif (sessionSpaceId === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn sessionSpaceId;\n\t}\n\n\t/**\n\t * Returns a compressed ID for the supplied stable ID if it was created by the local session, and undefined otherwise.\n\t */\n\tprivate getCompressedIdForStableId(stableId: StableId | NumericUuid): SessionSpaceCompressedId | undefined {\n\t\tconst numericUuid = typeof stableId === 'string' ? numericUuidFromStableId(stableId) : stableId;\n\t\tconst creationIndex = getPositiveDelta(numericUuid, this.localSession.sessionUuid, this.localIdCount - 1);\n\t\tif (creationIndex !== undefined) {\n\t\t\tconst sessionSpaceId = this.sessionIdNormalizer.getIdByCreationIndex(creationIndex);\n\t\t\tif (sessionSpaceId !== undefined) {\n\t\t\t\treturn sessionSpaceId;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate getClusterForFinalId(\n\t\tfinalId: FinalCompressedId\n\t): readonly [baseFinalId: FinalCompressedId, cluster: IdCluster] | undefined {\n\t\tconst possibleCluster = this.finalIdToCluster.getPairOrNextLower(finalId);\n\t\tif (possibleCluster === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst [clusterBase, cluster] = possibleCluster;\n\t\tif (finalId - clusterBase >= cluster.count) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn possibleCluster;\n\t}\n\n\t/**\n\t * @returns if `other` is equal to this `IdCompressor`. The equality check includes local session state only if specified.\n\t * \\@testOnly\n\t */\n\tpublic equals(other: IdCompressor, compareLocalState: boolean): boolean {\n\t\tif (compareLocalState) {\n\t\t\tif (\n\t\t\t\tthis.localIdCount !== other.localIdCount ||\n\t\t\t\tthis.localSessionId !== other.localSessionId ||\n\t\t\t\tthis.lastTakenLocalId !== other.lastTakenLocalId ||\n\t\t\t\tthis.attributionId !== other.attributionId\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!this.localOverrides.equals(other.localOverrides, (a, b) => a === b)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!compareMaps(this.sessions, other.sessions, (a, b) =>\n\t\t\t\t\tIdCompressor.sessionDataEqual(a, b, true, compareLocalState)\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!this.sessionIdNormalizer.equals(other.sessionIdNormalizer, (a, b) =>\n\t\t\t\t\tIdCompressor.idClustersEqual(a, b, false, compareLocalState)\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\tfor (const [keyA, valueA] of this.sessions) {\n\t\t\t\tconst valueB = other.sessions.get(keyA);\n\t\t\t\tif (valueB === undefined) {\n\t\t\t\t\tif (valueA.lastFinalizedLocalId !== undefined) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} else if (!IdCompressor.sessionDataEqual(valueA, valueB, true, compareLocalState)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (const [keyB, valueB] of other.sessions) {\n\t\t\t\tconst valueA = this.sessions.get(keyB);\n\t\t\t\tif (valueA === undefined) {\n\t\t\t\t\tif (valueB.lastFinalizedLocalId !== undefined) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\tthis.nextClusterBaseFinalId !== other.nextClusterBaseFinalId ||\n\t\t\tthis.newClusterCapacity !== other.newClusterCapacity\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tif (\n\t\t\t!this.finalIdToCluster.equals(other.finalIdToCluster, (a, b) =>\n\t\t\t\tIdCompressor.idClustersEqual(a, b, true, compareLocalState)\n\t\t\t)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst missingInOne = (_: string, value: CompressionMapping): { break: boolean } | undefined => {\n\t\t\tif (!compareLocalState && IdCompressor.isUnfinalizedOverride(value)) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn { break: true };\n\t\t};\n\n\t\tconst compareCompressionMappings = (a, b): boolean => {\n\t\t\tconst unfinalizedA = IdCompressor.isUnfinalizedOverride(a);\n\t\t\tconst unfinalizedB = IdCompressor.isUnfinalizedOverride(b);\n\t\t\tif (unfinalizedA) {\n\t\t\t\tif (unfinalizedB) {\n\t\t\t\t\treturn a === b;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t} else if (unfinalizedB) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (IdCompressor.isClusterInfo(a)) {\n\t\t\t\tif (!IdCompressor.isClusterInfo(b) || a.clusterBase !== b.clusterBase) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (\n\t\t\t\t\tIdCompressor.isClusterInfo(b) ||\n\t\t\t\t\t(compareLocalState && a.associatedLocalId !== b.associatedLocalId) ||\n\t\t\t\t\ta.originalOverridingFinal !== b.originalOverridingFinal\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!IdCompressor.idClustersEqual(a.cluster, b.cluster, true, compareLocalState)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tconst diff = this.clustersAndOverridesInversion.diffAgainst(\n\t\t\tother.clustersAndOverridesInversion,\n\t\t\tmissingInOne,\n\t\t\tmissingInOne,\n\t\t\t(_, valA, valB) => {\n\t\t\t\tif (!compareCompressionMappings(valA, valB)) {\n\t\t\t\t\treturn { break: true };\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t);\n\n\t\treturn diff === undefined;\n\t}\n\n\tprivate static sessionDataEqual(a: Session, b: Session, checkCluster = true, compareLocalState = true): boolean {\n\t\tif (\n\t\t\ta.attributionId !== b.attributionId ||\n\t\t\t!numericUuidEquals(a.sessionUuid, b.sessionUuid) ||\n\t\t\ta.lastFinalizedLocalId !== b.lastFinalizedLocalId\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tif (a.currentClusterDetails === undefined || b.currentClusterDetails === undefined) {\n\t\t\tif (a.currentClusterDetails !== b.currentClusterDetails) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tif (\n\t\t\tcheckCluster &&\n\t\t\t!IdCompressor.idClustersEqual(\n\t\t\t\ta.currentClusterDetails.cluster,\n\t\t\t\tb.currentClusterDetails.cluster,\n\t\t\t\tfalse,\n\t\t\t\tcompareLocalState\n\t\t\t)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate static idClustersEqual(\n\t\ta: IdCluster,\n\t\tb: IdCluster,\n\t\tcheckSessionData = true,\n\t\tcompareLocalState = true\n\t): boolean {\n\t\tconst areEqual =\n\t\t\tnumericUuidEquals(a.baseUuid, b.baseUuid) &&\n\t\t\ta.capacity === b.capacity &&\n\t\t\ta.count === b.count &&\n\t\t\t(!checkSessionData || IdCompressor.sessionDataEqual(a.session, b.session, false, compareLocalState)) &&\n\t\t\t(a.overrides === undefined) === (b.overrides === undefined) &&\n\t\t\t(a.overrides === undefined ||\n\t\t\t\tcompareMaps(assertNotUndefined(a.overrides), assertNotUndefined(b.overrides), (a, b) => {\n\t\t\t\t\tif (compareLocalState) {\n\t\t\t\t\t\tif (typeof a === 'string' || typeof b === 'string') {\n\t\t\t\t\t\t\treturn a === b;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst overridesEqual =\n\t\t\t\t\t\t\ta.override === b.override &&\n\t\t\t\t\t\t\ta.originalOverridingFinal === b.originalOverridingFinal &&\n\t\t\t\t\t\t\t(!compareLocalState || a.associatedLocalId === b.associatedLocalId);\n\t\t\t\t\t\treturn overridesEqual;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst uuidA = typeof a === 'string' ? a : a.override;\n\t\t\t\t\tconst uuidB = typeof b === 'string' ? b : b.override;\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof a !== 'string' &&\n\t\t\t\t\t\ttypeof b !== 'string' &&\n\t\t\t\t\t\ta.originalOverridingFinal !== b.originalOverridingFinal\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn uuidA === uuidB;\n\t\t\t\t}));\n\t\treturn areEqual;\n\t}\n\n\t/**\n\t * Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.\n\t * This includes finalized state as well as un-finalized state and is therefore suitable for use in offline scenarios.\n\t */\n\tpublic serialize(\n\t\twithSession: boolean\n\t): SerializedIdCompressorWithOngoingSession | SerializedIdCompressorWithNoSession;\n\n\t/**\n\t * Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.\n\t * This includes finalized state as well as un-finalized state and is therefore suitable for use in offline scenarios.\n\t */\n\tpublic serialize(withSession: true): SerializedIdCompressorWithOngoingSession;\n\n\t/**\n\t * Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.\n\t * This only includes finalized state and is therefore suitable for use in summaries.\n\t */\n\tpublic serialize(withSession: false): SerializedIdCompressorWithNoSession;\n\n\tpublic serialize(withSession: boolean): SerializedIdCompressor {\n\t\tconst serializedSessions: SerializedSessionData[] = [];\n\t\tconst sessionIdToSessionIndex = new Map<SessionId, number>();\n\t\tconst attributionIdToAttributionIndex = new Map<AttributionId, number>();\n\t\tlet serializedAttributionIds: UuidString[] | undefined;\n\n\t\tfor (const [sessionId, session] of this.sessions) {\n\t\t\tconst isLocalSession = sessionId === this.localSessionId;\n\t\t\tconst includeSession =\n\t\t\t\tsessionId !== reservedSessionId && // Ignore reserved clusters, but\n\t\t\t\t(session.lastFinalizedLocalId !== undefined || // always serialize sessions that made final IDs,\n\t\t\t\t\t(isLocalSession && withSession)); // include the un-acked local session if requested\n\n\t\t\tif (includeSession) {\n\t\t\t\tconst sessionData: Mutable<SerializedSessionData> = [sessionId];\n\t\t\t\tif (session.attributionId !== sessionId) {\n\t\t\t\t\t// As an optimization, don't include the attributionId if it is its default (the sessionId)\n\t\t\t\t\t// Get the index into the array for the given attribution ID. If it doesn't exist, push it onto the array and update the map.\n\t\t\t\t\tsessionData.push(\n\t\t\t\t\t\tgetOrCreate(\n\t\t\t\t\t\t\tattributionIdToAttributionIndex,\n\t\t\t\t\t\t\tsession.attributionId,\n\t\t\t\t\t\t\t(id) => (serializedAttributionIds ??= []).push(id) - 1\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tsessionIdToSessionIndex.set(sessionId, serializedSessions.length);\n\t\t\t\tserializedSessions.push(sessionData);\n\t\t\t}\n\t\t}\n\n\t\tconst serializedClusters: SerializedCluster[] = [];\n\t\tfor (const [baseFinalId, cluster] of this.finalIdToCluster.entries()) {\n\t\t\tconst sessionId = stableIdFromNumericUuid(cluster.session.sessionUuid) as SessionId;\n\t\t\tif (sessionId !== reservedSessionId) {\n\t\t\t\tconst sessionIndex =\n\t\t\t\t\tsessionIdToSessionIndex.get(sessionId) ?? fail('Session object contains wrong session numeric UUID');\n\n\t\t\t\tconst serializedCluster: Mutable<SerializedCluster> = [sessionIndex, cluster.capacity];\n\t\t\t\tif (cluster.count !== cluster.capacity) {\n\t\t\t\t\tserializedCluster.push(cluster.count);\n\t\t\t\t}\n\n\t\t\t\tif (cluster.overrides !== undefined) {\n\t\t\t\t\tconst serializedOverrides: Mutable<SerializedClusterOverrides> = [];\n\t\t\t\t\tfor (const [finalId, override] of cluster.overrides) {\n\t\t\t\t\t\tconst finalIdIndex = finalId - baseFinalId;\n\t\t\t\t\t\tif (typeof override === 'string') {\n\t\t\t\t\t\t\tserializedOverrides.push([finalIdIndex, override]);\n\t\t\t\t\t\t} else if (override.originalOverridingFinal === finalId) {\n\t\t\t\t\t\t\tserializedOverrides.push([finalIdIndex, override.override]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tserializedOverrides.push([finalIdIndex, override.override, override.originalOverridingFinal]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tserializedCluster.push(serializedOverrides);\n\t\t\t\t}\n\n\t\t\t\tserializedClusters.push(serializedCluster);\n\t\t\t}\n\t\t}\n\n\t\t// Reserved session not serialized, and local session is present but may not make IDs\n\t\tassert(serializedSessions.length - this.sessions.size <= 2, 0x653 /* session not serialized */);\n\n\t\tconst serializedIdCompressor: Omit<SerializedIdCompressor, '_versionedSerializedIdCompressor'> = {\n\t\t\tversion: currentWrittenVersion,\n\t\t\treservedIdCount: this.reservedIdCount,\n\t\t\tclusterCapacity: this.clusterCapacity,\n\t\t\tsessions: serializedSessions,\n\t\t\tclusters: serializedClusters,\n\t\t};\n\t\tsetPropertyIfDefined(serializedAttributionIds, serializedIdCompressor, 'attributionIds');\n\n\t\tif (withSession) {\n\t\t\tconst serializedWithSession = serializedIdCompressor as Mutable<SerializedIdCompressorWithOngoingSession>;\n\t\t\tserializedWithSession.localSessionIndex = serializedWithSession.sessions.findIndex(\n\t\t\t\t([sessionId]) => sessionId === this.localSessionId\n\t\t\t);\n\t\t\tif (this.localIdCount > 0) {\n\t\t\t\tserializedWithSession.localState = {\n\t\t\t\t\tlocalIdCount: this.localIdCount,\n\t\t\t\t\toverrides: [...this.localOverrides.entries()].map((entry) => [...entry]),\n\t\t\t\t\tlastTakenLocalId: this.lastTakenLocalId,\n\t\t\t\t\tsessionNormalizer: this.sessionIdNormalizer.serialize(),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn serializedWithSession;\n\t\t}\n\n\t\tthis.logger?.sendTelemetryEvent({\n\t\t\teventName: 'SharedTreeIdCompressor:SerializedIdCompressorSize',\n\t\t\tsize: JSON.stringify(serializedIdCompressor).length,\n\t\t\tclusterCount: serializedIdCompressor.clusters.length,\n\t\t\tsessionCount: serializedIdCompressor.sessions.length,\n\t\t});\n\n\t\treturn serializedIdCompressor as SerializedIdCompressor;\n\t}\n\n\t/**\n\t * Deserialize an serialized IdCompressor that is part of an ongoing session, thereby resuming that session.\n\t */\n\tpublic static deserialize(serialized: SerializedIdCompressorWithOngoingSession): IdCompressor;\n\n\t/**\n\t * Deserialize a serialized IdCompressor with a new session.\n\t * @param serialized - the serialized compressor state\n\t * @param newSessionId - the session ID for the new compressor.\n\t * @param attributionId - information used by other clients to attribute IDs made by this client\n\t */\n\tpublic static deserialize(\n\t\tserialized: SerializedIdCompressorWithNoSession,\n\t\tnewSessionId: SessionId,\n\t\tattributionId?: AttributionId\n\t): IdCompressor;\n\n\tpublic static deserialize(\n\t\t...args:\n\t\t\t| [\n\t\t\t\t\tserialized: SerializedIdCompressorWithNoSession,\n\t\t\t\t\tnewSessionIdMaybe: SessionId,\n\t\t\t\t\tattributionIdMaybe?: AttributionId,\n\t\t\t ]\n\t\t\t| [\n\t\t\t\t\tserialized: SerializedIdCompressorWithOngoingSession,\n\t\t\t\t\tnewSessionIdMaybe?: undefined,\n\t\t\t\t\tattributionIdMaybe?: undefined,\n\t\t\t ]\n\t): IdCompressor {\n\t\tconst [serialized, newSessionIdMaybe, attributionIdMaybe] = args;\n\n\t\tconst {\n\t\t\tclusterCapacity,\n\t\t\treservedIdCount,\n\t\t\tsessions: serializedSessions,\n\t\t\tclusters: serializedClusters,\n\t\t\tattributionIds: serializedAttributionIds,\n\t\t} = serialized;\n\n\t\tlet localSessionId: SessionId;\n\t\tlet attributionId: AttributionId | undefined;\n\t\tlet serializedLocalState: SerializedLocalState | undefined;\n\t\tif (newSessionIdMaybe === undefined) {\n\t\t\t// Alias of serialized, but known to be a SerializedIdCompressorWithOngoingSession\n\t\t\tconst [serializedWithSession] = args;\n\t\t\tconst serializedSessionData = serializedSessions[serializedWithSession.localSessionIndex];\n\t\t\tlocalSessionId = serializedSessionData[0];\n\t\t\tconst attributionIndex = serializedSessionData[1];\n\t\t\tif (attributionIndex !== undefined) {\n\t\t\t\tassertWithMessage(serializedAttributionIds !== undefined && serializedAttributionIds.length > attributionIndex);\n\t\t\t\tattributionId = serializedAttributionIds[attributionIndex];\n\t\t\t}\n\t\t\tserializedLocalState = serializedWithSession.localState;\n\t\t} else {\n\t\t\tlocalSessionId = newSessionIdMaybe;\n\t\t\tattributionId = attributionIdMaybe;\n\t\t}\n\n\t\tconst compressor = new IdCompressor(localSessionId, reservedIdCount, attributionId);\n\t\tcompressor.clusterCapacity = clusterCapacity;\n\n\t\tconst localOverridesInverse = new Map<string, LocalCompressedId>();\n\t\tif (serializedLocalState !== undefined) {\n\t\t\t// Do this part of local rehydration first since the cluster map population needs to query to local overrides\n\t\t\tcompressor.localIdCount = serializedLocalState.localIdCount;\n\t\t\tcompressor.lastTakenLocalId = serializedLocalState.lastTakenLocalId;\n\t\t\tif (serializedLocalState.overrides !== undefined) {\n\t\t\t\tfor (const [localId, override] of serializedLocalState.overrides) {\n\t\t\t\t\tcompressor.localOverrides.append(localId, override);\n\t\t\t\t\tlocalOverridesInverse.set(override, localId);\n\t\t\t\t\tcompressor.clustersAndOverridesInversion.set(\n\t\t\t\t\t\tIdCompressor.createInversionKey(override),\n\t\t\t\t\t\tlocalId as UnackedLocalId\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst sessionInfos: {\n\t\t\treadonly session: Session;\n\t\t\treadonly sessionId: SessionId;\n\t\t}[] = [];\n\t\tfor (const serializedSession of serializedSessions) {\n\t\t\tconst [sessionId, attributionIndex] = serializedSession;\n\t\t\tif (sessionId === localSessionId) {\n\t\t\t\tassert(hasOngoingSession(serialized), 0x654 /* Cannot resume existing session. */);\n\t\t\t\tsessionInfos.push({ session: compressor.localSession, sessionId });\n\t\t\t} else {\n\t\t\t\tlet attributionId: AttributionId | undefined;\n\t\t\t\tif (attributionIndex !== undefined) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tserializedAttributionIds !== undefined && serializedAttributionIds.length > attributionIndex,\n\t\t\t\t\t\t0x655 /* AttributionId index out of bounds */\n\t\t\t\t\t);\n\t\t\t\t\tattributionId = serializedAttributionIds[attributionIndex];\n\t\t\t\t}\n\t\t\t\tconst session = compressor.createSession(sessionId, attributionId);\n\t\t\t\tsessionInfos.push({ session, sessionId });\n\t\t\t}\n\t\t}\n\n\t\tfor (const serializedCluster of serializedClusters) {\n\t\t\tconst { sessionIndex, capacity, count, overrides } = deserializeCluster(serializedCluster);\n\t\t\tconst { session, sessionId } = sessionInfos[sessionIndex];\n\t\t\tconst { lastFinalizedLocalId, sessionUuid } = session;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\t\tconst currentIdCount = lastFinalizedLocalId === undefined ? 0 : -lastFinalizedLocalId;\n\n\t\t\tconst cluster: Mutable<IdCluster> = {\n\t\t\t\tcapacity,\n\t\t\t\tcount,\n\t\t\t\tbaseUuid: incrementUuid(sessionUuid, currentIdCount),\n\t\t\t\tsession,\n\t\t\t};\n\n\t\t\tconst lastFinalizedNormalized = lastFinalizedLocalId ?? 0;\n\t\t\tconst clusterBase = compressor.nextClusterBaseFinalId;\n\n\t\t\tsession.lastFinalizedLocalId = (lastFinalizedNormalized - count) as LocalCompressedId;\n\t\t\tsession.currentClusterDetails = { clusterBase, cluster };\n\t\t\tcompressor.nextClusterBaseFinalId = (compressor.nextClusterBaseFinalId + capacity) as FinalCompressedId;\n\t\t\tcompressor.finalIdToCluster.append(clusterBase, cluster);\n\t\t\tcompressor.clustersAndOverridesInversion.set(stableIdFromNumericUuid(cluster.baseUuid), {\n\t\t\t\tclusterBase,\n\t\t\t\tcluster,\n\t\t\t});\n\n\t\t\tif (overrides !== undefined) {\n\t\t\t\tcluster.overrides = new Map();\n\t\t\t\tfor (const [finalIdIndex, override, originalOverridingFinal] of overrides) {\n\t\t\t\t\tconst finalId = (clusterBase + finalIdIndex) as FinalCompressedId;\n\t\t\t\t\tif (originalOverridingFinal !== undefined) {\n\t\t\t\t\t\tconst unifiedOverride: Mutable<UnifiedOverride> = {\n\t\t\t\t\t\t\toverride,\n\t\t\t\t\t\t\toriginalOverridingFinal,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (serializedLocalState !== undefined) {\n\t\t\t\t\t\t\tsetPropertyIfDefined(localOverridesInverse.get(override), unifiedOverride, 'associatedLocalId');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcluster.overrides.set(finalId, unifiedOverride);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst associatedLocal = localOverridesInverse.get(override);\n\t\t\t\t\t\tif (associatedLocal !== undefined && sessionId !== localSessionId) {\n\t\t\t\t\t\t\t// In this case, there is a local ID associated with this override, but this is the first cluster to contain\n\t\t\t\t\t\t\t// that override (because only the first cluster will have the string serialized). In this case, the override\n\t\t\t\t\t\t\t// needs to hold that local value.\n\t\t\t\t\t\t\tcluster.overrides.set(finalId, {\n\t\t\t\t\t\t\t\toverride,\n\t\t\t\t\t\t\t\toriginalOverridingFinal: finalId,\n\t\t\t\t\t\t\t\tassociatedLocalId: associatedLocal,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcluster.overrides.set(finalId, override);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst finalizedOverride: Mutable<FinalizedOverride> = {\n\t\t\t\t\t\t\tcluster,\n\t\t\t\t\t\t\toriginalOverridingFinal: finalId,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (serializedLocalState !== undefined) {\n\t\t\t\t\t\t\tsetPropertyIfDefined(associatedLocal, finalizedOverride, 'associatedLocalId');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcompressor.clustersAndOverridesInversion.set(IdCompressor.createInversionKey(override), finalizedOverride);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (serializedLocalState !== undefined) {\n\t\t\tcompressor.sessionIdNormalizer = SessionIdNormalizer.deserialize(\n\t\t\t\tserializedLocalState.sessionNormalizer,\n\t\t\t\t(finalId) => {\n\t\t\t\t\tconst [_, cluster] =\n\t\t\t\t\t\tcompressor.finalIdToCluster.getPairOrNextLower(finalId) ??\n\t\t\t\t\t\tfail('Final in serialized normalizer was never created.');\n\t\t\t\t\treturn cluster;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\tassertWithMessage(\n\t\t\tcompressor.localSession.lastFinalizedLocalId === undefined ||\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-unary-minus\n\t\t\t\tcompressor.localIdCount >= -compressor.localSession.lastFinalizedLocalId\n\t\t);\n\n\t\treturn compressor;\n\t}\n\n\t/**\n\t * Converts the given serialized compressor to the current version.\n\t * @param serializedCompressor - the serialized compressor to convert. Must not have been serialized with an ongoing session.\n\t * @returns a serialized compressor with no ongoing session.\n\t */\n\tpublic static convertToCurrentVersion(\n\t\tserializedCompressor: VersionedSerializedIdCompressor,\n\t\thasSession: false\n\t): SerializedIdCompressorWithNoSession;\n\n\t/**\n\t * Converts the given serialized compressor to the current version.\n\t * @param serializedCompressor - the serialized compressor to convert. Must have been serialized with an ongoing session.\n\t * @returns a serialized compressor with the same ongoing session.\n\t */\n\tpublic static convertToCurrentVersion(\n\t\tserializedCompressor: VersionedSerializedIdCompressor,\n\t\thasSession: true\n\t): SerializedIdCompressorWithOngoingSession;\n\n\tpublic static convertToCurrentVersion(\n\t\tserializedCompressor: VersionedSerializedIdCompressor,\n\t\thasSession: boolean\n\t): SerializedIdCompressor | undefined {\n\t\tif (serializedCompressor.version !== currentWrittenVersion) {\n\t\t\tfail('Unknown SerializedIdCompressor version number');\n\t\t}\n\t\tconst serialized = serializedCompressor as SerializedIdCompressorWithOngoingSession;\n\t\tif (hasSession !== hasOngoingSession(serialized)) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn serialized;\n\t}\n}\n\n/**\n * The version of `IdCompressor` that is currently persisted.\n */\nconst currentWrittenVersion = '0.0.1';\n\n/**\n * @returns whether or not the given serialized ID compressor has an ongoing session.\n */\nexport function hasOngoingSession(\n\tserialized: SerializedIdCompressorWithNoSession | SerializedIdCompressorWithOngoingSession\n): serialized is SerializedIdCompressorWithOngoingSession {\n\treturn (serialized as Partial<SerializedIdCompressorWithOngoingSession>).localSessionIndex !== undefined;\n}\n\nfunction deserializeCluster(serializedCluster: SerializedCluster): {\n\tsessionIndex: number;\n\tcapacity: number;\n\tcount: number;\n\toverrides?: SerializedClusterOverrides;\n} {\n\tconst [sessionIndex, capacity, countOrOverrides, overrides] = serializedCluster;\n\tconst hasCount = typeof countOrOverrides === 'number';\n\n\treturn {\n\t\tsessionIndex,\n\t\tcapacity,\n\t\tcount: hasCount ? countOrOverrides : capacity,\n\t\toverrides: hasCount ? overrides : countOrOverrides,\n\t};\n}\n\n/**\n * Optimization used by the sorted-btree library to avoid allocating tuples every time a lookup method is called.\n * Lookup methods on BTree accept a pre-allocated array that it populates with the result of the lookup and retains no ownership\n * of after the call, so this array may be supplied to any of them. References to this array should not be retained elsewhere and\n * lookup results should be extracted from the tuple immediately after invocation.\n */\nconst reusedArray: [any, any] = [] as unknown as [any, any];\n"]}