@fluidframework/id-compressor 2.0.0-rc.1.0.6 → 2.0.0-rc.2.0.1

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 (264) hide show
  1. package/{.eslintrc.js → .eslintrc.cjs} +5 -5
  2. package/{.mocharc.js → .mocharc.cjs} +1 -1
  3. package/CHANGELOG.md +8 -0
  4. package/{api-extractor-esm.json → api-extractor-cjs.json} +5 -1
  5. package/api-extractor-lint.json +1 -1
  6. package/api-extractor.json +1 -1
  7. package/api-report/id-compressor.api.md +5 -42
  8. package/dist/finalSpace.d.ts +2 -2
  9. package/dist/finalSpace.d.ts.map +1 -1
  10. package/dist/finalSpace.js +4 -4
  11. package/dist/finalSpace.js.map +1 -1
  12. package/dist/id-compressor-alpha.d.ts +117 -112
  13. package/dist/id-compressor-beta.d.ts +84 -77
  14. package/dist/id-compressor-public.d.ts +84 -77
  15. package/dist/id-compressor-untrimmed.d.ts +117 -112
  16. package/dist/idCompressor.d.ts +15 -19
  17. package/dist/idCompressor.d.ts.map +1 -1
  18. package/dist/idCompressor.js +107 -94
  19. package/dist/idCompressor.js.map +1 -1
  20. package/dist/identifiers.d.ts +1 -1
  21. package/dist/identifiers.d.ts.map +1 -1
  22. package/dist/identifiers.js.map +1 -1
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +9 -10
  26. package/dist/index.js.map +1 -1
  27. package/dist/package.json +3 -0
  28. package/dist/packageVersion.d.ts +1 -1
  29. package/dist/packageVersion.js +1 -1
  30. package/dist/packageVersion.js.map +1 -1
  31. package/dist/persistanceUtilities.d.ts +1 -1
  32. package/dist/persistanceUtilities.d.ts.map +1 -1
  33. package/dist/persistanceUtilities.js.map +1 -1
  34. package/dist/sessionSpaceNormalizer.d.ts +2 -2
  35. package/dist/sessionSpaceNormalizer.d.ts.map +1 -1
  36. package/dist/sessionSpaceNormalizer.js +4 -4
  37. package/dist/sessionSpaceNormalizer.js.map +1 -1
  38. package/dist/sessions.d.ts +2 -2
  39. package/dist/sessions.d.ts.map +1 -1
  40. package/dist/sessions.js +12 -12
  41. package/dist/sessions.js.map +1 -1
  42. package/dist/test/appendOnlySortedMap.perf.spec.d.ts +6 -0
  43. package/dist/test/appendOnlySortedMap.perf.spec.d.ts.map +1 -0
  44. package/dist/test/appendOnlySortedMap.perf.spec.js.map +1 -0
  45. package/dist/test/appendOnlySortedMap.spec.d.ts +6 -0
  46. package/dist/test/appendOnlySortedMap.spec.d.ts.map +1 -0
  47. package/dist/test/appendOnlySortedMap.spec.js.map +1 -0
  48. package/dist/test/idCompressor.perf.spec.d.ts +6 -0
  49. package/dist/test/idCompressor.perf.spec.d.ts.map +1 -0
  50. package/dist/test/idCompressor.perf.spec.js.map +1 -0
  51. package/dist/test/idCompressor.spec.d.ts +6 -0
  52. package/dist/test/idCompressor.spec.d.ts.map +1 -0
  53. package/dist/test/idCompressor.spec.js.map +1 -0
  54. package/dist/test/idCompressorTestUtilities.d.ts +245 -0
  55. package/dist/test/idCompressorTestUtilities.d.ts.map +1 -0
  56. package/dist/test/idCompressorTestUtilities.js +589 -0
  57. package/dist/test/idCompressorTestUtilities.js.map +1 -0
  58. package/dist/test/index.d.ts +9 -0
  59. package/dist/test/index.d.ts.map +1 -0
  60. package/dist/test/index.js +13 -0
  61. package/dist/test/index.js.map +1 -0
  62. package/dist/test/numericUuid.spec.d.ts +6 -0
  63. package/dist/test/numericUuid.spec.d.ts.map +1 -0
  64. package/dist/test/numericUuid.spec.js.map +1 -0
  65. package/dist/test/sessionSpaceNormalizer.spec.d.ts +6 -0
  66. package/dist/test/sessionSpaceNormalizer.spec.d.ts.map +1 -0
  67. package/dist/test/sessionSpaceNormalizer.spec.js.map +1 -0
  68. package/dist/test/snapshots/dirname.cjs +16 -0
  69. package/dist/test/snapshots/dirname.cjs.map +1 -0
  70. package/dist/test/snapshots/dirname.d.cts +6 -0
  71. package/dist/test/snapshots/dirname.d.cts.map +1 -0
  72. package/{lib/types/idCompressor.mjs → dist/test/snapshots/summary.spec.d.ts} +1 -1
  73. package/dist/test/snapshots/summary.spec.d.ts.map +1 -0
  74. package/dist/test/snapshots/summary.spec.js.map +1 -0
  75. package/dist/test/testCommon.d.ts +90 -0
  76. package/dist/test/testCommon.d.ts.map +1 -0
  77. package/dist/test/testCommon.js +90 -0
  78. package/dist/test/testCommon.js.map +1 -0
  79. package/dist/tsdoc-metadata.json +1 -1
  80. package/dist/types/idCompressor.d.ts +134 -67
  81. package/dist/types/idCompressor.d.ts.map +1 -1
  82. package/dist/types/idCompressor.js.map +1 -1
  83. package/dist/types/index.d.ts +3 -3
  84. package/dist/types/index.d.ts.map +1 -1
  85. package/dist/types/index.js.map +1 -1
  86. package/dist/types/persisted-types/0.0.1.d.ts +1 -1
  87. package/dist/types/persisted-types/0.0.1.d.ts.map +1 -1
  88. package/dist/types/persisted-types/0.0.1.js.map +1 -1
  89. package/dist/types/persisted-types/index.d.ts +1 -1
  90. package/dist/types/persisted-types/index.d.ts.map +1 -1
  91. package/dist/types/persisted-types/index.js.map +1 -1
  92. package/dist/utilities.d.ts +2 -2
  93. package/dist/utilities.d.ts.map +1 -1
  94. package/dist/utilities.js.map +1 -1
  95. package/lib/{appendOnlySortedMap.d.mts → appendOnlySortedMap.d.ts} +1 -1
  96. package/lib/appendOnlySortedMap.d.ts.map +1 -0
  97. package/lib/{appendOnlySortedMap.mjs → appendOnlySortedMap.js} +3 -1
  98. package/lib/appendOnlySortedMap.js.map +1 -0
  99. package/lib/{finalSpace.d.mts → finalSpace.d.ts} +3 -3
  100. package/lib/finalSpace.d.ts.map +1 -0
  101. package/lib/{finalSpace.mjs → finalSpace.js} +2 -2
  102. package/lib/finalSpace.js.map +1 -0
  103. package/lib/{id-compressor-alpha.d.mts → id-compressor-alpha.d.ts} +117 -112
  104. package/lib/id-compressor-beta.d.ts +179 -0
  105. package/lib/id-compressor-public.d.ts +179 -0
  106. package/lib/{id-compressor-untrimmed.d.mts → id-compressor-untrimmed.d.ts} +117 -112
  107. package/lib/{idCompressor.d.mts → idCompressor.d.ts} +16 -20
  108. package/lib/idCompressor.d.ts.map +1 -0
  109. package/lib/{idCompressor.mjs → idCompressor.js} +54 -41
  110. package/lib/idCompressor.js.map +1 -0
  111. package/lib/{identifiers.d.mts → identifiers.d.ts} +2 -2
  112. package/lib/identifiers.d.ts.map +1 -0
  113. package/lib/{identifiers.mjs → identifiers.js} +1 -1
  114. package/lib/identifiers.js.map +1 -0
  115. package/lib/{index.d.mts → index.d.ts} +7 -4
  116. package/lib/index.d.ts.map +1 -0
  117. package/lib/index.js +10 -0
  118. package/lib/index.js.map +1 -0
  119. package/lib/{packageVersion.d.mts → packageVersion.d.ts} +2 -2
  120. package/lib/packageVersion.d.ts.map +1 -0
  121. package/lib/{packageVersion.mjs → packageVersion.js} +2 -2
  122. package/lib/packageVersion.js.map +1 -0
  123. package/lib/{persistanceUtilities.d.mts → persistanceUtilities.d.ts} +2 -2
  124. package/lib/persistanceUtilities.d.ts.map +1 -0
  125. package/lib/{persistanceUtilities.mjs → persistanceUtilities.js} +1 -1
  126. package/lib/persistanceUtilities.js.map +1 -0
  127. package/lib/{sessionSpaceNormalizer.d.mts → sessionSpaceNormalizer.d.ts} +3 -3
  128. package/lib/sessionSpaceNormalizer.d.ts.map +1 -0
  129. package/lib/{sessionSpaceNormalizer.mjs → sessionSpaceNormalizer.js} +3 -3
  130. package/lib/sessionSpaceNormalizer.js.map +1 -0
  131. package/lib/{sessions.d.mts → sessions.d.ts} +3 -3
  132. package/lib/sessions.d.ts.map +1 -0
  133. package/lib/{sessions.mjs → sessions.js} +2 -2
  134. package/lib/sessions.js.map +1 -0
  135. package/lib/test/appendOnlySortedMap.perf.spec.d.ts +6 -0
  136. package/lib/test/appendOnlySortedMap.perf.spec.d.ts.map +1 -0
  137. package/lib/test/appendOnlySortedMap.perf.spec.js +49 -0
  138. package/lib/test/appendOnlySortedMap.perf.spec.js.map +1 -0
  139. package/lib/test/appendOnlySortedMap.spec.d.ts +6 -0
  140. package/lib/test/appendOnlySortedMap.spec.d.ts.map +1 -0
  141. package/lib/test/appendOnlySortedMap.spec.js +166 -0
  142. package/lib/test/appendOnlySortedMap.spec.js.map +1 -0
  143. package/lib/test/idCompressor.perf.spec.d.ts +6 -0
  144. package/lib/test/idCompressor.perf.spec.d.ts.map +1 -0
  145. package/lib/test/idCompressor.perf.spec.js +281 -0
  146. package/lib/test/idCompressor.perf.spec.js.map +1 -0
  147. package/lib/test/idCompressor.spec.d.ts +6 -0
  148. package/lib/test/idCompressor.spec.d.ts.map +1 -0
  149. package/lib/test/idCompressor.spec.js +953 -0
  150. package/lib/test/idCompressor.spec.js.map +1 -0
  151. package/lib/test/idCompressorTestUtilities.d.ts +245 -0
  152. package/lib/test/idCompressorTestUtilities.d.ts.map +1 -0
  153. package/lib/test/idCompressorTestUtilities.js +576 -0
  154. package/lib/test/idCompressorTestUtilities.js.map +1 -0
  155. package/lib/test/index.d.ts +9 -0
  156. package/lib/test/index.d.ts.map +1 -0
  157. package/lib/test/index.js +9 -0
  158. package/lib/test/index.js.map +1 -0
  159. package/lib/test/numericUuid.spec.d.ts +6 -0
  160. package/lib/test/numericUuid.spec.d.ts.map +1 -0
  161. package/lib/test/numericUuid.spec.js +74 -0
  162. package/lib/test/numericUuid.spec.js.map +1 -0
  163. package/lib/test/sessionSpaceNormalizer.spec.d.ts +6 -0
  164. package/lib/test/sessionSpaceNormalizer.spec.d.ts.map +1 -0
  165. package/lib/test/sessionSpaceNormalizer.spec.js +43 -0
  166. package/lib/test/sessionSpaceNormalizer.spec.js.map +1 -0
  167. package/lib/test/snapshots/dirname.cjs +16 -0
  168. package/lib/test/snapshots/dirname.cjs.map +1 -0
  169. package/lib/test/snapshots/dirname.d.cts +6 -0
  170. package/lib/test/snapshots/dirname.d.cts.map +1 -0
  171. package/lib/test/snapshots/summary.spec.d.ts +6 -0
  172. package/lib/test/snapshots/summary.spec.d.ts.map +1 -0
  173. package/lib/test/snapshots/summary.spec.js +127 -0
  174. package/lib/test/snapshots/summary.spec.js.map +1 -0
  175. package/lib/test/testCommon.d.ts +90 -0
  176. package/lib/test/testCommon.d.ts.map +1 -0
  177. package/lib/test/testCommon.js +80 -0
  178. package/lib/test/testCommon.js.map +1 -0
  179. package/lib/types/{idCompressor.d.mts → idCompressor.d.ts} +135 -68
  180. package/lib/types/idCompressor.d.ts.map +1 -0
  181. package/lib/types/{identifiers.mjs → idCompressor.js} +1 -1
  182. package/lib/types/idCompressor.js.map +1 -0
  183. package/lib/types/{identifiers.d.mts → identifiers.d.ts} +1 -1
  184. package/lib/types/identifiers.d.ts.map +1 -0
  185. package/lib/types/identifiers.js +6 -0
  186. package/lib/types/identifiers.js.map +1 -0
  187. package/lib/types/{index.d.mts → index.d.ts} +4 -4
  188. package/lib/types/index.d.ts.map +1 -0
  189. package/lib/types/{persisted-types/0.0.1.mjs → index.js} +1 -1
  190. package/lib/types/index.js.map +1 -0
  191. package/lib/types/persisted-types/{0.0.1.d.mts → 0.0.1.d.ts} +2 -2
  192. package/lib/types/persisted-types/0.0.1.d.ts.map +1 -0
  193. package/lib/types/persisted-types/{index.mjs → 0.0.1.js} +1 -1
  194. package/lib/types/persisted-types/0.0.1.js.map +1 -0
  195. package/lib/types/persisted-types/{index.d.mts → index.d.ts} +2 -2
  196. package/lib/types/persisted-types/index.d.ts.map +1 -0
  197. package/lib/types/{index.mjs → persisted-types/index.js} +1 -1
  198. package/lib/types/persisted-types/index.js.map +1 -0
  199. package/lib/{utilities.d.mts → utilities.d.ts} +3 -3
  200. package/lib/utilities.d.ts.map +1 -0
  201. package/lib/{utilities.mjs → utilities.js} +2 -1
  202. package/lib/utilities.js.map +1 -0
  203. package/package.json +87 -21
  204. package/src/finalSpace.ts +2 -2
  205. package/src/idCompressor.ts +75 -59
  206. package/src/identifiers.ts +1 -1
  207. package/src/index.ts +3 -3
  208. package/src/packageVersion.ts +1 -1
  209. package/src/persistanceUtilities.ts +1 -1
  210. package/src/sessionSpaceNormalizer.ts +3 -3
  211. package/src/sessions.ts +3 -3
  212. package/src/test/idCompressorTestUtilities.ts +921 -0
  213. package/src/test/index.ts +10 -0
  214. package/src/test/snapshots/dirname.cts +13 -0
  215. package/src/test/snapshots/files/compressor-with-finalized-range-from-one-client +1 -0
  216. package/src/test/snapshots/files/compressor-with-finalized-range-from-one-client-client2 +1 -0
  217. package/src/test/snapshots/files/compressors-with-finalized-ranges-from-two-clients +1 -0
  218. package/src/test/snapshots/files/compressors-with-finalized-ranges-from-two-clients-client2 +1 -0
  219. package/src/test/snapshots/files/empty-compressor-summary +1 -0
  220. package/src/test/snapshots/files/expansion-semantics +1 -0
  221. package/src/test/snapshots/files/expansion-semantics-client2 +1 -0
  222. package/src/test/testCommon.ts +143 -0
  223. package/src/test/tsconfig.cjs.json +12 -0
  224. package/src/test/tsconfig.json +20 -0
  225. package/src/types/idCompressor.ts +147 -72
  226. package/src/types/index.ts +8 -3
  227. package/src/types/persisted-types/0.0.1.ts +1 -1
  228. package/src/types/persisted-types/index.ts +1 -1
  229. package/src/utilities.ts +2 -2
  230. package/tsconfig.cjs.json +7 -0
  231. package/tsconfig.json +2 -5
  232. package/lib/appendOnlySortedMap.d.mts.map +0 -1
  233. package/lib/appendOnlySortedMap.mjs.map +0 -1
  234. package/lib/finalSpace.d.mts.map +0 -1
  235. package/lib/finalSpace.mjs.map +0 -1
  236. package/lib/id-compressor-beta.d.mts +0 -172
  237. package/lib/id-compressor-public.d.mts +0 -172
  238. package/lib/idCompressor.d.mts.map +0 -1
  239. package/lib/idCompressor.mjs.map +0 -1
  240. package/lib/identifiers.d.mts.map +0 -1
  241. package/lib/identifiers.mjs.map +0 -1
  242. package/lib/index.d.mts.map +0 -1
  243. package/lib/index.mjs +0 -7
  244. package/lib/index.mjs.map +0 -1
  245. package/lib/packageVersion.d.mts.map +0 -1
  246. package/lib/packageVersion.mjs.map +0 -1
  247. package/lib/persistanceUtilities.d.mts.map +0 -1
  248. package/lib/persistanceUtilities.mjs.map +0 -1
  249. package/lib/sessionSpaceNormalizer.d.mts.map +0 -1
  250. package/lib/sessionSpaceNormalizer.mjs.map +0 -1
  251. package/lib/sessions.d.mts.map +0 -1
  252. package/lib/sessions.mjs.map +0 -1
  253. package/lib/types/idCompressor.d.mts.map +0 -1
  254. package/lib/types/idCompressor.mjs.map +0 -1
  255. package/lib/types/identifiers.d.mts.map +0 -1
  256. package/lib/types/identifiers.mjs.map +0 -1
  257. package/lib/types/index.d.mts.map +0 -1
  258. package/lib/types/index.mjs.map +0 -1
  259. package/lib/types/persisted-types/0.0.1.d.mts.map +0 -1
  260. package/lib/types/persisted-types/0.0.1.mjs.map +0 -1
  261. package/lib/types/persisted-types/index.d.mts.map +0 -1
  262. package/lib/types/persisted-types/index.mjs.map +0 -1
  263. package/lib/utilities.d.mts.map +0 -1
  264. package/lib/utilities.mjs.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import { ITelemetryBaseLogger } from '@fluidframework/core-interfaces';
