@fluidframework/container-runtime 2.0.0-internal.6.1.2 → 2.0.0-internal.6.2.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.
- package/CHANGELOG.md +35 -0
- package/README.md +4 -3
- package/dist/batchTracker.d.ts +1 -1
- package/dist/batchTracker.js +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +4 -20
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +47 -125
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +82 -14
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +236 -138
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +1 -2
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +4 -5
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +1 -2
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.js +2 -2
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +4 -5
- package/dist/dataStores.js.map +1 -1
- package/dist/error.d.ts +14 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +21 -0
- package/dist/error.js.map +1 -0
- package/dist/gc/garbageCollection.d.ts +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +23 -5
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +5 -3
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +2 -0
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +2 -0
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/id-compressor/appendOnlySortedMap.d.ts +8 -30
- package/dist/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
- package/dist/id-compressor/appendOnlySortedMap.js +25 -67
- package/dist/id-compressor/appendOnlySortedMap.js.map +1 -1
- package/dist/id-compressor/finalSpace.d.ts +29 -0
- package/dist/id-compressor/finalSpace.d.ts.map +1 -0
- package/dist/id-compressor/finalSpace.js +62 -0
- package/dist/id-compressor/finalSpace.js.map +1 -0
- package/dist/id-compressor/idCompressor.d.ts +25 -250
- package/dist/id-compressor/idCompressor.d.ts.map +1 -1
- package/dist/id-compressor/idCompressor.js +385 -1149
- package/dist/id-compressor/idCompressor.js.map +1 -1
- package/dist/id-compressor/identifiers.d.ts +32 -0
- package/dist/id-compressor/identifiers.d.ts.map +1 -0
- package/dist/id-compressor/identifiers.js +15 -0
- package/dist/id-compressor/identifiers.js.map +1 -0
- package/dist/id-compressor/index.d.ts +5 -6
- package/dist/id-compressor/index.d.ts.map +1 -1
- package/dist/id-compressor/index.js +20 -26
- package/dist/id-compressor/index.js.map +1 -1
- package/dist/id-compressor/persistanceUtilities.d.ts +22 -0
- package/dist/id-compressor/persistanceUtilities.d.ts.map +1 -0
- package/dist/id-compressor/persistanceUtilities.js +43 -0
- package/dist/id-compressor/persistanceUtilities.js.map +1 -0
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
- package/dist/id-compressor/sessionSpaceNormalizer.js +80 -0
- package/dist/id-compressor/sessionSpaceNormalizer.js.map +1 -0
- package/dist/id-compressor/sessions.d.ts +115 -0
- package/dist/id-compressor/sessions.d.ts.map +1 -0
- package/dist/id-compressor/sessions.js +305 -0
- package/dist/id-compressor/sessions.js.map +1 -0
- package/dist/id-compressor/utilities.d.ts +49 -0
- package/dist/id-compressor/utilities.d.ts.map +1 -0
- package/dist/id-compressor/utilities.js +166 -0
- package/dist/id-compressor/utilities.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +1 -2
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +2 -3
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +1 -0
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +10 -11
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +11 -5
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +12 -5
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +24 -10
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +4 -5
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/index.d.ts +2 -2
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +2 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +1 -2
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +2 -3
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +27 -4
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +237 -66
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +6 -5
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +70 -67
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +38 -25
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +1 -2
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +9 -3
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +42 -38
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +7 -6
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +22 -15
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +1 -1
- package/lib/batchTracker.js +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +4 -20
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +46 -124
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +82 -14
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +223 -123
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +1 -2
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +1 -2
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +1 -2
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.js +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +1 -2
- package/lib/dataStores.js.map +1 -1
- package/lib/error.d.ts +14 -0
- package/lib/error.d.ts.map +1 -0
- package/lib/error.js +17 -0
- package/lib/error.js.map +1 -0
- package/lib/gc/garbageCollection.d.ts +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +22 -4
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +3 -1
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +2 -0
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +2 -0
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/id-compressor/appendOnlySortedMap.d.ts +8 -30
- package/lib/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
- package/lib/id-compressor/appendOnlySortedMap.js +24 -65
- package/lib/id-compressor/appendOnlySortedMap.js.map +1 -1
- package/lib/id-compressor/finalSpace.d.ts +29 -0
- package/lib/id-compressor/finalSpace.d.ts.map +1 -0
- package/lib/id-compressor/finalSpace.js +58 -0
- package/lib/id-compressor/finalSpace.js.map +1 -0
- package/lib/id-compressor/idCompressor.d.ts +25 -250
- package/lib/id-compressor/idCompressor.d.ts.map +1 -1
- package/lib/id-compressor/idCompressor.js +381 -1139
- package/lib/id-compressor/idCompressor.js.map +1 -1
- package/lib/id-compressor/identifiers.d.ts +32 -0
- package/lib/id-compressor/identifiers.d.ts.map +1 -0
- package/lib/id-compressor/identifiers.js +11 -0
- package/lib/id-compressor/identifiers.js.map +1 -0
- package/lib/id-compressor/index.d.ts +5 -6
- package/lib/id-compressor/index.d.ts.map +1 -1
- package/lib/id-compressor/index.js +5 -6
- package/lib/id-compressor/index.js.map +1 -1
- package/lib/id-compressor/persistanceUtilities.d.ts +22 -0
- package/lib/id-compressor/persistanceUtilities.d.ts.map +1 -0
- package/lib/id-compressor/persistanceUtilities.js +34 -0
- package/lib/id-compressor/persistanceUtilities.js.map +1 -0
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
- package/lib/id-compressor/sessionSpaceNormalizer.js +76 -0
- package/lib/id-compressor/sessionSpaceNormalizer.js.map +1 -0
- package/lib/id-compressor/sessions.d.ts +115 -0
- package/lib/id-compressor/sessions.d.ts.map +1 -0
- package/lib/id-compressor/sessions.js +290 -0
- package/lib/id-compressor/sessions.js.map +1 -0
- package/lib/id-compressor/utilities.d.ts +49 -0
- package/lib/id-compressor/utilities.d.ts.map +1 -0
- package/lib/id-compressor/utilities.js +148 -0
- package/lib/id-compressor/utilities.js.map +1 -0
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +1 -2
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +1 -2
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +1 -0
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +6 -7
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +12 -6
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +12 -5
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +21 -7
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +1 -2
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/index.d.ts +2 -2
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +1 -2
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +1 -2
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +27 -4
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +237 -66
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +6 -5
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +68 -65
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +38 -25
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +1 -2
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +9 -3
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +43 -39
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +7 -6
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +23 -16
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +26 -23
- package/src/batchTracker.ts +1 -1
- package/src/blobManager.ts +57 -146
- package/src/containerRuntime.ts +331 -158
- package/src/dataStore.ts +1 -2
- package/src/dataStoreContext.ts +3 -6
- package/src/dataStoreContexts.ts +1 -2
- package/src/dataStoreRegistry.ts +1 -1
- package/src/dataStores.ts +3 -5
- package/src/error.ts +18 -0
- package/src/gc/garbageCollection.ts +38 -5
- package/src/gc/gcConfigs.ts +4 -2
- package/src/gc/gcDefinitions.ts +2 -0
- package/src/gc/gcTelemetry.ts +2 -0
- package/src/id-compressor/appendOnlySortedMap.ts +25 -86
- package/src/id-compressor/finalSpace.ts +67 -0
- package/src/id-compressor/idCompressor.ts +455 -1681
- package/src/id-compressor/identifiers.ts +42 -0
- package/src/id-compressor/index.ts +11 -20
- package/src/id-compressor/persistanceUtilities.ts +58 -0
- package/src/id-compressor/sessionSpaceNormalizer.ts +83 -0
- package/src/id-compressor/sessions.ts +405 -0
- package/src/id-compressor/utilities.ts +187 -0
- package/src/index.ts +7 -1
- package/src/opLifecycle/opCompressor.ts +1 -2
- package/src/opLifecycle/opSplitter.ts +4 -4
- package/src/opLifecycle/outbox.ts +13 -10
- package/src/opLifecycle/remoteMessageProcessor.ts +19 -6
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +49 -27
- package/src/scheduleManager.ts +5 -4
- package/src/summary/index.ts +3 -1
- package/src/summary/orderedClientElection.ts +6 -4
- package/src/summary/runningSummarizer.ts +276 -95
- package/src/summary/summarizer.ts +22 -12
- package/src/summary/summarizerClientElection.ts +1 -1
- package/src/summary/summarizerTypes.ts +40 -25
- package/src/summary/summaryCollection.ts +1 -2
- package/src/summary/summaryGenerator.ts +49 -52
- package/src/summary/summaryManager.ts +33 -11
- package/dist/id-compressor/idRange.d.ts +0 -11
- package/dist/id-compressor/idRange.d.ts.map +0 -1
- package/dist/id-compressor/idRange.js +0 -29
- package/dist/id-compressor/idRange.js.map +0 -1
- package/dist/id-compressor/numericUuid.d.ts +0 -59
- package/dist/id-compressor/numericUuid.d.ts.map +0 -1
- package/dist/id-compressor/numericUuid.js +0 -325
- package/dist/id-compressor/numericUuid.js.map +0 -1
- package/dist/id-compressor/sessionIdNormalizer.d.ts +0 -138
- package/dist/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
- package/dist/id-compressor/sessionIdNormalizer.js +0 -483
- package/dist/id-compressor/sessionIdNormalizer.js.map +0 -1
- package/dist/id-compressor/utils.d.ts +0 -57
- package/dist/id-compressor/utils.d.ts.map +0 -1
- package/dist/id-compressor/utils.js +0 -90
- package/dist/id-compressor/utils.js.map +0 -1
- package/dist/id-compressor/uuidUtilities.d.ts +0 -28
- package/dist/id-compressor/uuidUtilities.d.ts.map +0 -1
- package/dist/id-compressor/uuidUtilities.js +0 -104
- package/dist/id-compressor/uuidUtilities.js.map +0 -1
- package/lib/id-compressor/idRange.d.ts +0 -11
- package/lib/id-compressor/idRange.d.ts.map +0 -1
- package/lib/id-compressor/idRange.js +0 -25
- package/lib/id-compressor/idRange.js.map +0 -1
- package/lib/id-compressor/numericUuid.d.ts +0 -59
- package/lib/id-compressor/numericUuid.d.ts.map +0 -1
- package/lib/id-compressor/numericUuid.js +0 -315
- package/lib/id-compressor/numericUuid.js.map +0 -1
- package/lib/id-compressor/sessionIdNormalizer.d.ts +0 -138
- package/lib/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
- package/lib/id-compressor/sessionIdNormalizer.js +0 -479
- package/lib/id-compressor/sessionIdNormalizer.js.map +0 -1
- package/lib/id-compressor/utils.d.ts +0 -57
- package/lib/id-compressor/utils.d.ts.map +0 -1
- package/lib/id-compressor/utils.js +0 -79
- package/lib/id-compressor/utils.js.map +0 -1
- package/lib/id-compressor/uuidUtilities.d.ts +0 -28
- package/lib/id-compressor/uuidUtilities.d.ts.map +0 -1
- package/lib/id-compressor/uuidUtilities.js +0 -96
- package/lib/id-compressor/uuidUtilities.js.map +0 -1
- package/src/id-compressor/idRange.ts +0 -35
- package/src/id-compressor/numericUuid.ts +0 -383
- package/src/id-compressor/sessionIdNormalizer.ts +0 -609
- package/src/id-compressor/utils.ts +0 -114
- package/src/id-compressor/uuidUtilities.ts +0 -120
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Fails true iff `array` has at least `length` elements
|
|
7
|
-
*/
|
|
8
|
-
export function hasAtLeastLength(array, length) {
|
|
9
|
-
return array.length >= length;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* A numeric comparator used for sorting in ascending order.
|
|
13
|
-
*
|
|
14
|
-
* Handles +/-0 like Map: -0 is equal to +0.
|
|
15
|
-
*/
|
|
16
|
-
export function compareFiniteNumbers(a, b) {
|
|
17
|
-
return a - b;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* A numeric comparator used for sorting in descending order.
|
|
21
|
-
*
|
|
22
|
-
* Handles +/-0 like Map: -0 is equal to +0.
|
|
23
|
-
*/
|
|
24
|
-
export function compareFiniteNumbersReversed(a, b) {
|
|
25
|
-
return b - a;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Compare two maps and return true if their contents are equivalent.
|
|
29
|
-
* @param mapA - The first array to compare
|
|
30
|
-
* @param mapB - The second array to compare
|
|
31
|
-
* @param elementComparator - The function used to check if two `T`s are equivalent.
|
|
32
|
-
* Defaults to `Object.is()` equality (a shallow compare)
|
|
33
|
-
*/
|
|
34
|
-
export function compareMaps(mapA, mapB, elementComparator = Object.is) {
|
|
35
|
-
if (mapA.size !== mapB.size) {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
for (const [keyA, valueA] of mapA) {
|
|
39
|
-
const valueB = mapB.get(keyA);
|
|
40
|
-
if (valueB === undefined || !elementComparator(valueA, valueB)) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Retrieve a value from a map with the given key, or create a new entry if the key is not in the map.
|
|
48
|
-
* @param map - The map to query/update
|
|
49
|
-
* @param key - The key to lookup in the map
|
|
50
|
-
* @param defaultValue - a function which returns a default value. This is called and used to set an initial value for the given key in the map if none exists
|
|
51
|
-
* @returns either the existing value for the given key, or the newly-created value (the result of `defaultValue`)
|
|
52
|
-
*/
|
|
53
|
-
export function getOrCreate(map, key, defaultValue) {
|
|
54
|
-
let value = map.get(key);
|
|
55
|
-
if (value === undefined) {
|
|
56
|
-
value = defaultValue(key);
|
|
57
|
-
map.set(key, value);
|
|
58
|
-
}
|
|
59
|
-
return value;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Compares strings lexically to form a strict partial ordering.
|
|
63
|
-
*/
|
|
64
|
-
export function compareStrings(a, b) {
|
|
65
|
-
return a > b ? 1 : a === b ? 0 : -1;
|
|
66
|
-
}
|
|
67
|
-
export function fail(message) {
|
|
68
|
-
throw new Error(message);
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Sets a property in such a way that it is only set on `destination` if the provided value is not undefined.
|
|
72
|
-
* This avoids having explicit undefined values under properties that would cause `Object.hasOwnProperty` to return true.
|
|
73
|
-
*/
|
|
74
|
-
export function setPropertyIfDefined(value, destination, property) {
|
|
75
|
-
if (value !== undefined) {
|
|
76
|
-
destination[property] = value;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/id-compressor/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiBH;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC/B,KAAmB,EACnB,MAAW;IAEX,OAAO,KAAK,CAAC,MAAM,IAAI,MAAM,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAmB,CAAI,EAAE,CAAI;IAChE,OAAO,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAAmB,CAAI,EAAE,CAAI;IACxE,OAAO,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAC1B,IAAuB,EACvB,IAAuB,EACvB,oBAA6C,MAAM,CAAC,EAAE;IAEtD,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE;QAC5B,OAAO,KAAK,CAAC;KACb;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;YAC/D,OAAO,KAAK,CAAC;SACb;KACD;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAO,GAAc,EAAE,GAAM,EAAE,YAA2B;IACpF,IAAI,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,IAAI,KAAK,KAAK,SAAS,EAAE;QACxB,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC1B,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;KACpB;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAmB,CAAI,EAAE,CAAI;IAC1D,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IACnC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CACnC,KAA0B,EAC1B,WAAiB,EACjB,QAAW;IAEX,IAAI,KAAK,KAAK,SAAS,EAAE;QACxB,WAAW,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;KAC9B;AACF,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Remove `readonly` from all fields.\n */\nexport type Mutable<T> = { -readonly [P in keyof T]: T[P] };\n\n/** A union type of the first `N` positive integers */\nexport type TakeWholeNumbers<N extends number, A extends never[] = []> = N extends A[\"length\"]\n\t? never\n\t: A[\"length\"] | TakeWholeNumbers<N, [never, ...A]>;\n\n/** Returns a tuple type with exactly `Length` elements of type `T` */\nexport type ArrayOfLength<T, Length extends number, A extends T[] = []> = Length extends A[\"length\"]\n\t? A\n\t: ArrayOfLength<T, Length, [T, ...A]>;\n\n/**\n * Fails true iff `array` has at least `length` elements\n */\nexport function hasAtLeastLength<T, Len extends TakeWholeNumbers<16>>(\n\tarray: readonly T[],\n\tlength: Len,\n): array is [...ArrayOfLength<T, Len>, ...T[]] {\n\treturn array.length >= length;\n}\n\n/**\n * A numeric comparator used for sorting in ascending order.\n *\n * Handles +/-0 like Map: -0 is equal to +0.\n */\nexport function compareFiniteNumbers<T extends number>(a: T, b: T): number {\n\treturn a - b;\n}\n\n/**\n * A numeric comparator used for sorting in descending order.\n *\n * Handles +/-0 like Map: -0 is equal to +0.\n */\nexport function compareFiniteNumbersReversed<T extends number>(a: T, b: T): number {\n\treturn b - a;\n}\n\n/**\n * Compare two maps and return true if their contents are equivalent.\n * @param mapA - The first array to compare\n * @param mapB - The second array to compare\n * @param elementComparator - The function used to check if two `T`s are equivalent.\n * Defaults to `Object.is()` equality (a shallow compare)\n */\nexport function compareMaps<K, V>(\n\tmapA: ReadonlyMap<K, V>,\n\tmapB: ReadonlyMap<K, V>,\n\telementComparator: (a: V, b: V) => boolean = Object.is,\n): boolean {\n\tif (mapA.size !== mapB.size) {\n\t\treturn false;\n\t}\n\n\tfor (const [keyA, valueA] of mapA) {\n\t\tconst valueB = mapB.get(keyA);\n\t\tif (valueB === undefined || !elementComparator(valueA, valueB)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Retrieve a value from a map with the given key, or create a new entry if the key is not in the map.\n * @param map - The map to query/update\n * @param key - The key to lookup in the map\n * @param defaultValue - a function which returns a default value. This is called and used to set an initial value for the given key in the map if none exists\n * @returns either the existing value for the given key, or the newly-created value (the result of `defaultValue`)\n */\nexport function getOrCreate<K, V>(map: Map<K, V>, key: K, defaultValue: (key: K) => V): V {\n\tlet value = map.get(key);\n\tif (value === undefined) {\n\t\tvalue = defaultValue(key);\n\t\tmap.set(key, value);\n\t}\n\treturn value;\n}\n\n/**\n * Compares strings lexically to form a strict partial ordering.\n */\nexport function compareStrings<T extends string>(a: T, b: T): number {\n\treturn a > b ? 1 : a === b ? 0 : -1;\n}\n\nexport function fail(message: string): never {\n\tthrow new Error(message);\n}\n\n/**\n * Sets a property in such a way that it is only set on `destination` if the provided value is not undefined.\n * This avoids having explicit undefined values under properties that would cause `Object.hasOwnProperty` to return true.\n */\nexport function setPropertyIfDefined<TDst, P extends keyof TDst>(\n\tvalue: TDst[P] | undefined,\n\tdestination: TDst,\n\tproperty: P,\n): void {\n\tif (value !== undefined) {\n\t\tdestination[property] = value;\n\t}\n}\n"]}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { StableId, UuidString } from "@fluidframework/runtime-definitions";
|
|
6
|
-
/**
|
|
7
|
-
* Asserts that the given string is a UUID
|
|
8
|
-
*/
|
|
9
|
-
export declare function assertIsUuidString(uuidString: string): UuidString;
|
|
10
|
-
/**
|
|
11
|
-
* Returns true iff the given string is a valid UUID-like string of hexadecimal characters
|
|
12
|
-
* 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
|
13
|
-
*/
|
|
14
|
-
export declare function isUuidString(str: string): str is UuidString;
|
|
15
|
-
/**
|
|
16
|
-
* Generate a random stable ID
|
|
17
|
-
*/
|
|
18
|
-
export declare function generateStableId(): StableId;
|
|
19
|
-
/**
|
|
20
|
-
* Asserts that the given string is a stable ID.
|
|
21
|
-
*/
|
|
22
|
-
export declare function assertIsStableId(stableId: string): StableId;
|
|
23
|
-
/**
|
|
24
|
-
* Returns true iff the given string is a valid Version 4, variant 2 UUID
|
|
25
|
-
* 'xxxxxxxx-xxxx-4xxx-vxxx-xxxxxxxxxxxx'
|
|
26
|
-
*/
|
|
27
|
-
export declare function isStableId(str: string): str is StableId;
|
|
28
|
-
//# sourceMappingURL=uuidUtilities.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"uuidUtilities.d.ts","sourceRoot":"","sources":["../../src/id-compressor/uuidUtilities.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAoB3E;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAGjE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,UAAU,CAqB3D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,QAAQ,CAE3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAG3D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,QAAQ,CAuCvD"}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { assert } from "@fluidframework/common-utils";
|
|
6
|
-
import { v4 } from "uuid";
|
|
7
|
-
const hexadecimalCharCodes = Array.from("09afAF").map((c) => c.charCodeAt(0));
|
|
8
|
-
function isHexadecimalCharacter(charCode) {
|
|
9
|
-
return ((charCode >= hexadecimalCharCodes[0] && charCode <= hexadecimalCharCodes[1]) ||
|
|
10
|
-
(charCode >= hexadecimalCharCodes[2] && charCode <= hexadecimalCharCodes[3]) ||
|
|
11
|
-
(charCode >= hexadecimalCharCodes[4] && charCode <= hexadecimalCharCodes[5]));
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Asserts that the given string is a UUID
|
|
15
|
-
*/
|
|
16
|
-
export function assertIsUuidString(uuidString) {
|
|
17
|
-
assert(isUuidString(uuidString), 0x4a2 /* Expected an UuidString */);
|
|
18
|
-
return uuidString;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Returns true iff the given string is a valid UUID-like string of hexadecimal characters
|
|
22
|
-
* 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
|
23
|
-
*/
|
|
24
|
-
export function isUuidString(str) {
|
|
25
|
-
for (let i = 0; i < str.length; i++) {
|
|
26
|
-
switch (i) {
|
|
27
|
-
case 8:
|
|
28
|
-
case 13:
|
|
29
|
-
case 18:
|
|
30
|
-
case 23:
|
|
31
|
-
if (str.charAt(i) !== "-") {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
break;
|
|
35
|
-
default:
|
|
36
|
-
if (!isHexadecimalCharacter(str.charCodeAt(i))) {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Generate a random stable ID
|
|
46
|
-
*/
|
|
47
|
-
export function generateStableId() {
|
|
48
|
-
return assertIsStableId(v4());
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Asserts that the given string is a stable ID.
|
|
52
|
-
*/
|
|
53
|
-
export function assertIsStableId(stableId) {
|
|
54
|
-
assert(isStableId(stableId), 0x4a3 /* Expected a StableId */);
|
|
55
|
-
return stableId;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Returns true iff the given string is a valid Version 4, variant 2 UUID
|
|
59
|
-
* 'xxxxxxxx-xxxx-4xxx-vxxx-xxxxxxxxxxxx'
|
|
60
|
-
*/
|
|
61
|
-
export function isStableId(str) {
|
|
62
|
-
if (str.length !== 36) {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
for (let i = 0; i < str.length; i++) {
|
|
66
|
-
switch (i) {
|
|
67
|
-
case 8:
|
|
68
|
-
case 13:
|
|
69
|
-
case 18:
|
|
70
|
-
case 23:
|
|
71
|
-
if (str.charAt(i) !== "-") {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
break;
|
|
75
|
-
case 14:
|
|
76
|
-
if (str.charAt(i) !== "4") {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
break;
|
|
80
|
-
case 19: {
|
|
81
|
-
const char = str.charAt(i);
|
|
82
|
-
if (char !== "8" && char !== "9" && char !== "a" && char !== "b") {
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
default:
|
|
88
|
-
if (!isHexadecimalCharacter(str.charCodeAt(i))) {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
//# sourceMappingURL=uuidUtilities.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"uuidUtilities.js","sourceRoot":"","sources":["../../src/id-compressor/uuidUtilities.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAEtD,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAE1B,MAAM,oBAAoB,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAO3E,CAAC;AAEF,SAAS,sBAAsB,CAAC,QAAgB;IAC/C,OAAO,CACN,CAAC,QAAQ,IAAI,oBAAoB,CAAC,CAAC,CAAC,IAAI,QAAQ,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC;QAC5E,CAAC,QAAQ,IAAI,oBAAoB,CAAC,CAAC,CAAC,IAAI,QAAQ,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC;QAC5E,CAAC,QAAQ,IAAI,oBAAoB,CAAC,CAAC,CAAC,IAAI,QAAQ,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAC5E,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB;IACpD,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACrE,OAAO,UAAU,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACpC,QAAQ,CAAC,EAAE;YACV,KAAK,CAAC,CAAC;YACP,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,CAAC;YACR,KAAK,EAAE;gBACN,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;oBAC1B,OAAO,KAAK,CAAC;iBACb;gBACD,MAAM;YAEP;gBACC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE;oBAC/C,OAAO,KAAK,CAAC;iBACb;gBACD,MAAM;SACP;KACD;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC/B,OAAO,gBAAgB,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAChD,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC9D,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACrC,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE;QACtB,OAAO,KAAK,CAAC;KACb;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACpC,QAAQ,CAAC,EAAE;YACV,KAAK,CAAC,CAAC;YACP,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,CAAC;YACR,KAAK,EAAE;gBACN,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;oBAC1B,OAAO,KAAK,CAAC;iBACb;gBACD,MAAM;YAEP,KAAK,EAAE;gBACN,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;oBAC1B,OAAO,KAAK,CAAC;iBACb;gBACD,MAAM;YAEP,KAAK,EAAE,CAAC,CAAC;gBACR,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC3B,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE;oBACjE,OAAO,KAAK,CAAC;iBACb;gBACD,MAAM;aACN;YAED;gBACC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE;oBAC/C,OAAO,KAAK,CAAC;iBACb;gBACD,MAAM;SACP;KACD;IAED,OAAO,IAAI,CAAC;AACb,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/common-utils\";\nimport { StableId, UuidString } from \"@fluidframework/runtime-definitions\";\nimport { v4 } from \"uuid\";\n\nconst hexadecimalCharCodes = Array.from(\"09afAF\").map((c) => c.charCodeAt(0)) as [\n\tzero: number,\n\tnine: number,\n\ta: number,\n\tf: number,\n\tA: number,\n\tF: number,\n];\n\nfunction isHexadecimalCharacter(charCode: number): boolean {\n\treturn (\n\t\t(charCode >= hexadecimalCharCodes[0] && charCode <= hexadecimalCharCodes[1]) ||\n\t\t(charCode >= hexadecimalCharCodes[2] && charCode <= hexadecimalCharCodes[3]) ||\n\t\t(charCode >= hexadecimalCharCodes[4] && charCode <= hexadecimalCharCodes[5])\n\t);\n}\n\n/**\n * Asserts that the given string is a UUID\n */\nexport function assertIsUuidString(uuidString: string): UuidString {\n\tassert(isUuidString(uuidString), 0x4a2 /* Expected an UuidString */);\n\treturn uuidString;\n}\n\n/**\n * Returns true iff the given string is a valid UUID-like string of hexadecimal characters\n * 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'\n */\nexport function isUuidString(str: string): str is UuidString {\n\tfor (let i = 0; i < str.length; i++) {\n\t\tswitch (i) {\n\t\t\tcase 8:\n\t\t\tcase 13:\n\t\t\tcase 18:\n\t\t\tcase 23:\n\t\t\t\tif (str.charAt(i) !== \"-\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tif (!isHexadecimalCharacter(str.charCodeAt(i))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Generate a random stable ID\n */\nexport function generateStableId(): StableId {\n\treturn assertIsStableId(v4());\n}\n\n/**\n * Asserts that the given string is a stable ID.\n */\nexport function assertIsStableId(stableId: string): StableId {\n\tassert(isStableId(stableId), 0x4a3 /* Expected a StableId */);\n\treturn stableId;\n}\n\n/**\n * Returns true iff the given string is a valid Version 4, variant 2 UUID\n * 'xxxxxxxx-xxxx-4xxx-vxxx-xxxxxxxxxxxx'\n */\nexport function isStableId(str: string): str is StableId {\n\tif (str.length !== 36) {\n\t\treturn false;\n\t}\n\n\tfor (let i = 0; i < str.length; i++) {\n\t\tswitch (i) {\n\t\t\tcase 8:\n\t\t\tcase 13:\n\t\t\tcase 18:\n\t\t\tcase 23:\n\t\t\t\tif (str.charAt(i) !== \"-\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 14:\n\t\t\t\tif (str.charAt(i) !== \"4\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 19: {\n\t\t\t\tconst char = str.charAt(i);\n\t\t\t\tif (char !== \"8\" && char !== \"9\" && char !== \"a\" && char !== \"b\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tif (!isHexadecimalCharacter(str.charCodeAt(i))) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn true;\n}\n"]}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { assert } from "@fluidframework/common-utils";
|
|
7
|
-
import type { IdCreationRange, UnackedLocalId } from "@fluidframework/runtime-definitions";
|
|
8
|
-
|
|
9
|
-
export function getIds(
|
|
10
|
-
range: IdCreationRange,
|
|
11
|
-
):
|
|
12
|
-
| { first: UnackedLocalId; last: UnackedLocalId; overrides?: IdCreationRange.Overrides }
|
|
13
|
-
| undefined {
|
|
14
|
-
const { ids } = range;
|
|
15
|
-
if (ids === undefined) {
|
|
16
|
-
return undefined;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
let first = ids.first;
|
|
20
|
-
let last = ids.last;
|
|
21
|
-
|
|
22
|
-
const overrides = ids as Partial<IdCreationRange.HasOverrides>;
|
|
23
|
-
if (overrides.overrides !== undefined) {
|
|
24
|
-
first ??= overrides.overrides[0][0];
|
|
25
|
-
last ??= overrides.overrides[overrides.overrides.length - 1][0];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
assert(first !== undefined && last !== undefined, 0x49b /* malformed IdCreationRange */);
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
first,
|
|
32
|
-
last,
|
|
33
|
-
overrides: overrides.overrides,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/* eslint-disable no-bitwise */
|
|
7
|
-
/* eslint-disable @typescript-eslint/no-namespace */
|
|
8
|
-
|
|
9
|
-
import { assert } from "@fluidframework/common-utils";
|
|
10
|
-
import { SessionId, StableId } from "@fluidframework/runtime-definitions";
|
|
11
|
-
import { fail } from "./utils";
|
|
12
|
-
import { generateStableId } from "./uuidUtilities";
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* A UUID (128 bit identifier) optimized for use as a 128 bit unsigned integer with fast addition and toString operations.
|
|
16
|
-
* The string entry is the upper 76 bits of the uuid and the integer entry holds the lower 52 bits:
|
|
17
|
-
*
|
|
18
|
-
* ```
|
|
19
|
-
* UUUUUUUU-UUUU-VUUU-vUUU-UUUUUUUUUUUU - the uuid
|
|
20
|
-
* SSSSSSSS-SSSS-SSSS-SSS - array[0]: string
|
|
21
|
-
* N NNNNNNNNNNNN - array[1]: integer
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* The integer keeps the common case cost of incrementing and computing deltas very low.
|
|
25
|
-
* The string optimizes toString by caching the the majority of the resulting string.
|
|
26
|
-
*/
|
|
27
|
-
export type NumericUuid = readonly [string, number] & {
|
|
28
|
-
readonly NumericUuid: "9132ea20-a811-4756-85f8-aa6da5ca90f8";
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const bitsInNumericUuidInteger = 52; // Not tunable. Do not change.
|
|
32
|
-
const nibblesInNumericUuidInteger = bitsInNumericUuidInteger / 4;
|
|
33
|
-
const stringEntryLength = 22;
|
|
34
|
-
const maxNumericUuidInteger = 2 ** bitsInNumericUuidInteger - 1;
|
|
35
|
-
const fiftyThirdBit = 2 ** 52;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Calculates the numeric delta between a and b (i.e. a - b).
|
|
39
|
-
* @param a - an uuid
|
|
40
|
-
* @param b - an other uuid
|
|
41
|
-
* @param maxDelta - the maximum integer delta (inclusive) to tolerate.
|
|
42
|
-
* @returns undefined if the delta is negative or greater than `maxDelta`
|
|
43
|
-
*/
|
|
44
|
-
export function getPositiveDelta(
|
|
45
|
-
a: NumericUuid,
|
|
46
|
-
b: NumericUuid,
|
|
47
|
-
maxDelta: number,
|
|
48
|
-
): number | undefined {
|
|
49
|
-
const [stringEntryA, lowNumberA] = a;
|
|
50
|
-
const [stringEntryB, lowNumberB] = b;
|
|
51
|
-
|
|
52
|
-
if (stringEntryA === stringEntryB) {
|
|
53
|
-
const difference = lowNumberA - lowNumberB;
|
|
54
|
-
if (difference >= 0 && difference <= maxDelta) {
|
|
55
|
-
return difference;
|
|
56
|
-
}
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const highNumberA = Number.parseInt(ChunkMath.Upper.parse(stringEntryA), 16);
|
|
61
|
-
const highNumberB = Number.parseInt(ChunkMath.Upper.parse(stringEntryB), 16);
|
|
62
|
-
|
|
63
|
-
let subtractHigh = highNumberA - highNumberB;
|
|
64
|
-
if (Math.abs(subtractHigh) > 1) {
|
|
65
|
-
// If the high bits differ by more than 1, then there is no chance that any lower bits could compensate
|
|
66
|
-
return undefined;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
let midNumberA = ChunkMath.getNumericValue(ChunkMath.Variant.parse(stringEntryA));
|
|
70
|
-
const midNumberB = ChunkMath.getNumericValue(ChunkMath.Variant.parse(stringEntryB));
|
|
71
|
-
|
|
72
|
-
let subtractLow = lowNumberA - lowNumberB;
|
|
73
|
-
if (subtractLow < 0) {
|
|
74
|
-
midNumberA -= 1;
|
|
75
|
-
subtractLow += fiftyThirdBit;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
let subtractMid = midNumberA - midNumberB;
|
|
79
|
-
if (subtractMid < 0) {
|
|
80
|
-
subtractHigh -= 1;
|
|
81
|
-
subtractMid += ChunkMath.twentyThirdBit;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (subtractHigh !== 0) {
|
|
85
|
-
// a < b, no positive delta, or
|
|
86
|
-
// a > b by much more than MAX_SAFE_INTEGER
|
|
87
|
-
return undefined;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (subtractMid > 1) {
|
|
91
|
-
return undefined;
|
|
92
|
-
} else {
|
|
93
|
-
const trueDelta = fiftyThirdBit * subtractMid + subtractLow;
|
|
94
|
-
return trueDelta > maxDelta ? undefined : trueDelta;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Pre-allocated array of strings of zeros.
|
|
99
|
-
// Used to pad hex strings up to 52 bits
|
|
100
|
-
const zeros: string[] = [];
|
|
101
|
-
for (let i = 0; i < nibblesInNumericUuidInteger; i++) {
|
|
102
|
-
zeros.push("0".repeat(i));
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function padToLengthWithZeros(str: string, count: number): string {
|
|
106
|
-
return str.length === count ? str : zeros[count - str.length] + str;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* @param offset - an optional offset to increment the returned StableId
|
|
111
|
-
* @returns the string representation of a `NumericUuid`.
|
|
112
|
-
*/
|
|
113
|
-
export function stableIdFromNumericUuid(uuid: NumericUuid, offset = 0): StableId {
|
|
114
|
-
const lowerAdd = uuid[1] + offset;
|
|
115
|
-
// Common fast-path
|
|
116
|
-
if (lowerAdd <= maxNumericUuidInteger) {
|
|
117
|
-
const lowerString = padToLengthWithZeros(
|
|
118
|
-
lowerAdd.toString(16),
|
|
119
|
-
nibblesInNumericUuidInteger,
|
|
120
|
-
);
|
|
121
|
-
return `${uuid[0] + lowerString.slice(0, 1)}-${lowerString.slice(1)}` as StableId;
|
|
122
|
-
}
|
|
123
|
-
return stableIdFromNumericUuid(incrementUuid(uuid, offset));
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* @param stableId - a minimal uuid string
|
|
128
|
-
* @returns a numeric representation of `stableId`.
|
|
129
|
-
*/
|
|
130
|
-
export function numericUuidFromStableId(stableId: StableId): NumericUuid {
|
|
131
|
-
const uuid: (string | number)[] = new Array(2);
|
|
132
|
-
uuid[0] = stableId.slice(0, stringEntryLength);
|
|
133
|
-
uuid[1] = Number.parseInt(ChunkMath.Lower.parse(stableId), 16);
|
|
134
|
-
return uuid as readonly (number | string)[] as NumericUuid;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Creates a session base ID.
|
|
139
|
-
* This method (rather than standard uuid generation methods) should be used to generate session IDs.
|
|
140
|
-
*/
|
|
141
|
-
export function createSessionId(): SessionId {
|
|
142
|
-
return ensureSessionUuid(generateStableId());
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Compares numeric uuids for equality.
|
|
147
|
-
*/
|
|
148
|
-
export function numericUuidEquals(a: NumericUuid, b: NumericUuid): boolean {
|
|
149
|
-
return a[0] === b[0] && a[1] === b[1];
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* The maximum value that can be contained in the upper string region of a numeric UUID (i.e. the string region excluding the version
|
|
154
|
-
* nibble and the variant chunk)
|
|
155
|
-
*/
|
|
156
|
-
const maxUpperNumber = 2 ** 48 - 1;
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Increments the uuid. `amount` must be a positive integer.
|
|
160
|
-
* @returns the result of incrementing the uuid by `amount`.
|
|
161
|
-
*/
|
|
162
|
-
export function incrementUuid(uuid: NumericUuid, amount: number): NumericUuid {
|
|
163
|
-
/*
|
|
164
|
-
* UUIDs incremented beyond the max UUID "ffffffff-ffff-4fff-bfff-ffffffffffff" will cause a failure.
|
|
165
|
-
* Also, some reserved bits of the v4 UUID must be treated as immutable (e.g. the version and
|
|
166
|
-
* variant bits) and thus must not be incremented.
|
|
167
|
-
*/
|
|
168
|
-
let newUuid: [string, number];
|
|
169
|
-
const result = uuid[1] + amount;
|
|
170
|
-
if (result <= maxNumericUuidInteger) {
|
|
171
|
-
// The new number still fits within the number region of a numeric UUID.
|
|
172
|
-
// Incrementing is usually done with small amounts, so this is the dominantly common case.
|
|
173
|
-
newUuid = [uuid[0], result];
|
|
174
|
-
} else {
|
|
175
|
-
// The numeric UUID's number region has overflowed. We will need to carry the overflow into the variant chunk (see `VariantChunk`).
|
|
176
|
-
/** The amount left over after filling up the rest of the uuid's number region with the increment amount */
|
|
177
|
-
const remainder = amount - (maxNumericUuidInteger - uuid[1]) - 1;
|
|
178
|
-
const stringEntry = uuid[0];
|
|
179
|
-
const [newVariantChunkString, carried] = ChunkMath.increment(stringEntry);
|
|
180
|
-
|
|
181
|
-
if (carried) {
|
|
182
|
-
// The variant chunk itself also overflowed. We'll need to carry the overflow further, into the upper string region of the UUID.
|
|
183
|
-
const upperString = ChunkMath.Upper.parse(stringEntry);
|
|
184
|
-
const upperNumber = Number.parseInt(upperString, 16);
|
|
185
|
-
assert(
|
|
186
|
-
upperNumber <= maxUpperNumber,
|
|
187
|
-
0x49c /* Unexpectedly large upper number when incrementing UUID */,
|
|
188
|
-
);
|
|
189
|
-
const newUpperNumber = upperNumber + 1;
|
|
190
|
-
if (newUpperNumber > maxUpperNumber) {
|
|
191
|
-
fail("Exceeded maximum numeric UUID");
|
|
192
|
-
} else {
|
|
193
|
-
// The variant chunk overflowed but the upper string region did not. Splice in the incremented string region.
|
|
194
|
-
const newUpperChunk = padToLengthWithZeros(newUpperNumber.toString(16), 12);
|
|
195
|
-
newUuid = [
|
|
196
|
-
`${ChunkMath.Upper.hyphenate(newUpperChunk)}-4${ChunkMath.Variant.hyphenate(
|
|
197
|
-
newVariantChunkString,
|
|
198
|
-
)}`,
|
|
199
|
-
remainder,
|
|
200
|
-
];
|
|
201
|
-
}
|
|
202
|
-
} else {
|
|
203
|
-
// The variant chunk did not overflow, so just splice it back in.
|
|
204
|
-
newUuid = [
|
|
205
|
-
`${ChunkMath.Upper.slice(stringEntry)}-4${ChunkMath.Variant.hyphenate(
|
|
206
|
-
newVariantChunkString,
|
|
207
|
-
)}`,
|
|
208
|
-
remainder,
|
|
209
|
-
];
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return newUuid as readonly [string, number] as NumericUuid;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
namespace ChunkMath {
|
|
217
|
-
/*
|
|
218
|
-
* Recall the UUID diagram from the top of this file which describes the layout of a Numeric UUID. To implement addition, we define
|
|
219
|
-
* another region called the "variant chunk" which overlaps with the "string" region. Note that it is just beneath the required v4 uuid
|
|
220
|
-
* version identifier (the 13th nibble 'V' which is always '4' in a v4 UUID) and just above the "number" region of the layout. It
|
|
221
|
-
* contains inside of it the v4 UUID variant identifier bits as well (see https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.1).
|
|
222
|
-
*
|
|
223
|
-
* UUUUUUUU-UUUU-VUUU-vUUU-UUUUUUUUUUUU - the uuid
|
|
224
|
-
* SSSSSSSS SSSS SSSS SSS - array[0]: string
|
|
225
|
-
* N NNNNNNNNNNNN - array[1]: integer
|
|
226
|
-
* VVV-VVV - the variant chunk
|
|
227
|
-
*
|
|
228
|
-
* By defining the variant chunk in this way it is simple to splice in the v4 UUID version identifier ('V') just above it and any
|
|
229
|
-
* "bit math" required due to the fact that the variant identifier bits ('v') do not fill up an entire nibble is handled within it.
|
|
230
|
-
* The variant chunk is made up of 6 nibbles. Note the "vv" which denotes the two bits used for the v4 UUID variant identifier:
|
|
231
|
-
*
|
|
232
|
-
* AAAA BBBB CCCC vvDD EEEE FFFF
|
|
233
|
-
*
|
|
234
|
-
* Since we'll be needing to "skip" the variant bits ("vv") when doing addition, we define a a few masks which will be used below to
|
|
235
|
-
* separate the variant chunk into pieces before recombining it:
|
|
236
|
-
*/
|
|
237
|
-
|
|
238
|
-
// AAAA BBBB CCCC vvDD EEEE FFFF
|
|
239
|
-
const upperVariantChunkMask = 0xfff000; // XXXX XXXX XXXX
|
|
240
|
-
const variantBitMask = 0x800; // XX
|
|
241
|
-
const middleVariantChunkMask = 0x300; // XX
|
|
242
|
-
const lowerVariantChunkMask = 0xff; // XXXX XXXX
|
|
243
|
-
|
|
244
|
-
/** The maximum numeric value that can be represented by the numerically relevant bits in the variant chunk */
|
|
245
|
-
const maxVariantNumber = 2 ** 22 - 1;
|
|
246
|
-
|
|
247
|
-
export const twentyThirdBit = 2 ** 22;
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* The upper chunk, denoted by 'U's in UUUUUUUU-UUUU-VVVV-vVVL-LLLLLLLLLLLL
|
|
251
|
-
*/
|
|
252
|
-
export namespace Upper {
|
|
253
|
-
export function parse(stringEntry: string): string {
|
|
254
|
-
return stringEntry.slice(0, 8) + stringEntry.slice(9, 13);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export function hyphenate(upperChunk: string): string {
|
|
258
|
-
return `${upperChunk.slice(0, 8)}-${upperChunk.slice(8)}`;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
export function slice(stringEntry: string): string {
|
|
262
|
-
return stringEntry.slice(0, 13);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* The variant chunk, denoted by 'V's in UUUUUUUU-UUUU-VVVV-vVVL-LLLLLLLLLLLL
|
|
268
|
-
*/
|
|
269
|
-
export namespace Variant {
|
|
270
|
-
export function parse(stringEntry: string): string {
|
|
271
|
-
return stringEntry.slice(15, 18) + stringEntry.slice(19, 22);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
export function hyphenate(variantChunk: string): string {
|
|
275
|
-
return `${variantChunk.slice(0, 3)}-${variantChunk.slice(3)}`;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* The lower chunk, denoted by 'L's in UUUUUUUU-UUUU-VVVV-vVVL-LLLLLLLLLLLL
|
|
281
|
-
*/
|
|
282
|
-
export namespace Lower {
|
|
283
|
-
export function parse(stableId: StableId): string {
|
|
284
|
-
return (
|
|
285
|
-
stableId.slice(stringEntryLength, stringEntryLength + 1) +
|
|
286
|
-
stableId.slice(stringEntryLength + 2)
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export function hyphenate(lowerChunk: string): string {
|
|
291
|
-
return `${lowerChunk.slice(0, 1)}-${lowerChunk.slice(1)}`;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Returns the number representation of the given bits corresponding to the variant chunk. The value is derived by
|
|
297
|
-
* parsing all bits except for reserved bits (i.e. the variant bits).
|
|
298
|
-
* @param variantChunk - the variantChunk
|
|
299
|
-
*/
|
|
300
|
-
export function getNumericValue(variantChunk: string): number {
|
|
301
|
-
const variantChunkBits = Number.parseInt(variantChunk, 16);
|
|
302
|
-
const upperVariantBits = (variantChunkBits & upperVariantChunkMask) >> 2;
|
|
303
|
-
const middleVariantBits = variantChunkBits & middleVariantChunkMask;
|
|
304
|
-
const lowerVariantBits = variantChunkBits & lowerVariantChunkMask;
|
|
305
|
-
return upperVariantBits + middleVariantBits + lowerVariantBits;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Given the string portion of a numeric uuid, add one to it.
|
|
310
|
-
* @returns the resulting hex string and whether or not the new value overflowed, i.e. it exceeds `maxVariantNumber`. In this case,
|
|
311
|
-
* the resulting hex string will wrap around to its minimum value '000b00'
|
|
312
|
-
*/
|
|
313
|
-
export function increment(stringEntry: string): [newVariantChunk: string, overflowed: boolean] {
|
|
314
|
-
// To implement addition, the variant identifier bits are extracted from the variant chunk, the chunk is interpreted as a number,
|
|
315
|
-
// that number is incremented by 1, and then the variant identifier bits are returned as we convert the number back into a hex
|
|
316
|
-
// string.
|
|
317
|
-
|
|
318
|
-
// This diagram may be helpful for seeing how the nibbles line up before and after the variant identifier bits are extracted. The
|
|
319
|
-
// letters used for each nibble ("AAAA", "BBBB") etc. are arbitrary and are simply there to differentiate the nibbles as they shift.
|
|
320
|
-
// --------------------------------
|
|
321
|
-
// 1. AAAA BBBB CCCC vvDD EEEE FFFF
|
|
322
|
-
// 2. AA AABB BBCC CCDD EEEE FFFF
|
|
323
|
-
// 3. AA AABB BBCC CCDD EEEE FFFF
|
|
324
|
-
// + 1
|
|
325
|
-
// = GG GGHH HHII IIJJ JJKK KKLL
|
|
326
|
-
// 4. GGGG HHHH IIII vvJJ JJKK KKLL
|
|
327
|
-
|
|
328
|
-
// 1. The variant chunk is given as a 6 character (6 nibble) hex string, where the fourth nibble contains the variant bits
|
|
329
|
-
// 2. The numerically important bits (i.e. not the variant identifier bits vv which are constant) are extracted into a single number
|
|
330
|
-
const variantChunk = Variant.parse(stringEntry);
|
|
331
|
-
const variantNumber = getNumericValue(variantChunk);
|
|
332
|
-
assert(
|
|
333
|
-
variantNumber <= maxVariantNumber,
|
|
334
|
-
0x49d /* Unexpectedly large variant number when incrementing UUID */,
|
|
335
|
-
);
|
|
336
|
-
// 3. Add one to the variant number to produce our new variant number.
|
|
337
|
-
const newVariantNumber = variantNumber + 1;
|
|
338
|
-
// 4. The variant identifier bits are added back into the number, which is then turned back into a hex string
|
|
339
|
-
const newUpperVariantBits = (newVariantNumber & (upperVariantChunkMask >> 2)) << 2;
|
|
340
|
-
const newMiddleVariantBits = (newVariantNumber & middleVariantChunkMask) | variantBitMask; // Add the variant bits back in
|
|
341
|
-
const newLowerVariantBits = newVariantNumber & lowerVariantChunkMask;
|
|
342
|
-
const newVariantChunkBits =
|
|
343
|
-
newUpperVariantBits + newMiddleVariantBits + newLowerVariantBits;
|
|
344
|
-
const newVariantChunk = padToLengthWithZeros(
|
|
345
|
-
newVariantChunkBits.toString(16),
|
|
346
|
-
variantChunk.length,
|
|
347
|
-
);
|
|
348
|
-
return [newVariantChunk, newVariantNumber > maxVariantNumber];
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
const maxUpperUuid = "ffffffff-ffff-4fff-bf";
|
|
353
|
-
const maxNibbleCount = [...maxUpperUuid].filter((n) => n === "f").length;
|
|
354
|
-
const newNibbles = ["7", "b", "d", "e"];
|
|
355
|
-
function isMaxUpperNibble(index: number): boolean {
|
|
356
|
-
return maxUpperUuid.charAt(index) === "f";
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Any session uuid with all of its highish bits set is in danger of overflowing after fewer than 2^53 increments.
|
|
361
|
-
* By zeroing one of those bits at random, potential overflow is prevented.
|
|
362
|
-
*/
|
|
363
|
-
export function ensureSessionUuid(uuid: StableId): SessionId {
|
|
364
|
-
if (uuid.startsWith(maxUpperUuid)) {
|
|
365
|
-
const targetNibble = Math.floor(Math.random() * maxNibbleCount);
|
|
366
|
-
let actualIndex = 0;
|
|
367
|
-
for (
|
|
368
|
-
let nibbleIndex = 0;
|
|
369
|
-
nibbleIndex < targetNibble && !isMaxUpperNibble(actualIndex);
|
|
370
|
-
actualIndex += 1
|
|
371
|
-
) {
|
|
372
|
-
if (isMaxUpperNibble(actualIndex)) {
|
|
373
|
-
nibbleIndex++;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const newNibble = newNibbles[Math.floor(Math.random() * newNibbles.length)]; // Randomly choose a bit to zero
|
|
378
|
-
const newUuid = uuid.slice(0, actualIndex) + newNibble + uuid.slice(actualIndex + 1);
|
|
379
|
-
return newUuid as SessionId;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return uuid as SessionId;
|
|
383
|
-
}
|