@fluidframework/id-compressor 2.0.0-internal.8.0.0 → 2.0.0-rc.1.0.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 (129) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +0 -6
  3. package/api-extractor-esm.json +4 -0
  4. package/api-extractor-lint.json +1 -10
  5. package/api-extractor.json +1 -9
  6. package/api-report/id-compressor.api.md +7 -5
  7. package/dist/id-compressor-alpha.d.ts +32 -5
  8. package/dist/id-compressor-beta.d.ts +142 -9
  9. package/dist/id-compressor-public.d.ts +142 -9
  10. package/dist/id-compressor-untrimmed.d.ts +32 -5
  11. package/dist/idCompressor.d.ts +6 -0
  12. package/dist/idCompressor.d.ts.map +1 -1
  13. package/dist/idCompressor.js +58 -20
  14. package/dist/idCompressor.js.map +1 -1
  15. package/dist/packageVersion.d.ts +1 -1
  16. package/dist/packageVersion.d.ts.map +1 -1
  17. package/dist/packageVersion.js +1 -1
  18. package/dist/packageVersion.js.map +1 -1
  19. package/dist/sessions.js +3 -6
  20. package/dist/sessions.js.map +1 -1
  21. package/dist/types/idCompressor.d.ts +22 -1
  22. package/dist/types/idCompressor.d.ts.map +1 -1
  23. package/dist/types/idCompressor.js.map +1 -1
  24. package/dist/types/identifiers.d.ts +4 -4
  25. package/dist/types/identifiers.js.map +1 -1
  26. package/lib/{appendOnlySortedMap.d.ts → appendOnlySortedMap.d.mts} +1 -1
  27. package/lib/appendOnlySortedMap.d.mts.map +1 -0
  28. package/lib/{appendOnlySortedMap.js → appendOnlySortedMap.mjs} +1 -3
  29. package/lib/appendOnlySortedMap.mjs.map +1 -0
  30. package/lib/{finalSpace.d.ts → finalSpace.d.mts} +3 -3
  31. package/lib/finalSpace.d.mts.map +1 -0
  32. package/lib/{finalSpace.js → finalSpace.mjs} +2 -2
  33. package/lib/finalSpace.mjs.map +1 -0
  34. package/lib/{id-compressor-alpha.d.ts → id-compressor-alpha.d.mts} +32 -5
  35. package/lib/id-compressor-beta.d.mts +172 -0
  36. package/lib/id-compressor-public.d.mts +172 -0
  37. package/lib/{id-compressor-untrimmed.d.ts → id-compressor-untrimmed.d.mts} +32 -5
  38. package/lib/{idCompressor.d.ts → idCompressor.d.mts} +8 -2
  39. package/lib/idCompressor.d.mts.map +1 -0
  40. package/lib/{idCompressor.js → idCompressor.mjs} +65 -27
  41. package/lib/idCompressor.mjs.map +1 -0
  42. package/lib/{identifiers.d.ts → identifiers.d.mts} +2 -2
  43. package/lib/identifiers.d.mts.map +1 -0
  44. package/lib/{identifiers.js → identifiers.mjs} +1 -1
  45. package/lib/identifiers.mjs.map +1 -0
  46. package/lib/{index.d.ts → index.d.mts} +4 -7
  47. package/lib/index.d.mts.map +1 -0
  48. package/lib/{index.js → index.mjs} +3 -6
  49. package/lib/index.mjs.map +1 -0
  50. package/lib/{packageVersion.d.ts → packageVersion.d.mts} +2 -2
  51. package/lib/packageVersion.d.mts.map +1 -0
  52. package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
  53. package/lib/packageVersion.mjs.map +1 -0
  54. package/lib/{persistanceUtilities.d.ts → persistanceUtilities.d.mts} +2 -2
  55. package/lib/persistanceUtilities.d.mts.map +1 -0
  56. package/lib/{persistanceUtilities.js → persistanceUtilities.mjs} +1 -1
  57. package/lib/persistanceUtilities.mjs.map +1 -0
  58. package/lib/{sessionSpaceNormalizer.d.ts → sessionSpaceNormalizer.d.mts} +3 -3
  59. package/lib/sessionSpaceNormalizer.d.mts.map +1 -0
  60. package/lib/{sessionSpaceNormalizer.js → sessionSpaceNormalizer.mjs} +3 -3
  61. package/lib/sessionSpaceNormalizer.mjs.map +1 -0
  62. package/lib/{sessions.d.ts → sessions.d.mts} +3 -3
  63. package/lib/sessions.d.mts.map +1 -0
  64. package/lib/{sessions.js → sessions.mjs} +3 -3
  65. package/lib/sessions.mjs.map +1 -0
  66. package/lib/types/{idCompressor.d.ts → idCompressor.d.mts} +25 -4
  67. package/lib/types/idCompressor.d.mts.map +1 -0
  68. package/lib/types/{identifiers.js → idCompressor.mjs} +1 -1
  69. package/lib/types/idCompressor.mjs.map +1 -0
  70. package/lib/types/{identifiers.d.ts → identifiers.d.mts} +5 -5
  71. package/lib/types/identifiers.d.mts.map +1 -0
  72. package/lib/types/{idCompressor.js → identifiers.mjs} +1 -1
  73. package/lib/types/identifiers.mjs.map +1 -0
  74. package/lib/types/{index.d.ts → index.d.mts} +4 -4
  75. package/lib/types/index.d.mts.map +1 -0
  76. package/lib/types/{persisted-types/0.0.1.js → index.mjs} +1 -1
  77. package/lib/types/index.mjs.map +1 -0
  78. package/lib/types/persisted-types/{0.0.1.d.ts → 0.0.1.d.mts} +2 -2
  79. package/lib/types/persisted-types/0.0.1.d.mts.map +1 -0
  80. package/lib/types/persisted-types/{index.js → 0.0.1.mjs} +1 -1
  81. package/lib/types/persisted-types/0.0.1.mjs.map +1 -0
  82. package/lib/types/persisted-types/{index.d.ts → index.d.mts} +2 -2
  83. package/lib/types/persisted-types/index.d.mts.map +1 -0
  84. package/lib/types/{index.js → persisted-types/index.mjs} +1 -1
  85. package/lib/types/persisted-types/index.mjs.map +1 -0
  86. package/lib/{utilities.d.ts → utilities.d.mts} +3 -3
  87. package/lib/utilities.d.mts.map +1 -0
  88. package/lib/{utilities.js → utilities.mjs} +1 -2
  89. package/lib/utilities.mjs.map +1 -0
  90. package/package.json +26 -20
  91. package/src/idCompressor.ts +76 -19
  92. package/src/packageVersion.ts +1 -1
  93. package/src/sessions.ts +1 -1
  94. package/src/types/idCompressor.ts +23 -1
  95. package/src/types/identifiers.ts +4 -4
  96. package/tsconfig.json +4 -2
  97. package/lib/appendOnlySortedMap.d.ts.map +0 -1
  98. package/lib/appendOnlySortedMap.js.map +0 -1
  99. package/lib/finalSpace.d.ts.map +0 -1
  100. package/lib/finalSpace.js.map +0 -1
  101. package/lib/id-compressor-beta.d.ts +0 -39
  102. package/lib/id-compressor-public.d.ts +0 -39
  103. package/lib/idCompressor.d.ts.map +0 -1
  104. package/lib/idCompressor.js.map +0 -1
  105. package/lib/identifiers.d.ts.map +0 -1
  106. package/lib/identifiers.js.map +0 -1
  107. package/lib/index.d.ts.map +0 -1
  108. package/lib/index.js.map +0 -1
  109. package/lib/packageVersion.d.ts.map +0 -1
  110. package/lib/packageVersion.js.map +0 -1
  111. package/lib/persistanceUtilities.d.ts.map +0 -1
  112. package/lib/persistanceUtilities.js.map +0 -1
  113. package/lib/sessionSpaceNormalizer.d.ts.map +0 -1
  114. package/lib/sessionSpaceNormalizer.js.map +0 -1
  115. package/lib/sessions.d.ts.map +0 -1
  116. package/lib/sessions.js.map +0 -1
  117. package/lib/types/idCompressor.d.ts.map +0 -1
  118. package/lib/types/idCompressor.js.map +0 -1
  119. package/lib/types/identifiers.d.ts.map +0 -1
  120. package/lib/types/identifiers.js.map +0 -1
  121. package/lib/types/index.d.ts.map +0 -1
  122. package/lib/types/index.js.map +0 -1
  123. package/lib/types/persisted-types/0.0.1.d.ts.map +0 -1
  124. package/lib/types/persisted-types/0.0.1.js.map +0 -1
  125. package/lib/types/persisted-types/index.d.ts.map +0 -1
  126. package/lib/types/persisted-types/index.js.map +0 -1
  127. package/lib/utilities.d.ts.map +0 -1
  128. package/lib/utilities.js.map +0 -1
  129. package/tsconfig.esnext.json +0 -7