2
+ import { ITelemetryLoggerExt } from '@fluidframework/telemetry-utils';
2
3
 
3
4
  /* Excluded from this release type: assertIsStableId */
4
5
 
@@ -10,112 +11,118 @@ import { ITelemetryBaseLogger } from '@fluidframework/core-interfaces';
10
11
 
11
12
  /* Excluded from this release type: generateStableId */
12
13
 
13
- /* Excluded from this release type: IdCompressor */
14
-
15
14
  /* Excluded from this release type: IdCreationRange */
16
15
 
17
16
  /**
18
17
  * 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.
18
+ * `IdCompressor` offers the ability to generate arbitrary non-colliding v4 UUIDs, called stable IDs, while compressing them into small integers
19
+ * for efficient storage and transmission. It also provides the ability to decompress these integers back into their original UUIDs.
20
+ *
21
+ * The compressor is designed to be used in a distributed environment, where multiple clients may be generating IDs concurrently.
22
+ * IDs generated by a compressor, via calls to `generateCompressedId`, are created in the compressor's "local" session.
23
+ * These IDs are unique within the session, but may not be unique across sessions. In the context of Fluid, the scope of a session
24
+ * is the same as the scope of a container. This means that anytime IDs are transferred between sessions, they must be translated
25
+ * through a process called "normalization":
26
+ * - The scope of a local session (in which local IDs are unique) is called the "session space" of the client.
27
+ * - The context of persisted state (in Fluid, this is the context of ops and summaries) is called "op space".
28
+ * - `SessionSpaceCompressedId`s, generated via calls to `generateCompressedId`, should NEVER be serialized directly.
29
+ * In Fluid, this means they should not be included in ops or summaries.
30
+ * - Before serialization, IDs must be normalized to op space to ensure they are interpretable by other clients.
31
+ * - Upon receipt, IDs should be normalized back to session space before use.
32
+ *
33
+ * Example Usage:
34
+ *
35
+ * ### Client A (Sender)
36
+ *
37
+ * ```typescript
38
+ * // Generate several local IDs
39
+ * const localId1 = idCompressor.generateCompressedId();
40
+ * const localId2 = idCompressor.generateCompressedId();
41
+ * const localId3 = idCompressor.generateCompressedId();
42
+ *
43
+ * // Normalize these IDs to op space for inclusion in a message
44
+ * const opSpaceId1 = idCompressor.normalizeToOpSpace(localId1);
45
+ * const opSpaceId2 = idCompressor.normalizeToOpSpace(localId2);
46
+ * const opSpaceId3 = idCompressor.normalizeToOpSpace(localId3);
47
+ *
48
+ * // Create and send a message containing these op space IDs along with the sender's session ID
49
+ * // In Fluid, this would be an op or summary
50
+ * const message = {
51
+ * sessionID: idCompressor.localSessionId,
52
+ * ids: [opSpaceId1, opSpaceId2, opSpaceId3]
53
+ * };
54
+ * ```
55
+ *
56
+ * ### Client B (Receiver)
57
+ *
58
+ * ```typescript
59
+ * // Receive the message from Client A
60
+ * const receivedMessage = ...; // In Fluid, this would be an op or summary
61
+ *
62
+ * // Normalize the received IDs back to session space, utilizing the sender's session ID
63
+ * const sessionSpaceId1 = idCompressor.normalizeToSessionSpace(receivedMessage.ids[0], receivedMessage.sessionID);
64
+ * const sessionSpaceId2 = idCompressor.normalizeToSessionSpace(receivedMessage.ids[1], receivedMessage.sessionID);
65
+ * const sessionSpaceId3 = idCompressor.normalizeToSessionSpace(receivedMessage.ids[2], receivedMessage.sessionID);
66
+ * ```
77
67
  * @public
78
68
  */
79
69
  export declare interface IIdCompressor {
70
+ /**
71
+ * The local session ID.
72
+ */
80
73
  localSessionId: SessionId;
81
74
  /**
82
- * Generates a new compressed ID or returns an existing one.
83
- * This should ONLY be called to generate IDs for local operations.
75
+ * Generates a new compressed ID.
76
+ * The returned ID is in session space and should not be serialized directly. See `IIdCompressor` for more details.
84
77
  * @returns A new local ID in session space.
85
78
  */
86
79
  generateCompressedId(): SessionSpaceCompressedId;
80
+ /**
81
+ * Generates a new ID that is guaranteed to be unique across all sessions known to this compressor without the need for any
82
+ * normalization. The returned ID is not guaranteed to be a compressed ID (small number); it may be a stable ID (UUID string).
83
+ * In Fluid, the likelihood of generating the bulkier stable ID is dictated by network conditions and is highly probably in
84
+ * scenarios such as offline. This is still useful for use cases where simplicity is more important than performance and
85
+ * this approach will often be superior to generating a UUID.
86
+ * If small numbers are a requirement, `generateCompressedId` and normalization should be used instead.
87
+ * See `IIdCompressor` for more details.
88
+ * @returns A new local ID in session space.
89
+ */
90
+ generateDocumentUniqueId(): (SessionSpaceCompressedId & OpSpaceCompressedId) | StableId;
87
91
  /**
88
92
  * Normalizes a session space ID into op space.
89
- * @param id - the local ID to normalize.
90
- * @returns the ID in op space.
93
+ * The returned ID is in op space and can be safely serialized. However, it should be normalized back to session space before use.
94
+ * See `IIdCompressor` for more details.
95
+ * @param id - The local ID to normalize.
96
+ * @returns The ID in op space.
91
97
  */
92
98
  normalizeToOpSpace(id: SessionSpaceCompressedId): OpSpaceCompressedId;
93
99
  /**
94
100
  * 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
+ * @param id - The ID to normalize.
102
+ * @param originSessionId - The session from which `id` originated. This should be the ID of the client that normalized `id` to op space.
103
+ * This means that it may not be the client that created `id` in the first place, but rather the client that serialized it.
104
+ * This is an important distinction in the case of a reference, where a client might refer to an ID created by another client.
105
+ * @returns The session-space ID in the local session corresponding to `id`.
101
106
  */
102
107
  normalizeToSessionSpace(id: OpSpaceCompressedId, originSessionId: SessionId): SessionSpaceCompressedId;
103
108
  /**
104
109
  * 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.
110
+ * @param id - The compressed ID to be decompressed.
111
+ * @returns The UUID associated with the compressed ID.
112
+ * @throws If the ID was not generated by any session known to this compressor.
107
113
  */
108
114
  decompress(id: SessionSpaceCompressedId): StableId;
109
115
  /**
110
116
  * 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.
117
+ * @param uncompressed - The UUID to recompress.
118
+ * @returns The `CompressedId` associated with `uncompressed`.
119
+ * @throws If the UUID was not generated by any session known to this compressor.
113
120
  */
114
121
  recompress(uncompressed: StableId): SessionSpaceCompressedId;
115
122
  /**
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.
123
+ * Attempts to recompress a UUID.
124
+ * @param uncompressed - The UUID to recompress.
125
+ * @returns The `CompressedId` associated with `uncompressed` or undefined if the UUID was not generated by any session known to this compressor.
119
126
  */
120
127
  tryRecompress(uncompressed: StableId): SessionSpaceCompressedId | undefined;
121
128
  }