@@ -1 +1 @@
1
- {"version":3,"file":"idCompressor.js","sourceRoot":"","sources":["../../src/types/idCompressor.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { SessionSpaceCompressedId, OpSpaceCompressedId, SessionId, StableId } from \"./identifiers\";\nimport {\n\tIdCreationRange,\n\tSerializedIdCompressorWithNoSession,\n\tSerializedIdCompressorWithOngoingSession,\n} from \"./persisted-types\";\n\n/**\n * @alpha\n */\nexport interface IIdCompressorCore {\n\t/**\n\t * Returns a range of IDs created by this session in a format for sending to the server for finalizing.\n\t * The range will include all IDs generated via calls to `generateCompressedId` since the last time this method was called.\n\t * @returns the range of 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\ttakeNextCreationRange(): IdCreationRange;\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\tfinalizeCreationRange(range: IdCreationRange): void;\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\tserialize(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\tserialize(withSession: false): SerializedIdCompressorWithNoSession;\n}\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 session-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. These IDs are session-unique and are thus only\n * safely usable within the scope of the compressor that created it.\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 session-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 * The following invariants are upheld by IdCompressor:\n *\n * 1. Session-local IDs will always decompress to the same UUIDs for the lifetime of the session.\n *\n * 2. Final IDs will always decompress to the same UUIDs.\n *\n * 3. After a server-processed range of session-local IDs (from any session) is received by a compressor, any of those session-local IDs may be\n * translated by the compressor into the corresponding final ID. For any given session-local ID, this translation will always yield the\n * same final ID.\n *\n * 4. A UUID will always compress into the same session-local ID for the lifetime of the session.\n *\n * Session-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 difficult. For example, if a cache is keyed off of a\n * session-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 session-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 * @alpha\n */\nexport interface IIdCompressor {\n\tlocalSessionId: SessionId;\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 * @returns A new local ID in session space.\n\t */\n\tgenerateCompressedId(): SessionSpaceCompressedId;\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\tnormalizeToOpSpace(id: SessionSpaceCompressedId): OpSpaceCompressedId;\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\tnormalizeToSessionSpace(\n\t\tid: OpSpaceCompressedId,\n\t\toriginSessionId: SessionId,\n\t): SessionSpaceCompressedId;\n\n\t/**\n\t * Decompresses a previously compressed ID into a UUID.\n\t * @param id - the compressed ID to be decompressed.\n\t * @returns the UUID associated with the compressed ID. Fails if the ID was not generated by this compressor.\n\t */\n\tdecompress(id: SessionSpaceCompressedId): StableId;\n\n\t/**\n\t * Recompresses a UUID.\n\t * @param uncompressed - the UUID to recompress.\n\t * @returns the `CompressedId` associated with `uncompressed`. Fails if it has not been previously compressed by this compressor.\n\t */\n\trecompress(uncompressed: StableId): SessionSpaceCompressedId;\n\n\t/**\n\t * Attempts to recompresses a UUID.\n\t * @param uncompressed - the UUID 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\ttryRecompress(uncompressed: StableId): SessionSpaceCompressedId | undefined;\n}\n"]}
1
+ {"version":3,"file":"idCompressor.js","sourceRoot":"","sources":["../../src/types/idCompressor.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { SessionSpaceCompressedId, OpSpaceCompressedId, SessionId, StableId } from \"./identifiers\";\nimport {\n\tIdCreationRange,\n\tSerializedIdCompressorWithNoSession,\n\tSerializedIdCompressorWithOngoingSession,\n} from \"./persisted-types\";\n\n/**\n * @alpha\n */\nexport interface IIdCompressorCore {\n\t/**\n\t * Returns a range of IDs created by this session in a format for sending to the server for finalizing.\n\t * The range will include all IDs generated via calls to `generateCompressedId` since the last time this method was called.\n\t * @returns the range of 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\ttakeNextCreationRange(): IdCreationRange;\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\tfinalizeCreationRange(range: IdCreationRange): void;\n\n\t/**\n\t * Run a callback that is performed from the perspective of a special \"ghost\" session.\n\t * Any ids generated by this session will be immediately finalized on the local client as if\n\t * they were created by a remote client with `ghostSessionId`.\n\t *\n\t * *WARNING:* This API requires an external consensus mechanism to safely use:\n\t * In an attached container (i.e. multiple clients may have the document loaded), all clients must guarantee that:\n\t * - They invoke this API starting from the same finalized creation ranges\n\t * - This API is invoked with the same ghost session id\n\t * - `ghostSessionCallback` deterministically mints the same number of ids on each client within the ghost session\n\t * Failure to meet these requirement will result in divergence across clients and eventual consistency errors.\n\t * While the ghost sesion callback is running, IdCompressor does not support serialization.\n\t * @remarks This API is primarily intended for data migration scenarios which are able to deterministically transform\n\t * data in some format into data in a new format.\n\t * The first requirement (that all clients must invoke the API with the same finalized creation ranges) is guaranteed\n\t * for this scenario because the data transformation callback occurs at a specific ack within the op stream on all\n\t * clients, and clients don't finalize creation ranges for local changes they might have at this point in time.\n\t * @param ghostSessionId - The session id that minted ids generated within `ghostSessionCallback` should be attributed to.\n\t * @param ghostSessionCallback - Callback which mints ids attributed to the ghost session.\n\t */\n\tbeginGhostSession(ghostSessionId: SessionId, ghostSessionCallback: () => void);\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\tserialize(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\tserialize(withSession: false): SerializedIdCompressorWithNoSession;\n}\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 session-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. These IDs are session-unique and are thus only\n * safely usable within the scope of the compressor that created it.\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 session-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 * The following invariants are upheld by IdCompressor:\n *\n * 1. Session-local IDs will always decompress to the same UUIDs for the lifetime of the session.\n *\n * 2. Final IDs will always decompress to the same UUIDs.\n *\n * 3. After a server-processed range of session-local IDs (from any session) is received by a compressor, any of those session-local IDs may be\n * translated by the compressor into the corresponding final ID. For any given session-local ID, this translation will always yield the\n * same final ID.\n *\n * 4. A UUID will always compress into the same session-local ID for the lifetime of the session.\n *\n * Session-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 difficult. For example, if a cache is keyed off of a\n * session-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 session-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 * @public\n */\nexport interface IIdCompressor {\n\tlocalSessionId: SessionId;\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 * @returns A new local ID in session space.\n\t */\n\tgenerateCompressedId(): SessionSpaceCompressedId;\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\tnormalizeToOpSpace(id: SessionSpaceCompressedId): OpSpaceCompressedId;\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\tnormalizeToSessionSpace(\n\t\tid: OpSpaceCompressedId,\n\t\toriginSessionId: SessionId,\n\t): SessionSpaceCompressedId;\n\n\t/**\n\t * Decompresses a previously compressed ID into a UUID.\n\t * @param id - the compressed ID to be decompressed.\n\t * @returns the UUID associated with the compressed ID. Fails if the ID was not generated by this compressor.\n\t */\n\tdecompress(id: SessionSpaceCompressedId): StableId;\n\n\t/**\n\t * Recompresses a UUID.\n\t * @param uncompressed - the UUID to recompress.\n\t * @returns the `CompressedId` associated with `uncompressed`. Fails if it has not been previously compressed by this compressor.\n\t */\n\trecompress(uncompressed: StableId): SessionSpaceCompressedId;\n\n\t/**\n\t * Attempts to recompresses a UUID.\n\t * @param uncompressed - the UUID 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\ttryRecompress(uncompressed: StableId): SessionSpaceCompressedId | undefined;\n}\n"]}
@@ -6,7 +6,7 @@
6
6
  * A compressed ID that has been normalized into "session space" (see `IdCompressor` for more).