@@ -1,4 +1,5 @@
1
1
  import { ITelemetryBaseLogger } from '@fluidframework/core-interfaces';
2
+ import { ITelemetryLoggerExt } from '@fluidframework/telemetry-utils';
2
3
 
3
4
  /* Excluded from this release type: assertIsStableId */
4
5
 
@@ -10,112 +11,118 @@ import { ITelemetryBaseLogger } from '@fluidframework/core-interfaces';
10
11
 
11
12
  /* Excluded from this release type: generateStableId */
12
13
 
13
- /* Excluded from this release type: IdCompressor */
14
-
15
14
  /* Excluded from this release type: IdCreationRange */
16
15
 
17
16
  /**
18
17
  * 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.
18
+ * `IdCompressor` offers the ability to generate arbitrary non-colliding v4 UUIDs, called stable IDs, while compressing them into small integers
19
+ * for efficient storage and transmission. It also provides the ability to decompress these integers back into their original UUIDs.
20
+ *
21
+ * The compressor is designed to be used in a distributed environment, where multiple clients may be generating IDs concurrently.
22
+ * IDs generated by a compressor, via calls to `generateCompressedId`, are created in the compressor's "local" session.
23
+ * These IDs are unique within the session, but may not be unique across sessions. In the context of Fluid, the scope of a session
24
+ * is the same as the scope of a container. This means that anytime IDs are transferred between sessions, they must be translated
25
+ * through a process called "normalization":
26
+ * - The scope of a local session (in which local IDs are unique) is called the "session space" of the client.
27
+ * - The context of persisted state (in Fluid, this is the context of ops and summaries) is called "op space".
28
+ * - `SessionSpaceCompressedId`s, generated via calls to `generateCompressedId`, should NEVER be serialized directly.
29
+ * In Fluid, this means they should not be included in ops or summaries.
30
+ * - Before serialization, IDs must be normalized to op space to ensure they are interpretable by other clients.
31
+ * - Upon receipt, IDs should be normalized back to session space before use.
32
+ *
33
+ * Example Usage:
34
+ *
35
+ * ### Client A (Sender)
36
+ *
37
+ * ```typescript
38
+ * // Generate several local IDs
39
+ * const localId1 = idCompressor.generateCompressedId();
40
+ * const localId2 = idCompressor.generateCompressedId();
41
+ * const localId3 = idCompressor.generateCompressedId();
42
+ *
43
+ * // Normalize these IDs to op space for inclusion in a message
44
+ * const opSpaceId1 = idCompressor.normalizeToOpSpace(localId1);
45
+ * const opSpaceId2 = idCompressor.normalizeToOpSpace(localId2);
46
+ * const opSpaceId3 = idCompressor.normalizeToOpSpace(localId3);
47
+ *
48
+ * // Create and send a message containing these op space IDs along with the sender's session ID
49
+ * // In Fluid, this would be an op or summary
50
+ * const message = {
51
+ * sessionID: idCompressor.localSessionId,
52
+ * ids: [opSpaceId1, opSpaceId2, opSpaceId3]
53
+ * };
54
+ * ```
55
+ *
56
+ * ### Client B (Receiver)
57
+ *
58
+ * ```typescript
59
+ * // Receive the message from Client A
60
+ * const receivedMessage = ...; // In Fluid, this would be an op or summary
61
+ *
62
+ * // Normalize the received IDs back to session space, utilizing the sender's session ID
63
+ * const sessionSpaceId1 = idCompressor.normalizeToSessionSpace(receivedMessage.ids[0], receivedMessage.sessionID);
64
+ * const sessionSpaceId2 = idCompressor.normalizeToSessionSpace(receivedMessage.ids[1], receivedMessage.sessionID);
65
+ * const sessionSpaceId3 = idCompressor.normalizeToSessionSpace(receivedMessage.ids[2], receivedMessage.sessionID);
66
+ * ```
77
67
  * @public
78
68
  */