7
7
  * Consumer-facing APIs and data structures should use session-space IDs as their lifetime and equality is stable and tied to
8
8
  * the scope of the session (i.e. compressor) that produced them.
9
- * @alpha
9
+ * @public
10
10
  */
11
11
  export type SessionSpaceCompressedId = number & {
12
12
  readonly SessionUnique: "cea55054-6b82-4cbf-ad19-1fa645ea3b3e";
@@ -15,7 +15,7 @@ export type SessionSpaceCompressedId = number & {
15
15
  * A compressed ID that has been normalized into "op space".
16
16
  * Serialized/persisted structures (e.g. ops) should use op-space IDs as a performance optimization, as they require less normalizing when
17
17
  * received by a remote client due to the fact that op space for a given compressor is session space for all other compressors.
18
- * @alpha
18
+ * @public
19
19
  */
20
20
  export type OpSpaceCompressedId = number & {
21
21
  readonly OpNormalized: "9209432d-a959-4df7-b2ad-767ead4dbcae";
@@ -25,14 +25,14 @@ export type OpSpaceCompressedId = number & {
25
25
  * A 128-bit Universally Unique IDentifier. Represented here
26
26
  * with a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
27
27
  * where x is a lowercase hex digit.
28
- * @alpha
28
+ * @public
29
29
  */
30
30
  export type StableId = string & {
31
31
  readonly StableId: "53172b0d-a3d5-41ea-bd75-b43839c97f5a";
32
32
  };
33
33
  /**
34
34
  * A StableId which is suitable for use as a session identifier
35
- * @alpha
35
+ * @public
36
36
  */
37
37
  export type SessionId = StableId & {
38
38
  readonly SessionId: "4498f850-e14e-4be9-8db0-89ec00997e58";
@@ -1 +1 @@
1
- {"version":3,"file":"identifiers.js","sourceRoot":"","sources":["../../src/types/identifiers.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * A compressed ID that has been normalized into \"session space\" (see `IdCompressor` for more).\n * Consumer-facing APIs and data structures should use session-space IDs as their lifetime and equality is stable and tied to\n * the scope of the session (i.e. compressor) that produced them.\n * @alpha\n */\nexport type SessionSpaceCompressedId = number & {\n\treadonly SessionUnique: \"cea55054-6b82-4cbf-ad19-1fa645ea3b3e\";\n};\n\n/**\n * A compressed ID that has been normalized into \"op space\".\n * Serialized/persisted structures (e.g. ops) should use op-space IDs as a performance optimization, as they require less normalizing when\n * received by a remote client due to the fact that op space for a given compressor is session space for all other compressors.\n * @alpha\n */\nexport type OpSpaceCompressedId = number & {\n\treadonly OpNormalized: \"9209432d-a959-4df7-b2ad-767ead4dbcae\";\n};\n\n/**\n * A version 4, variant 1 uuid (https://datatracker.ietf.org/doc/html/rfc4122).\n * A 128-bit Universally Unique IDentifier. Represented here\n * with a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,\n * where x is a lowercase hex digit.\n * @alpha\n */\nexport type StableId = string & { readonly StableId: \"53172b0d-a3d5-41ea-bd75-b43839c97f5a\" };\n\n/**\n * A StableId which is suitable for use as a session identifier\n * @alpha\n */\nexport type SessionId = StableId & { readonly SessionId: \"4498f850-e14e-4be9-8db0-89ec00997e58\" };\n"]}
1
+ {"version":3,"file":"identifiers.js","sourceRoot":"","sources":["../../src/types/identifiers.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * A compressed ID that has been normalized into \"session space\" (see `IdCompressor` for more).\n * Consumer-facing APIs and data structures should use session-space IDs as their lifetime and equality is stable and tied to\n * the scope of the session (i.e. compressor) that produced them.\n * @public\n */\nexport type SessionSpaceCompressedId = number & {\n\treadonly SessionUnique: \"cea55054-6b82-4cbf-ad19-1fa645ea3b3e\";\n};\n\n/**\n * A compressed ID that has been normalized into \"op space\".\n * Serialized/persisted structures (e.g. ops) should use op-space IDs as a performance optimization, as they require less normalizing when\n * received by a remote client due to the fact that op space for a given compressor is session space for all other compressors.\n * @public\n */\nexport type OpSpaceCompressedId = number & {\n\treadonly OpNormalized: \"9209432d-a959-4df7-b2ad-767ead4dbcae\";\n};\n\n/**\n * A version 4, variant 1 uuid (https://datatracker.ietf.org/doc/html/rfc4122).\n * A 128-bit Universally Unique IDentifier. Represented here\n * with a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,\n * where x is a lowercase hex digit.\n * @public\n */\nexport type StableId = string & { readonly StableId: \"53172b0d-a3d5-41ea-bd75-b43839c97f5a\" };\n\n/**\n * A StableId which is suitable for use as a session identifier\n * @public\n */\nexport type SessionId = StableId & { readonly SessionId: \"4498f850-e14e-4be9-8db0-89ec00997e58\" };\n"]}
@@ -121,4 +121,4 @@ export declare class AppendOnlySortedMap<K, V> {
121
121
  */
122
122
  static keyIndexOf<T, K, V>(elements: readonly (K | V)[], search: T, comparator: (search: T, key: K, value: V) => number): number;
123
123
  }
124
- //# sourceMappingURL=appendOnlySortedMap.d.ts.map
124
+ //# sourceMappingURL=appendOnlySortedMap.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appendOnlySortedMap.d.mts","sourceRoot":"","sources":["../src/appendOnlySortedMap.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,6 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- /* eslint-disable tsdoc/syntax */
6
- /* eslint-disable no-bitwise */
7
5
  import { assert } from "@fluidframework/core-utils";
8
6
  /**
9
7
  * A map in which entries are always added in key-sorted order.
@@ -311,4 +309,4 @@ export class AppendOnlySortedMap {
311
309
  * The value xor'd with the result index when a search fails.
312
310
  */
313
311
  AppendOnlySortedMap.failureXor = -1;
314
- //# sourceMappingURL=appendOnlySortedMap.js.map
312
+ //# sourceMappingURL=appendOnlySortedMap.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appendOnlySortedMap.mjs","sourceRoot":"","sources":["../src/appendOnlySortedMap.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\n/* eslint-disable tsdoc/syntax */\n/* eslint-disable no-bitwise */\nimport { assert } from \"@fluidframework/core-utils\";\n\n/**\n * A map in which entries are always added in key-sorted order.\n * Supports appending and searching.\n */\nexport class AppendOnlySortedMap<K, V> {\n\tprotected readonly elements: (K | V)[] = [];\n\n\t/**\n\t * @param comparator - a comparator for keys\n\t */\n\tpublic constructor(protected readonly comparator: (a: K, b: K) => number) {}\n\n\t/**\n\t * @returns the number of entries in this map\n\t */\n\tpublic get size(): number {\n\t\treturn this.elements.length / 2;\n\t}\n\n\t/**\n\t * @returns the min key in the map.\n\t */\n\tpublic minKey(): K | undefined {\n\t\treturn this.elements[0] as K | undefined;\n\t}\n\n\t/**\n\t * @returns the max key in the map.\n\t */\n\tpublic maxKey(): K | undefined {\n\t\treturn this.elements[this.elements.length - 2] as K | undefined;\n\t}\n\n\t/**\n\t * @returns the min value in the map.\n\t */\n\tpublic minValue(): V | undefined {\n\t\treturn this.elements[1] as V | undefined;\n\t}\n\n\t/**\n\t * @returns the min value in the map.\n\t */\n\tpublic maxValue(): V | undefined {\n\t\treturn this.elements[this.elements.length - 1] as V | undefined;\n\t}\n\n\t/**\n\t * @returns the min key in the map.\n\t */\n\tpublic first(): [K, V] | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [elements[0] as K, elements[1] as V];\n\t}\n\n\t/**\n\t * @returns the max key in the map.\n\t */\n\tpublic last(): [K, V] | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst lastKeyIndex = length - 2;\n\t\treturn [elements[lastKeyIndex] as K, elements[lastKeyIndex + 1] as V];\n\t}\n\n\t/**\n\t * Returns the element at the insertion index.\n\t */\n\tpublic getAtIndex(index: number): [K, V] | undefined {\n\t\tconst realIndex = index * 2;\n\t\tconst { elements } = this;\n\t\tif (realIndex < 0 || realIndex > elements.length - 1) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [elements[realIndex] as K, elements[realIndex + 1] as V];\n\t}\n\n\t/**\n\t * @returns an iterable of the entries in the map.\n\t */\n\tpublic *entries(): IterableIterator<readonly [K, V]> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield [elements[i] as K, elements[i + 1] as V];\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the keys in the map.\n\t */\n\tpublic *keys(): IterableIterator<K> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield elements[i] as K;\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the values in the map.\n\t */\n\tpublic *values(): IterableIterator<V> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield elements[i + 1] as V;\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the entries in the map, reversed.\n\t */\n\tpublic *entriesReversed(): IterableIterator<readonly [K, V]> {\n\t\tconst { elements } = this;\n\t\tfor (let i = elements.length - 2; i >= 0; i -= 2) {\n\t\t\tyield [elements[i] as K, elements[i + 1] as V];\n\t\t}\n\t}\n\n\t/**\n\t * Adds a new key/value pair to the map. `key` must be > to all keys in the map.\n\t * @param key - the key to add.\n\t * @param value - the value to add.\n\t */\n\tpublic append(key: K, value: V): void {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length !== 0 && this.comparator(key, this.maxKey() as K) <= 0) {\n\t\t\tthrow new Error(\"Inserted key must be > all others in the map.\");\n\t\t}\n\t\telements.push(key);\n\t\telements.push(value);\n\t}\n\n\t/**\n\t * Replaces the last key/value pair with the given one. If the map is empty, it simply appends.\n\t * `key` must be > to all keys in the map prior to the one replaced.\n\t * @param key - the key to add.\n\t * @param value - the value to add.\n\t */\n\tpublic replaceLast(key: K, value: V): void {\n\t\tconst { elements, comparator } = this;\n\t\tconst { length } = elements;\n\t\tif (length !== 0) {\n\t\t\telements.pop();\n\t\t\telements.pop();\n\t\t\tif (comparator(key, this.maxKey() as K) <= 0) {\n\t\t\t\tthrow new Error(\"Inserted key must be > all others in the map.\");\n\t\t\t}\n\t\t}\n\t\telements.push(key);\n\t\telements.push(value);\n\t}\n\n\t/**\n\t * @param key - the key to lookup.\n\t * @returns the value associated with `key` if such an entry exists, and undefined otherwise.\n\t */\n\tpublic get(key: K): V | undefined {\n\t\tconst index = AppendOnlySortedMap.keyIndexOf(this.elements, key, this.comparator);\n\t\tif (index < 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.elements[index + 1] as V;\n\t}\n\n\t/**\n\t * @param key - the key to lookup.\n\t * @returns the entry associated with `key` if such an entry exists, the entry associated with the next lower key if such an entry\n\t * exists, and undefined otherwise.\n\t */\n\tpublic getPairOrNextLower(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextLowerBy(key, this.comparator);\n\t}\n\n\t/**\n\t * @param key - the key to lookup.\n\t * @returns the entry associated with `key` if such an entry exists, the entry associated with the next higher key if such an entry\n\t * exists, and undefined otherwise.\n\t */\n\tpublic getPairOrNextHigher(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextHigherBy(key, this.comparator);\n\t}\n\n\t/**\n\t * Compares two `AppendOnlySortedMap`s.\n\t */\n\tpublic equals(\n\t\tother: AppendOnlySortedMap<K, V>,\n\t\tcompareValues: (a: V, b: V) => boolean,\n\t): boolean {\n\t\tif (other === this) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (this.elements.length !== other.elements.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (let i = this.elements.length - 2; i >= 0; i -= 2) {\n\t\t\tconst keyThis = this.elements[i] as K;\n\t\t\tconst valueThis = this.elements[i + 1] as V;\n\t\t\tconst keyOther = other.elements[i] as K;\n\t\t\tconst valueOther = other.elements[i + 1] as V;\n\t\t\tif (this.comparator(keyThis, keyOther) !== 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!compareValues(valueThis, valueOther)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Test-only expensive assertions to check the internal validity of the data structure.\n\t */\n\tpublic assertValid(): void {\n\t\tlet prev: readonly [K, unknown] | undefined;\n\t\tfor (const kv of this.entries()) {\n\t\t\tif (prev !== undefined) {\n\t\t\t\tassert(\n\t\t\t\t\tthis.comparator(kv[0], prev[0]) > 0,\n\t\t\t\t\t0x752 /* Keys in map must be sorted. */,\n\t\t\t\t);\n\t\t\t}\n\t\t\tprev = kv;\n\t\t}\n\t}\n\n\t/**\n\t * Queries a range of entries.\n\t * @param from - the key to start the range query at, inclusive.\n\t * @param to - the key to end the range query at, inclusive.\n\t * @returns the range of entries.\n\t */\n\tpublic *getRange(from: K, to: K): IterableIterator<readonly [K, V]> {\n\t\tconst keyIndexFrom = this.getKeyIndexOfOrNextHigher(from, this.comparator);\n\t\tif (keyIndexFrom === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst keyIndexTo = this.getKeyIndexOfOrNextLower(to, this.comparator);\n\t\tif (keyIndexTo === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = keyIndexFrom; i <= keyIndexTo; i += 2) {\n\t\t\tyield [this.elements[i] as K, this.elements[i + 1] as V];\n\t\t}\n\t}\n\n\tprotected getPairOrNextLowerBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): readonly [K, V] | undefined {\n\t\tconst keyIndex = this.getKeyIndexOfOrNextLower(search, comparator);\n\t\tif (keyIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn [this.elements[keyIndex] as K, this.elements[keyIndex + 1] as V];\n\t}\n\n\tprivate getKeyIndexOfOrNextLower<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number | undefined {\n\t\tconst { elements } = this;\n\t\tif (elements.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);\n\t\tif (keyIndex < 0) {\n\t\t\tkeyIndex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (keyIndex > 0) {\n\t\t\t\treturn keyIndex - 2;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn keyIndex;\n\t}\n\n\tprotected getPairOrNextHigherBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): readonly [K, V] | undefined {\n\t\tconst keyIndex = this.getKeyIndexOfOrNextHigher(search, comparator);\n\t\tif (keyIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn [this.elements[keyIndex] as K, this.elements[keyIndex + 1] as V];\n\t}\n\n\tprivate getKeyIndexOfOrNextHigher<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);\n\t\tif (keyIndex < 0) {\n\t\t\tkeyIndex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (keyIndex < length) {\n\t\t\t\treturn keyIndex;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn keyIndex;\n\t}\n\n\t/**\n\t * The value xor'd with the result index when a search fails.\n\t */\n\tpublic static readonly failureXor = -1;\n\n\t/**\n\t * Performs a binary search on the sorted array.\n\t * @returns the index of the key for `search`, or (if not present) the index it would have been inserted into xor'd\n\t * with `failureXor`. Note that negating is not an adequate solution as that could result in -0.\n\t */\n\tpublic static keyIndexOf<T, K, V>(\n\t\telements: readonly (K | V)[],\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number {\n\t\t// Low, high, and mid are addresses of [K,V] pairs and *not* key indices\n\t\tlet low = 0;\n\t\tlet high = elements.length / 2;\n\t\tlet mid = high >> 1;\n\t\twhile (low < high) {\n\t\t\tconst keyIndex = mid * 2;\n\t\t\tconst c = comparator(search, elements[keyIndex] as K, elements[keyIndex + 1] as V);\n\t\t\tif (c > 0) {\n\t\t\t\tlow = mid + 1;\n\t\t\t} else if (c < 0) {\n\t\t\t\thigh = mid;\n\t\t\t} else if (c === 0) {\n\t\t\t\treturn keyIndex;\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid comparator.\");\n\t\t\t}\n\t\t\tmid = (low + high) >> 1;\n\t\t}\n\t\treturn (mid * 2) ^ AppendOnlySortedMap.failureXor;\n\t}\n}\n"]}
@@ -2,8 +2,8 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { IdCluster } from "./sessions";
6
- import { FinalCompressedId } from "./identifiers";
5
+ import { IdCluster } from "./sessions.mjs";
6
+ import { FinalCompressedId } from "./identifiers.mjs";
7
7
  /**
8
8
  * All IDs that have been finalized (acked), grouped into clusters sorted by their base final IDs.
9
9
  * These clusters span the positive integer space and are not sparse, meaning a cluster's base final
@@ -26,4 +26,4 @@ export declare class FinalSpace {
26
26
  getAllocatedIdLimit(): FinalCompressedId;
27
27
  equals(other: FinalSpace): boolean;
28
28
  }
29
- //# sourceMappingURL=finalSpace.d.ts.map
29
+ //# sourceMappingURL=finalSpace.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalSpace.d.mts","sourceRoot":"","sources":["../src/finalSpace.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAGI,EAAE,SAAS,EAAyD;OACpE,EAAE,iBAAiB,EAAE;AAE5B;;;;GAIG;AACH,qBAAa,UAAU;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAE/C,IAAW,QAAQ,IAAI,SAAS,SAAS,EAAE,CAE1C;IAEM,cAAc,IAAI,SAAS,GAAG,SAAS;IAIvC,UAAU,CAAC,UAAU,EAAE,SAAS;IAWvC;;;OAGG;IACI,mBAAmB,IAAI,iBAAiB;IAO/C;;;OAGG;IACI,mBAAmB,IAAI,iBAAiB;IAOxC,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;CAQzC"}
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { assert } from "@fluidframework/core-utils";
6
- import { clustersEqual, lastAllocatedFinal, lastFinalizedFinal } from "./sessions";
6
+ import { clustersEqual, lastAllocatedFinal, lastFinalizedFinal } from "./sessions.mjs";
7
7
  /**
8
8
  * All IDs that have been finalized (acked), grouped into clusters sorted by their base final IDs.
9
9
  * These clusters span the positive integer space and are not sparse, meaning a cluster's base final
@@ -55,4 +55,4 @@ export class FinalSpace {
55
55
  return this.clusterList.length === other.clusterList.length;
56
56
  }
57
57
  }
58
- //# sourceMappingURL=finalSpace.js.map
58
+ //# sourceMappingURL=finalSpace.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalSpace.mjs","sourceRoot":"","sources":["../src/finalSpace.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAEI,EAAE,MAAM,EAAE,MAAM,4BAA4B;OAC5C,EAAa,aAAa,EAAE,kBAAkB,EAAE,kBAAkB,EAAE;AAG3E;;;;GAIG;AACH,MAAM,OAAO,UAAU;IAAvB;QACkB,gBAAW,GAAgB,EAAE,CAAC;IAmDhD,CAAC;IAjDA,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAEM,cAAc;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC;IAEM,UAAU,CAAC,UAAqB;QACtC,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,MAAM,CACL,WAAW,KAAK,SAAS;YACxB,qEAAqE;YACrE,UAAU,CAAC,WAAW,KAAK,WAAW,CAAC,WAAW,GAAG,WAAW,CAAC,QAAQ,EAC1E,KAAK,CAAC,oDAAoD,CAC1D,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAED;;;OAGG;IACI,mBAAmB;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,OAAO,WAAW,KAAK,SAAS;YAC/B,CAAC,CAAE,CAAuB;YAC1B,CAAC,CAAE,CAAE,kBAAkB,CAAC,WAAW,CAAY,GAAG,CAAC,CAAuB,CAAC;IAC7E,CAAC;IAED;;;OAGG;IACI,mBAAmB;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,OAAO,WAAW,KAAK,SAAS;YAC/B,CAAC,CAAE,CAAuB;YAC1B,CAAC,CAAE,CAAE,kBAAkB,CAAC,WAAW,CAAY,GAAG,CAAC,CAAuB,CAAC;IAC7E,CAAC;IAEM,MAAM,CAAC,KAAiB;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACjD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE;gBAC9D,OAAO,KAAK,CAAC;aACb;SACD;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;IAC7D,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IdCluster, clustersEqual, lastAllocatedFinal, lastFinalizedFinal } from \"./sessions\";\nimport { FinalCompressedId } from \"./identifiers\";\n\n/**\n * All IDs that have been finalized (acked), grouped into clusters sorted by their base final IDs.\n * These clusters span the positive integer space and are not sparse, meaning a cluster's base final\n * ID will always be one greater than the last final ID in the previous cluster (or 0 if there is not one).\n */\nexport class FinalSpace {\n\tprivate readonly clusterList: IdCluster[] = [];\n\n\tpublic get clusters(): readonly IdCluster[] {\n\t\treturn this.clusterList;\n\t}\n\n\tpublic getLastCluster(): IdCluster | undefined {\n\t\treturn this.clusterList[this.clusterList.length - 1];\n\t}\n\n\tpublic addCluster(newCluster: IdCluster) {\n\t\tconst lastCluster = this.getLastCluster();\n\t\tassert(\n\t\t\tlastCluster === undefined ||\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n\t\t\t\tnewCluster.baseFinalId === lastCluster.baseFinalId + lastCluster.capacity,\n\t\t\t0x753 /* Cluster insert to final_space is out of order. */,\n\t\t);\n\t\tthis.clusterList.push(newCluster);\n\t}\n\n\t/**\n\t * @returns the upper bound (exclusive) of finalized IDs in final space, i.e. one greater than the last final ID in the last cluster.\n\t * Note: this does not include allocated but unfinalized space in clusters.\n\t */\n\tpublic getFinalizedIdLimit(): FinalCompressedId {\n\t\tconst lastCluster = this.getLastCluster();\n\t\treturn lastCluster === undefined\n\t\t\t? (0 as FinalCompressedId)\n\t\t\t: (((lastFinalizedFinal(lastCluster) as number) + 1) as FinalCompressedId);\n\t}\n\n\t/**\n\t * @returns the upper bound (exclusive) of allocated IDs in final space, i.e. one greater than the last final ID in the last cluster.\n\t * Note: this does includes all allocated IDs in clusters.\n\t */\n\tpublic getAllocatedIdLimit(): FinalCompressedId {\n\t\tconst lastCluster = this.getLastCluster();\n\t\treturn lastCluster === undefined\n\t\t\t? (0 as FinalCompressedId)\n\t\t\t: (((lastAllocatedFinal(lastCluster) as number) + 1) as FinalCompressedId);\n\t}\n\n\tpublic equals(other: FinalSpace): boolean {\n\t\tfor (let i = 0; i < this.clusterList.length; i++) {\n\t\t\tif (!clustersEqual(this.clusterList[i], other.clusterList[i])) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn this.clusterList.length === other.clusterList.length;\n\t}\n}\n"]}
@@ -65,6 +65,7 @@ export declare class IdCompressor implements IIdCompressor, IIdCompressorCore {
65
65
  private nextRequestedClusterSize;
66
66
  private telemetryLocalIdCount;
67
67
  private telemetryEagerFinalIdCount;
68
+ private ongoingGhostSession?;
68
69
  private constructor();
69
70
  /**
70
71
  * @deprecated Use `createIdCompressor` instead.
@@ -75,6 +76,10 @@ export declare class IdCompressor implements IIdCompressor, IIdCompressorCore {
75
76
  */
76
77
  static create(sessionId: SessionId, logger?: ITelemetryBaseLogger): IIdCompressor & IIdCompressorCore;
77
78
  generateCompressedId(): SessionSpaceCompressedId;
79
+ /**
80
+ * {@inheritdoc IIdCompressorCore.beginGhostSession}
81
+ */
82
+ beginGhostSession(ghostSessionId: SessionId, ghostSessionCallback: () => void): void;
78
83
  private generateNextLocalId;
79
84
  takeNextCreationRange(): IdCreationRange;
80
85
  private static assertValidRange;
@@ -89,6 +94,7 @@ export declare class IdCompressor implements IIdCompressor, IIdCompressorCore {
89
94
  serialize(withSession: false): SerializedIdCompressorWithNoSession;
90
95
  static deserialize(serialized: SerializedIdCompressorWithOngoingSession): IdCompressor;
91
96
  static deserialize(serialized: SerializedIdCompressorWithNoSession, newSessionId: SessionId): IdCompressor;
97
+ private static deserialize2_0;
92
98
  equals(other: IdCompressor, includeLocalState: boolean): boolean;
93
99
  }
94
100
 
@@ -178,7 +184,7 @@ export declare interface IdCreationRange {
178
184
  *
179
185
  * These two spaces naturally define a rule: consumers of compressed IDs should use session-space IDs, but serialized forms such as ops
180
186
  * should use op-space IDs.
181
- * @alpha
187
+ * @public
182
188
  */
183
189
  export declare interface IIdCompressor {
184
190
  localSessionId: SessionId;
@@ -240,6 +246,27 @@ export declare interface IIdCompressorCore {
240
246
  * @param range - the range of session-local IDs to finalize.
241
247
  */
242
248
  finalizeCreationRange(range: IdCreationRange): void;
249
+ /**
250
+ * Run a callback that is performed from the perspective of a special "ghost" session.
251
+ * Any ids generated by this session will be immediately finalized on the local client as if
252
+ * they were created by a remote client with `ghostSessionId`.
253
+ *
254
+ * *WARNING:* This API requires an external consensus mechanism to safely use:
255
+ * In an attached container (i.e. multiple clients may have the document loaded), all clients must guarantee that:
256
+ * - They invoke this API starting from the same finalized creation ranges
257
+ * - This API is invoked with the same ghost session id
258
+ * - `ghostSessionCallback` deterministically mints the same number of ids on each client within the ghost session
259
+ * Failure to meet these requirement will result in divergence across clients and eventual consistency errors.
260
+ * While the ghost sesion callback is running, IdCompressor does not support serialization.
261
+ * @remarks This API is primarily intended for data migration scenarios which are able to deterministically transform
262
+ * data in some format into data in a new format.
263
+ * The first requirement (that all clients must invoke the API with the same finalized creation ranges) is guaranteed
264
+ * for this scenario because the data transformation callback occurs at a specific ack within the op stream on all
265
+ * clients, and clients don't finalize creation ranges for local changes they might have at this point in time.
266
+ * @param ghostSessionId - The session id that minted ids generated within `ghostSessionCallback` should be attributed to.
267
+ * @param ghostSessionCallback - Callback which mints ids attributed to the ghost session.
268
+ */
269
+ beginGhostSession(ghostSessionId: SessionId, ghostSessionCallback: () => void): any;
243
270
  /**
244
271
  * Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.
245
272
  * This includes finalized state as well as un-finalized state and is therefore suitable for use in offline scenarios.
@@ -258,7 +285,7 @@ export declare interface IIdCompressorCore {
258
285
  * A compressed ID that has been normalized into "op space".
259
286
  * Serialized/persisted structures (e.g. ops) should use op-space IDs as a performance optimization, as they require less normalizing when
260
287
  * received by a remote client due to the fact that op space for a given compressor is session space for all other compressors.
261
- * @alpha
288
+ * @public
262
289
  */
263
290
  export declare type OpSpaceCompressedId = number & {
264
291
  readonly OpNormalized: "9209432d-a959-4df7-b2ad-767ead4dbcae";
@@ -290,7 +317,7 @@ export declare type SerializedIdCompressorWithOngoingSession = SerializedIdCompr
290
317
 
291
318
  /**
292
319
  * A StableId which is suitable for use as a session identifier
293
- * @alpha
320
+ * @public
294
321
  */
295
322
  export declare type SessionId = StableId & {
296
323
  readonly SessionId: "4498f850-e14e-4be9-8db0-89ec00997e58";
@@ -300,7 +327,7 @@ export declare type SessionId = StableId & {
300
327
  * A compressed ID that has been normalized into "session space" (see `IdCompressor` for more).
301
328
  * Consumer-facing APIs and data structures should use session-space IDs as their lifetime and equality is stable and tied to
302
329
  * the scope of the session (i.e. compressor) that produced them.
303
- * @alpha
330
+ * @public
304
331
  */
305
332
  export declare type SessionSpaceCompressedId = number & {
306
333
  readonly SessionUnique: "cea55054-6b82-4cbf-ad19-1fa645ea3b3e";
@@ -311,7 +338,7 @@ export declare type SessionSpaceCompressedId = number & {
311
338
  * A 128-bit Universally Unique IDentifier. Represented here
312
339
  * with a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
313
340
  * where x is a lowercase hex digit.
314
- * @alpha
341
+ * @public
315
342
  */
316
343
  export declare type StableId = string & {
317
344
  readonly StableId: "53172b0d-a3d5-41ea-bd75-b43839c97f5a";
@@ -0,0 +1,172 @@
1
+ import { ITelemetryBaseLogger } from '@fluidframework/core-interfaces';
2
+
3
+ /* Excluded from this release type: assertIsStableId */
4
+
5
+ /* Excluded from this release type: createIdCompressor */
6
+
7
+ /* Excluded from this release type: createSessionId */
8
+
9
+ /* Excluded from this release type: deserializeIdCompressor */
10
+
11
+ /* Excluded from this release type: generateStableId */
12
+
13
+ /* Excluded from this release type: IdCompressor */
14
+
15
+ /* Excluded from this release type: IdCreationRange */
16
+
17
+ /**
18
+ * A distributed UUID generator and compressor.
19
+ *
20
+ * Generates arbitrary non-colliding v4 UUIDs, called stable IDs, for multiple "sessions" (which can be distributed across the network),
21
+ * providing each session with the ability to map these UUIDs to `numbers`.
22
+ *
23
+ * A session is a unique identifier that denotes a single compressor. New IDs are created through a single compressor API
24
+ * which should then sent in ranges to the server for total ordering (and are subsequently relayed to other clients). When a new ID is
25
+ * created it is said to be created by the compressor's "local" session.
26
+ *
27
+ * For each stable ID created, two numeric IDs are provided by the compressor:
28
+ *
29
+ * 1. A session-local ID, which is stable for the lifetime of the session (which could be longer than that of the compressor object, as it may
30
+ * be serialized for offline usage). Available as soon as the stable ID is allocated. These IDs are session-unique and are thus only
31
+ * safely usable within the scope of the compressor that created it.
32
+ *
33
+ * 2. A final ID, which is stable across serialization and deserialization of an IdCompressor. Available as soon as the range containing
34
+ * the corresponding session-local ID is totally ordered (via consensus) with respect to other sessions' allocations.
35
+ * Final IDs are known to and publicly usable by any compressor that has received them.
36
+ *
37
+ * Compressors will allocate UUIDs in non-random ways to reduce entropy allowing for optimized storage of the data needed
38
+ * to map the UUIDs to the numbers.
39
+ *
40
+ * The following invariants are upheld by IdCompressor:
41
+ *
42
+ * 1. Session-local IDs will always decompress to the same UUIDs for the lifetime of the session.
43
+ *
44
+ * 2. Final IDs will always decompress to the same UUIDs.
45
+ *
46
+ * 3. After a server-processed range of session-local IDs (from any session) is received by a compressor, any of those session-local IDs may be
47
+ * translated by the compressor into the corresponding final ID. For any given session-local ID, this translation will always yield the
48
+ * same final ID.
49
+ *
50
+ * 4. A UUID will always compress into the same session-local ID for the lifetime of the session.
51
+ *
52
+ * Session-local IDs are sent across the wire in efficiently-represented ranges. These ranges are created by querying the compressor, and *must*
53
+ * be ordered (i.e. sent to the server) in the order they are created in order to preserve the above invariants.
54
+ *
55
+ * Session-local IDs can be used immediately after creation, but will eventually (after being sequenced) have a corresponding final ID. This
56
+ * could make reasoning about equality of those two forms difficult. For example, if a cache is keyed off of a
57
+ * session-local ID but is later queried using the final ID (which is semantically equal, as it decompresses to the same UUID/string) it will
58
+ * produce a cache miss. In order to make using collections of both remotely created and locally created IDs easy, regardless of whether the
59
+ * session-local IDs have been finalized, the compressor defines two "spaces" of IDs:
60
+ *
61
+ * 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
62
+ * will be in local form, regardless of if they have been finalized. Remotely created IDs, which could only have been received after
63
+ * 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
64
+ * 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
65
+ * these IDs across compressor objects, as the local IDs are specific to the compressor that created them.
66
+ *
67
+ * 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
68
+ * 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
69
+ * 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
70
+ * out of Op space over time, namely, when a session-local ID in this space becomes finalized, and thereafter has a "more final form".
71
+ * Consequentially, it may be useful to restrict parameters of a persisted type to this space (to optimize perf), but it is potentially
72
+ * 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
73
+ * "local as possible".
74
+ *
75
+ * These two spaces naturally define a rule: consumers of compressed IDs should use session-space IDs, but serialized forms such as ops
76
+ * should use op-space IDs.
77
+ * @public
78
+ */
79
+ export declare interface IIdCompressor {
80
+ localSessionId: SessionId;
81
+ /**
82
+ * Generates a new compressed ID or returns an existing one.
83
+ * This should ONLY be called to generate IDs for local operations.
84
+ * @returns A new local ID in session space.
85
+ */
86
+ generateCompressedId(): SessionSpaceCompressedId;
87
+ /**
88
+ * Normalizes a session space ID into op space.
89
+ * @param id - the local ID to normalize.
90
+ * @returns the ID in op space.
91
+ */
92
+ normalizeToOpSpace(id: SessionSpaceCompressedId): OpSpaceCompressedId;
93
+ /**
94
+ * Normalizes an ID into session space.
95
+ * @param id - the ID to normalize. If it is a local ID, it is assumed to have been created by the session corresponding
96
+ * to `sessionId`.
97
+ * @param originSessionId - the session from which `id` originated
98
+ * @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
99
+ * 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
100
+ * range that contained it from the server.
101
+ */
102
+ normalizeToSessionSpace(id: OpSpaceCompressedId, originSessionId: SessionId): SessionSpaceCompressedId;
103
+ /**
104
+ * Decompresses a previously compressed ID into a UUID.
105
+ * @param id - the compressed ID to be decompressed.
106
+ * @returns the UUID associated with the compressed ID. Fails if the ID was not generated by this compressor.
107
+ */
108
+ decompress(id: SessionSpaceCompressedId): StableId;
109
+ /**
110
+ * Recompresses a UUID.
111
+ * @param uncompressed - the UUID to recompress.
112
+ * @returns the `CompressedId` associated with `uncompressed`. Fails if it has not been previously compressed by this compressor.
113
+ */
114
+ recompress(uncompressed: StableId): SessionSpaceCompressedId;
115
+ /**
116
+ * Attempts to recompresses a UUID.
117
+ * @param uncompressed - the UUID to recompress,
118
+ * @returns the `CompressedId` associated with `uncompressed` or undefined if it has not been previously compressed by this compressor.
119
+ */
120
+ tryRecompress(uncompressed: StableId): SessionSpaceCompressedId | undefined;
121
+ }
122
+
123
+ /* Excluded from this release type: IIdCompressorCore */
124
+
125
+ /* Excluded from this release type: isStableId */
126
+
127
+ /**
128
+ * A compressed ID that has been normalized into "op space".
129
+ * Serialized/persisted structures (e.g. ops) should use op-space IDs as a performance optimization, as they require less normalizing when
130
+ * received by a remote client due to the fact that op space for a given compressor is session space for all other compressors.
131
+ * @public
132
+ */
133
+ export declare type OpSpaceCompressedId = number & {
134
+ readonly OpNormalized: "9209432d-a959-4df7-b2ad-767ead4dbcae";
135
+ };
136
+
137
+ /* Excluded from this release type: SerializedIdCompressor */
138
+
139
+ /* Excluded from this release type: SerializedIdCompressorWithNoSession */
140
+
141
+ /* Excluded from this release type: SerializedIdCompressorWithOngoingSession */
142
+
143
+ /**
144
+ * A StableId which is suitable for use as a session identifier
145
+ * @public
146
+ */
147
+ export declare type SessionId = StableId & {
148
+ readonly SessionId: "4498f850-e14e-4be9-8db0-89ec00997e58";
149
+ };
150
+
151
+ /**
152
+ * A compressed ID that has been normalized into "session space" (see `IdCompressor` for more).
153
+ * Consumer-facing APIs and data structures should use session-space IDs as their lifetime and equality is stable and tied to
154
+ * the scope of the session (i.e. compressor) that produced them.
155
+ * @public
156
+ */
157
+ export declare type SessionSpaceCompressedId = number & {
158
+ readonly SessionUnique: "cea55054-6b82-4cbf-ad19-1fa645ea3b3e";
159
+ };
160
+
161
+ /**
162
+ * A version 4, variant 1 uuid (https://datatracker.ietf.org/doc/html/rfc4122).
163
+ * A 128-bit Universally Unique IDentifier. Represented here
164
+ * with a string of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,
165
+ * where x is a lowercase hex digit.
166
+ * @public
167
+ */
168
+ export declare type StableId = string & {
169
+ readonly StableId: "53172b0d-a3d5-41ea-bd75-b43839c97f5a";
170
+ };
171
+
172
+ export { }