79
69
  export declare interface IIdCompressor {
70
+ /**
71
+ * The local session ID.
72
+ */
80
73
  localSessionId: SessionId;
81
74
  /**
82
- * Generates a new compressed ID or returns an existing one.
83
- * This should ONLY be called to generate IDs for local operations.
75
+ * Generates a new compressed ID.
76
+ * The returned ID is in session space and should not be serialized directly. See `IIdCompressor` for more details.
84
77
  * @returns A new local ID in session space.
85
78
  */
86
79
  generateCompressedId(): SessionSpaceCompressedId;
80
+ /**
81
+ * Generates a new ID that is guaranteed to be unique across all sessions known to this compressor without the need for any
82
+ * normalization. The returned ID is not guaranteed to be a compressed ID (small number); it may be a stable ID (UUID string).
83
+ * In Fluid, the likelihood of generating the bulkier stable ID is dictated by network conditions and is highly probably in
84
+ * scenarios such as offline. This is still useful for use cases where simplicity is more important than performance and
85
+ * this approach will often be superior to generating a UUID.
86
+ * If small numbers are a requirement, `generateCompressedId` and normalization should be used instead.
87
+ * See `IIdCompressor` for more details.
88
+ * @returns A new local ID in session space.
89
+ */
90
+ generateDocumentUniqueId(): (SessionSpaceCompressedId & OpSpaceCompressedId) | StableId;
87
91
  /**
88
92
  * Normalizes a session space ID into op space.
89
- * @param id - the local ID to normalize.
90
- * @returns the ID in op space.
93
+ * The returned ID is in op space and can be safely serialized. However, it should be normalized back to session space before use.
94
+ * See `IIdCompressor` for more details.
95
+ * @param id - The local ID to normalize.
96
+ * @returns The ID in op space.
91
97
  */
92
98
  normalizeToOpSpace(id: SessionSpaceCompressedId): OpSpaceCompressedId;
93
99
  /**
94
100
  * 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
+ * @param id - The ID to normalize.
102
+ * @param originSessionId - The session from which `id` originated. This should be the ID of the client that normalized `id` to op space.
103
+ * This means that it may not be the client that created `id` in the first place, but rather the client that serialized it.
104
+ * This is an important distinction in the case of a reference, where a client might refer to an ID created by another client.
105
+ * @returns The session-space ID in the local session corresponding to `id`.
101
106
  */
102
107
  normalizeToSessionSpace(id: OpSpaceCompressedId, originSessionId: SessionId): SessionSpaceCompressedId;
103
108
  /**
104
109
  * 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.
110
+ * @param id - The compressed ID to be decompressed.
111
+ * @returns The UUID associated with the compressed ID.
112
+ * @throws If the ID was not generated by any session known to this compressor.
107
113
  */
108
114
  decompress(id: SessionSpaceCompressedId): StableId;
109
115
  /**
110
116
  * 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.
117
+ * @param uncompressed - The UUID to recompress.
118
+ * @returns The `CompressedId` associated with `uncompressed`.
119
+ * @throws If the UUID was not generated by any session known to this compressor.
113
120
  */
114
121
  recompress(uncompressed: StableId): SessionSpaceCompressedId;
115
122
  /**
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.
123
+ * Attempts to recompress a UUID.
124
+ * @param uncompressed - The UUID to recompress.
125
+ * @returns The `CompressedId` associated with `uncompressed` or undefined if the UUID was not generated by any session known to this compressor.
119
126
  */
120
127
  tryRecompress(uncompressed: StableId): SessionSpaceCompressedId | undefined;
121
128
  }