@fluidframework/id-compressor 2.117.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -2
- package/README.md +10 -10
- package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
- package/dist/appendOnlySortedMap.js +6 -5
- package/dist/appendOnlySortedMap.js.map +1 -1
- package/dist/finalSpace.js +1 -3
- package/dist/finalSpace.js.map +1 -1
- package/dist/idCompressor.js +43 -37
- package/dist/idCompressor.js.map +1 -1
- package/dist/identifiers.js +1 -2
- package/dist/identifiers.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/persistanceUtilities.js +6 -7
- package/dist/persistanceUtilities.js.map +1 -1
- package/dist/sessionSpaceNormalizer.js +3 -5
- package/dist/sessionSpaceNormalizer.js.map +1 -1
- package/dist/sessions.js +17 -15
- package/dist/sessions.js.map +1 -1
- package/dist/test/idCompressorTestUtilities.js +32 -15
- package/dist/test/idCompressorTestUtilities.js.map +1 -1
- package/dist/test/testCommon.js +7 -8
- package/dist/test/testCommon.js.map +1 -1
- package/dist/utilities.js +15 -16
- package/dist/utilities.js.map +1 -1
- package/lib/appendOnlySortedMap.js +6 -5
- package/lib/appendOnlySortedMap.js.map +1 -1
- package/lib/finalSpace.js +1 -3
- package/lib/finalSpace.js.map +1 -1
- package/lib/idCompressor.js +38 -32
- package/lib/idCompressor.js.map +1 -1
- package/lib/legacy.d.ts +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/lib/sessionSpaceNormalizer.js +3 -5
- package/lib/sessionSpaceNormalizer.js.map +1 -1
- package/lib/sessions.js +9 -7
- package/lib/sessions.js.map +1 -1
- package/lib/test/idCompressorTestUtilities.js +21 -4
- package/lib/test/idCompressorTestUtilities.js.map +1 -1
- package/package.json +33 -52
- package/src/packageVersion.ts +1 -1
- package/src/test/tsconfig.json +4 -1
- package/tsconfig.json +1 -1
- package/internal.d.ts +0 -11
- package/legacy.d.ts +0 -11
- /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
- /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,42 @@
|
|
|
1
1
|
# @fluidframework/id-compressor
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 3.0.0
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Removal of direct CommonJS support ([#28124](https://github.com/microsoft/FluidFramework/pull/28124)) [0f84e3b8878](https://github.com/microsoft/FluidFramework/commit/0f84e3b8878a5e75b2253976d98fd963bbd9db88)
|
|
8
|
+
|
|
9
|
+
Direct `require()` import is no longer directly supported.
|
|
10
|
+
Package is transpiled as ECMAScript Module.
|
|
11
|
+
|
|
12
|
+
See [Removal of direct CommonJS support in v3.0](https://github.com/microsoft/FluidFramework/issues/27444) for more information.
|
|
13
|
+
|
|
14
|
+
- Require modern TypeScript module resolution ([#27970](https://github.com/microsoft/FluidFramework/pull/27970)) [325e2016ca9](https://github.com/microsoft/FluidFramework/commit/325e2016ca9978d4a1f7552c97ba34feac9df41f)
|
|
15
|
+
|
|
16
|
+
Fluid Framework Client packages no longer include type declaration compatibility entrypoints for TypeScript's legacy Node10 resolution mode (`"moduleResolution": "node"` or `"node10"`).
|
|
17
|
+
Applications upgrading to Fluid Framework 3.0 must use one of the following supported configurations:
|
|
18
|
+
- `"module": "Node16"` with `"moduleResolution": "Node16"`
|
|
19
|
+
- `"module": "NodeNext"` with `"moduleResolution": "NodeNext"`
|
|
20
|
+
- `"module": "ESNext"` with `"moduleResolution": "Bundler"`
|
|
21
|
+
|
|
22
|
+
Existing public package entrypoints exposed through `package.json` exports, including `/alpha`, `/beta`, and `/legacy`, remain available under supported module resolution modes.
|
|
23
|
+
|
|
24
|
+
See [Removal of Node10 resolutions in v3.0](https://github.com/microsoft/FluidFramework/issues/27457) for more information.
|
|
25
|
+
|
|
26
|
+
- Client packages now target ES2022 ([#27846](https://github.com/microsoft/FluidFramework/pull/27846)) [91c78541bdd](https://github.com/microsoft/FluidFramework/commit/91c78541bddcbca5d6c5f357b023eeaee617d885)
|
|
27
|
+
|
|
28
|
+
The TypeScript compilation `target` and `lib` for the Fluid Framework client packages have been raised from ES2021/ES2020 to **ES2022**.
|
|
29
|
+
The published JavaScript now uses ES2022 language features (with correspondingly less down-leveling), so consuming these packages requires a runtime that supports ES2022.
|
|
30
|
+
All actively supported Node.js versions and evergreen browsers already meet this requirement.
|
|
31
|
+
|
|
32
|
+
Note that Fluid Framework has not officially supported targets older than ES2022 since before 2.0: this is documented in [ClientRequirements.md](https://github.com/microsoft/FluidFramework/blob/main/ClientRequirements.md) as well as the README for every client package.
|
|
33
|
+
|
|
34
|
+
It is possible this change could impact users of less up to date JavaScript runtimes.
|
|
35
|
+
Impacted users can use a tool like [babel](https://babeljs.io/) to transpile out unsupported language features.
|
|
36
|
+
|
|
37
|
+
- Build with TypeScript 6 ([#28052](https://github.com/microsoft/FluidFramework/pull/28052)) [7ab015c49de](https://github.com/microsoft/FluidFramework/commit/7ab015c49deec84833cdfe1fb5e1606b901f6e81)
|
|
38
|
+
|
|
39
|
+
FluidFramework Client SDK is now built using TypeScript 6. Consumers should build with TypeScript v6 or v7 or compatible tooling.
|
|
6
40
|
|
|
7
41
|
## 2.116.0
|
|
8
42
|
|
package/README.md
CHANGED
|
@@ -9,15 +9,15 @@ A library which generates small number representations of arbitrary non-collidin
|
|
|
9
9
|
|
|
10
10
|
## Using Fluid Framework libraries
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
library consumers should always prefer `^`.
|
|
12
|
+
For a dependency on a Fluid Framework library's public APIs, we recommend a `^` (caret) version range.
|
|
13
|
+
For example, use `^1.3.4`.
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
For a dependency on an unstable API, such as a `beta` API, we recommend a more restrictive version range.
|
|
16
|
+
For example, use a `~` version range.
|
|
17
17
|
|
|
18
18
|
## Installation
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Run this command to install the package:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
npm i @fluidframework/id-compressor
|
|
@@ -25,16 +25,16 @@ npm i @fluidframework/id-compressor
|
|
|
25
25
|
|
|
26
26
|
## Importing from this package
|
|
27
27
|
|
|
28
|
-
This package
|
|
29
|
-
For
|
|
28
|
+
This package uses [package.json exports](https://nodejs.org/api/packages.html#exports) to separate APIs by support level.
|
|
29
|
+
For information about the support guarantees, read [API Support Levels](https://fluidframework.com/docs/build/releases-and-apitags/#api-support-levels).
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
Import the `public` APIs from `@fluidframework/id-compressor`.
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
Import the `legacy` APIs from `@fluidframework/id-compressor/legacy`.
|
|
34
34
|
|
|
35
35
|
## API Documentation
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Read the **@fluidframework/id-compressor** API documentation at <https://fluidframework.com/docs/apis/id-compressor>.
|
|
38
38
|
|
|
39
39
|
<!-- prettier-ignore-end -->
|
|
40
40
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
|
3
|
-
"extends": "
|
|
3
|
+
"extends": "<projectFolder>/../../../common/build/build-common/api-extractor-model.esm.json"
|
|
4
4
|
}
|
|
@@ -12,12 +12,13 @@ const internal_1 = require("@fluidframework/core-utils/internal");
|
|
|
12
12
|
* Supports appending and searching.
|
|
13
13
|
*/
|
|
14
14
|
class AppendOnlySortedMap {
|
|
15
|
+
comparator;
|
|
16
|
+
elements = [];
|
|
15
17
|
/**
|
|
16
18
|
* @param comparator - a comparator for keys
|
|
17
19
|
*/
|
|
18
20
|
constructor(comparator) {
|
|
19
21
|
this.comparator = comparator;
|
|
20
|
-
this.elements = [];
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
24
|
* Gets the size of the map.
|
|
@@ -298,6 +299,10 @@ class AppendOnlySortedMap {
|
|
|
298
299
|
}
|
|
299
300
|
return keyIndex;
|
|
300
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* The value xor'd with the result index when a search fails.
|
|
304
|
+
*/
|
|
305
|
+
static failureXor = -1;
|
|
301
306
|
/**
|
|
302
307
|
* Performs a binary search on the sorted array.
|
|
303
308
|
* @returns the index of the key for `search`, or (if not present) the index it would have been inserted into xor'd
|
|
@@ -329,8 +334,4 @@ class AppendOnlySortedMap {
|
|
|
329
334
|
}
|
|
330
335
|
}
|
|
331
336
|
exports.AppendOnlySortedMap = AppendOnlySortedMap;
|
|
332
|
-
/**
|
|
333
|
-
* The value xor'd with the result index when a search fails.
|
|
334
|
-
*/
|
|
335
|
-
AppendOnlySortedMap.failureXor = -1;
|
|
336
337
|
//# sourceMappingURL=appendOnlySortedMap.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appendOnlySortedMap.js","sourceRoot":"","sources":["../src/appendOnlySortedMap.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable no-bitwise */\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\n/**\n * A map in which entries are always added in key-sorted order.\n * Supports appending and searching.\n */\nexport class AppendOnlySortedMap<K, V> {\n\tprotected readonly elements: (K | V)[] = [];\n\n\t/**\n\t * @param comparator - a comparator for keys\n\t */\n\tpublic constructor(protected readonly comparator: (a: K, b: K) => number) {}\n\n\t/**\n\t * Gets the size of the map.\n\t * @returns the number of entries in this map\n\t */\n\tpublic get size(): number {\n\t\treturn this.elements.length / 2;\n\t}\n\n\t/**\n\t * Gets the min key in the map.\n\t * @returns the min key in the map.\n\t */\n\tpublic minKey(): K | undefined {\n\t\treturn this.elements[0] as K | undefined;\n\t}\n\n\t/**\n\t * Gets the max key in the map.\n\t * @returns the max key in the map.\n\t */\n\tpublic maxKey(): K | undefined {\n\t\treturn this.elements[this.elements.length - 2] as K | undefined;\n\t}\n\n\t/**\n\t * Gets the min value in the map.\n\t * @returns the min value in the map.\n\t */\n\tpublic minValue(): V | undefined {\n\t\treturn this.elements[1] as V | undefined;\n\t}\n\n\t/**\n\t * Gets the max value in the map.\n\t * @returns the max value in the map.\n\t */\n\tpublic maxValue(): V | undefined {\n\t\treturn this.elements[this.elements.length - 1] as V | undefined;\n\t}\n\n\t/**\n\t * Gets the first key/value pair in the map.\n\t * @returns the first pair if it exists, or undefined otherwise.\n\t */\n\tpublic first(): [K, V] | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [elements[0] as K, elements[1] as V];\n\t}\n\n\t/**\n\t * Gets the last key/value pair in the map.\n\t * @returns the last pair if it exists, or undefined otherwise.\n\t */\n\tpublic last(): [K, V] | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst lastKeyIndex = length - 2;\n\t\treturn [elements[lastKeyIndex] as K, elements[lastKeyIndex + 1] as V];\n\t}\n\n\t/**\n\t * Gets the entry at the specified index.\n\t * @param index - the entry index\n\t * @returns the key/value pair if it exists, or undefined otherwise.\n\t */\n\tpublic getAtIndex(index: number): [K, V] | undefined {\n\t\tconst realIndex = index * 2;\n\t\tconst { elements } = this;\n\t\tif (realIndex < 0 || realIndex > elements.length - 1) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [elements[realIndex] as K, elements[realIndex + 1] as V];\n\t}\n\n\t/**\n\t * Gets the entries in the map.\n\t * @returns an iterable of the entries in the map.\n\t */\n\tpublic *entries(): IterableIterator<readonly [K, V]> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield [elements[i] as K, elements[i + 1] as V];\n\t\t}\n\t}\n\n\t/**\n\t * Gets the keys in the map.\n\t * @returns an iterable of the keys in the map.\n\t */\n\tpublic *keys(): IterableIterator<K> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield elements[i] as K;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the values in the map.\n\t * @returns an iterable of the values in the map.\n\t */\n\tpublic *values(): IterableIterator<V> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield elements[i + 1] as V;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the entries in the map, reversed.\n\t * @returns an iterable of the entries in the map, reversed.\n\t */\n\tpublic *entriesReversed(): IterableIterator<readonly [K, V]> {\n\t\tconst { elements } = this;\n\t\tfor (let i = elements.length - 2; i >= 0; i -= 2) {\n\t\t\tyield [elements[i] as K, elements[i + 1] as V];\n\t\t}\n\t}\n\n\t/**\n\t * Appends a new key/value pair at the end of the map. `key` must be greater than all other keys in the map.\n\t * @param key - the key to add\n\t * @param value - the value to add\n\t */\n\tpublic append(key: K, value: V): void {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length !== 0 && this.comparator(key, this.maxKey() as K) <= 0) {\n\t\t\tthrow new Error(\"Inserted key must be > all others in the map.\");\n\t\t}\n\t\telements.push(key, value);\n\t}\n\n\t/**\n\t * Replaces the last key/value pair with a new one. If the map is empty, the new pair is appended.\n\t * 'key' must be greater than all other keys in the map.\n\t * @param key - the key to set\n\t * @param value - the value to set\n\t */\n\tpublic replaceLast(key: K, value: V): void {\n\t\tconst { elements, comparator } = this;\n\t\tconst { length } = elements;\n\t\tif (length !== 0) {\n\t\t\telements.pop();\n\t\t\telements.pop();\n\t\t\tif (comparator(key, this.maxKey() as K) <= 0) {\n\t\t\t\tthrow new Error(\"Inserted key must be > all others in the map.\");\n\t\t\t}\n\t\t}\n\t\telements.push(key, value);\n\t}\n\n\t/**\n\t * Gets the value associated with a given key.\n\t * @param key - the key to lookup\n\t * @returns the value if it exists, or undefined otherwise.\n\t */\n\tpublic get(key: K): V | undefined {\n\t\tconst index = AppendOnlySortedMap.keyIndexOf(this.elements, key, this.comparator);\n\t\tif (index < 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.elements[index + 1] as V;\n\t}\n\n\t/**\n\t * Gets the pair associated with the given key or the next smaller key.\n\t * @param key - the key to lookup\n\t * @returns the pair if it exists, or undefined otherwise.\n\t */\n\tpublic getPairOrNextLower(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextLowerBy(key, this.comparator);\n\t}\n\n\t/**\n\t * Gets the pair associated with the given key or the next higher key.\n\t * @param key - the key to lookup.\n\t * @returns the entry associated with `key` if such an entry exists, the entry associated with the next higher key if such an entry\n\t * exists, and undefined otherwise.\n\t */\n\tpublic getPairOrNextHigher(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextHigherBy(key, this.comparator);\n\t}\n\n\t/**\n\t * Compares two `AppendOnlySortedMap`s.\n\t */\n\tpublic equals(\n\t\tother: AppendOnlySortedMap<K, V>,\n\t\tcompareValues: (a: V, b: V) => boolean,\n\t): boolean {\n\t\tif (other === this) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (this.elements.length !== other.elements.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (let i = this.elements.length - 2; i >= 0; i -= 2) {\n\t\t\tconst keyThis = this.elements[i] as K;\n\t\t\tconst valueThis = this.elements[i + 1] as V;\n\t\t\tconst keyOther = other.elements[i] as K;\n\t\t\tconst valueOther = other.elements[i + 1] as V;\n\t\t\tif (this.comparator(keyThis, keyOther) !== 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!compareValues(valueThis, valueOther)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Test-only expensive assertions to check the internal validity of the data structure.\n\t */\n\tpublic assertValid(): void {\n\t\tlet prev: readonly [K, unknown] | undefined;\n\t\tfor (const kv of this.entries()) {\n\t\t\tif (prev !== undefined) {\n\t\t\t\tassert(this.comparator(kv[0], prev[0]) > 0, 0x752 /* Keys in map must be sorted. */);\n\t\t\t}\n\t\t\tprev = kv;\n\t\t}\n\t}\n\n\t/**\n\t * Queries a range of entries.\n\t * @param from - the key to start the range query at, inclusive.\n\t * @param to - the key to end the range query at, inclusive.\n\t * @returns the range of entries.\n\t */\n\tpublic *getRange(from: K, to: K): IterableIterator<readonly [K, V]> {\n\t\tconst keyIndexFrom = this.getKeyIndexOfOrNextHigher(from, this.comparator);\n\t\tif (keyIndexFrom === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst keyIndexTo = this.getKeyIndexOfOrNextLower(to, this.comparator);\n\t\tif (keyIndexTo === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = keyIndexFrom; i <= keyIndexTo; i += 2) {\n\t\t\tyield [this.elements[i] as K, this.elements[i + 1] as V];\n\t\t}\n\t}\n\n\tprotected getPairOrNextLowerBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): readonly [K, V] | undefined {\n\t\tconst keyIndex = this.getKeyIndexOfOrNextLower(search, comparator);\n\t\tif (keyIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn [this.elements[keyIndex] as K, this.elements[keyIndex + 1] as V];\n\t}\n\n\tprivate getKeyIndexOfOrNextLower<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number | undefined {\n\t\tconst { elements } = this;\n\t\tif (elements.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);\n\t\tif (keyIndex < 0) {\n\t\t\tkeyIndex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (keyIndex > 0) {\n\t\t\t\treturn keyIndex - 2;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn keyIndex;\n\t}\n\n\t/**\n\t * Gets the pair associated with the given key or next higher key.\n\t * @param search - the search value\n\t * @param comparator - a comparison function\n\t * @returns the pair if it exists, or undefined otherwise.\n\t */\n\tprotected getPairOrNextHigherBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): readonly [K, V] | undefined {\n\t\tconst keyIndex = this.getKeyIndexOfOrNextHigher(search, comparator);\n\t\tif (keyIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn [this.elements[keyIndex] as K, this.elements[keyIndex + 1] as V];\n\t}\n\n\tprivate getKeyIndexOfOrNextHigher<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);\n\t\tif (keyIndex < 0) {\n\t\t\tkeyIndex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (keyIndex < length) {\n\t\t\t\treturn keyIndex;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn keyIndex;\n\t}\n\n\t/**\n\t * The value xor'd with the result index when a search fails.\n\t */\n\tpublic static readonly failureXor = -1;\n\n\t/**\n\t * Performs a binary search on the sorted array.\n\t * @returns the index of the key for `search`, or (if not present) the index it would have been inserted into xor'd\n\t * with `failureXor`. Note that negating is not an adequate solution as that could result in -0.\n\t */\n\tpublic static keyIndexOf<T, K, V>(\n\t\telements: readonly (K | V)[],\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number {\n\t\t// Low, high, and mid are addresses of [K,V] pairs and *not* key indices\n\t\tlet low = 0;\n\t\tlet high = elements.length / 2;\n\t\tlet mid = high >> 1;\n\t\twhile (low < high) {\n\t\t\tconst keyIndex = mid * 2;\n\t\t\tconst c = comparator(search, elements[keyIndex] as K, elements[keyIndex + 1] as V);\n\t\t\tif (c > 0) {\n\t\t\t\tlow = mid + 1;\n\t\t\t} else if (c < 0) {\n\t\t\t\thigh = mid;\n\t\t\t} else if (c === 0) {\n\t\t\t\treturn keyIndex;\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid comparator.\");\n\t\t\t}\n\t\t\tmid = (low + high) >> 1;\n\t\t}\n\t\treturn (mid * 2) ^ AppendOnlySortedMap.failureXor;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"appendOnlySortedMap.js","sourceRoot":"","sources":["../src/appendOnlySortedMap.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable no-bitwise */\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\n/**\n * A map in which entries are always added in key-sorted order.\n * Supports appending and searching.\n */\nexport class AppendOnlySortedMap<K, V> {\n\tprotected readonly elements: (K | V)[] = [];\n\n\t/**\n\t * @param comparator - a comparator for keys\n\t */\n\tpublic constructor(protected readonly comparator: (a: K, b: K) => number) {}\n\n\t/**\n\t * Gets the size of the map.\n\t * @returns the number of entries in this map\n\t */\n\tpublic get size(): number {\n\t\treturn this.elements.length / 2;\n\t}\n\n\t/**\n\t * Gets the min key in the map.\n\t * @returns the min key in the map.\n\t */\n\tpublic minKey(): K | undefined {\n\t\treturn this.elements[0] as K | undefined;\n\t}\n\n\t/**\n\t * Gets the max key in the map.\n\t * @returns the max key in the map.\n\t */\n\tpublic maxKey(): K | undefined {\n\t\treturn this.elements[this.elements.length - 2] as K | undefined;\n\t}\n\n\t/**\n\t * Gets the min value in the map.\n\t * @returns the min value in the map.\n\t */\n\tpublic minValue(): V | undefined {\n\t\treturn this.elements[1] as V | undefined;\n\t}\n\n\t/**\n\t * Gets the max value in the map.\n\t * @returns the max value in the map.\n\t */\n\tpublic maxValue(): V | undefined {\n\t\treturn this.elements[this.elements.length - 1] as V | undefined;\n\t}\n\n\t/**\n\t * Gets the first key/value pair in the map.\n\t * @returns the first pair if it exists, or undefined otherwise.\n\t */\n\tpublic first(): [K, V] | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [elements[0] as K, elements[1] as V];\n\t}\n\n\t/**\n\t * Gets the last key/value pair in the map.\n\t * @returns the last pair if it exists, or undefined otherwise.\n\t */\n\tpublic last(): [K, V] | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst lastKeyIndex = length - 2;\n\t\treturn [elements[lastKeyIndex] as K, elements[lastKeyIndex + 1] as V];\n\t}\n\n\t/**\n\t * Gets the entry at the specified index.\n\t * @param index - the entry index\n\t * @returns the key/value pair if it exists, or undefined otherwise.\n\t */\n\tpublic getAtIndex(index: number): [K, V] | undefined {\n\t\tconst realIndex = index * 2;\n\t\tconst { elements } = this;\n\t\tif (realIndex < 0 || realIndex > elements.length - 1) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [elements[realIndex] as K, elements[realIndex + 1] as V];\n\t}\n\n\t/**\n\t * Gets the entries in the map.\n\t * @returns an iterable of the entries in the map.\n\t */\n\tpublic *entries(): IterableIterator<readonly [K, V]> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield [elements[i] as K, elements[i + 1] as V];\n\t\t}\n\t}\n\n\t/**\n\t * Gets the keys in the map.\n\t * @returns an iterable of the keys in the map.\n\t */\n\tpublic *keys(): IterableIterator<K> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield elements[i] as K;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the values in the map.\n\t * @returns an iterable of the values in the map.\n\t */\n\tpublic *values(): IterableIterator<V> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield elements[i + 1] as V;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the entries in the map, reversed.\n\t * @returns an iterable of the entries in the map, reversed.\n\t */\n\tpublic *entriesReversed(): IterableIterator<readonly [K, V]> {\n\t\tconst { elements } = this;\n\t\tfor (let i = elements.length - 2; i >= 0; i -= 2) {\n\t\t\tyield [elements[i] as K, elements[i + 1] as V];\n\t\t}\n\t}\n\n\t/**\n\t * Appends a new key/value pair at the end of the map. `key` must be greater than all other keys in the map.\n\t * @param key - the key to add\n\t * @param value - the value to add\n\t */\n\tpublic append(key: K, value: V): void {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length !== 0 && this.comparator(key, this.maxKey() as K) <= 0) {\n\t\t\tthrow new Error(\"Inserted key must be > all others in the map.\");\n\t\t}\n\t\telements.push(key, value);\n\t}\n\n\t/**\n\t * Replaces the last key/value pair with a new one. If the map is empty, the new pair is appended.\n\t * 'key' must be greater than all other keys in the map.\n\t * @param key - the key to set\n\t * @param value - the value to set\n\t */\n\tpublic replaceLast(key: K, value: V): void {\n\t\tconst { elements, comparator } = this;\n\t\tconst { length } = elements;\n\t\tif (length !== 0) {\n\t\t\telements.pop();\n\t\t\telements.pop();\n\t\t\tif (comparator(key, this.maxKey() as K) <= 0) {\n\t\t\t\tthrow new Error(\"Inserted key must be > all others in the map.\");\n\t\t\t}\n\t\t}\n\t\telements.push(key, value);\n\t}\n\n\t/**\n\t * Gets the value associated with a given key.\n\t * @param key - the key to lookup\n\t * @returns the value if it exists, or undefined otherwise.\n\t */\n\tpublic get(key: K): V | undefined {\n\t\tconst index = AppendOnlySortedMap.keyIndexOf(this.elements, key, this.comparator);\n\t\tif (index < 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.elements[index + 1] as V;\n\t}\n\n\t/**\n\t * Gets the pair associated with the given key or the next smaller key.\n\t * @param key - the key to lookup\n\t * @returns the pair if it exists, or undefined otherwise.\n\t */\n\tpublic getPairOrNextLower(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextLowerBy(key, this.comparator);\n\t}\n\n\t/**\n\t * Gets the pair associated with the given key or the next higher key.\n\t * @param key - the key to lookup.\n\t * @returns the entry associated with `key` if such an entry exists, the entry associated with the next higher key if such an entry\n\t * exists, and undefined otherwise.\n\t */\n\tpublic getPairOrNextHigher(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextHigherBy(key, this.comparator);\n\t}\n\n\t/**\n\t * Compares two `AppendOnlySortedMap`s.\n\t */\n\tpublic equals(\n\t\tother: AppendOnlySortedMap<K, V>,\n\t\tcompareValues: (a: V, b: V) => boolean,\n\t): boolean {\n\t\tif (other === this) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (this.elements.length !== other.elements.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (let i = this.elements.length - 2; i >= 0; i -= 2) {\n\t\t\tconst keyThis = this.elements[i] as K;\n\t\t\tconst valueThis = this.elements[i + 1] as V;\n\t\t\tconst keyOther = other.elements[i] as K;\n\t\t\tconst valueOther = other.elements[i + 1] as V;\n\t\t\tif (this.comparator(keyThis, keyOther) !== 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!compareValues(valueThis, valueOther)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Test-only expensive assertions to check the internal validity of the data structure.\n\t */\n\tpublic assertValid(): void {\n\t\tlet prev: readonly [K, unknown] | undefined;\n\t\tfor (const kv of this.entries()) {\n\t\t\tif (prev !== undefined) {\n\t\t\t\tassert(this.comparator(kv[0], prev[0]) > 0, 0x752 /* Keys in map must be sorted. */);\n\t\t\t}\n\t\t\tprev = kv;\n\t\t}\n\t}\n\n\t/**\n\t * Queries a range of entries.\n\t * @param from - the key to start the range query at, inclusive.\n\t * @param to - the key to end the range query at, inclusive.\n\t * @returns the range of entries.\n\t */\n\tpublic *getRange(from: K, to: K): IterableIterator<readonly [K, V]> {\n\t\tconst keyIndexFrom = this.getKeyIndexOfOrNextHigher(from, this.comparator);\n\t\tif (keyIndexFrom === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst keyIndexTo = this.getKeyIndexOfOrNextLower(to, this.comparator);\n\t\tif (keyIndexTo === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = keyIndexFrom; i <= keyIndexTo; i += 2) {\n\t\t\tyield [this.elements[i] as K, this.elements[i + 1] as V];\n\t\t}\n\t}\n\n\tprotected getPairOrNextLowerBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): readonly [K, V] | undefined {\n\t\tconst keyIndex = this.getKeyIndexOfOrNextLower(search, comparator);\n\t\tif (keyIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn [this.elements[keyIndex] as K, this.elements[keyIndex + 1] as V];\n\t}\n\n\tprivate getKeyIndexOfOrNextLower<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number | undefined {\n\t\tconst { elements } = this;\n\t\tif (elements.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);\n\t\tif (keyIndex < 0) {\n\t\t\tkeyIndex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (keyIndex > 0) {\n\t\t\t\treturn keyIndex - 2;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn keyIndex;\n\t}\n\n\t/**\n\t * Gets the pair associated with the given key or next higher key.\n\t * @param search - the search value\n\t * @param comparator - a comparison function\n\t * @returns the pair if it exists, or undefined otherwise.\n\t */\n\tprotected getPairOrNextHigherBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): readonly [K, V] | undefined {\n\t\tconst keyIndex = this.getKeyIndexOfOrNextHigher(search, comparator);\n\t\tif (keyIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn [this.elements[keyIndex] as K, this.elements[keyIndex + 1] as V];\n\t}\n\n\tprivate getKeyIndexOfOrNextHigher<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);\n\t\tif (keyIndex < 0) {\n\t\t\tkeyIndex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (keyIndex < length) {\n\t\t\t\treturn keyIndex;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn keyIndex;\n\t}\n\n\t/**\n\t * The value xor'd with the result index when a search fails.\n\t */\n\tpublic static readonly failureXor = -1;\n\n\t/**\n\t * Performs a binary search on the sorted array.\n\t * @returns the index of the key for `search`, or (if not present) the index it would have been inserted into xor'd\n\t * with `failureXor`. Note that negating is not an adequate solution as that could result in -0.\n\t */\n\tpublic static keyIndexOf<T, K, V>(\n\t\telements: readonly (K | V)[],\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number {\n\t\t// Low, high, and mid are addresses of [K,V] pairs and *not* key indices\n\t\tlet low = 0;\n\t\tlet high = elements.length / 2;\n\t\tlet mid = high >> 1;\n\t\twhile (low < high) {\n\t\t\tconst keyIndex = mid * 2;\n\t\t\tconst c = comparator(search, elements[keyIndex] as K, elements[keyIndex + 1] as V);\n\t\t\tif (c > 0) {\n\t\t\t\tlow = mid + 1;\n\t\t\t} else if (c < 0) {\n\t\t\t\thigh = mid;\n\t\t\t} else if (c === 0) {\n\t\t\t\treturn keyIndex;\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid comparator.\");\n\t\t\t}\n\t\t\tmid = (low + high) >> 1;\n\t\t}\n\t\treturn (mid * 2) ^ AppendOnlySortedMap.failureXor;\n\t}\n}\n"]}
|
package/dist/finalSpace.js
CHANGED
|
@@ -13,9 +13,7 @@ const sessions_js_1 = require("./sessions.js");
|
|
|
13
13
|
* ID will always be one greater than the last final ID in the previous cluster (or 0 if there is not one).
|
|
14
14
|
*/
|
|
15
15
|
class FinalSpace {
|
|
16
|
-
|
|
17
|
-
this.clusterList = [];
|
|
18
|
-
}
|
|
16
|
+
clusterList = [];
|
|
19
17
|
get clusters() {
|
|
20
18
|
return this.clusterList;
|
|
21
19
|
}
|
package/dist/finalSpace.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finalSpace.js","sourceRoot":"","sources":["../src/finalSpace.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAG7D,+CAKuB;AAEvB;;;;GAIG;AACH,MAAa,UAAU;
|
|
1
|
+
{"version":3,"file":"finalSpace.js","sourceRoot":"","sources":["../src/finalSpace.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA6D;AAG7D,+CAKuB;AAEvB;;;;GAIG;AACH,MAAa,UAAU;IACL,WAAW,GAAgB,EAAE,CAAC;IAE/C,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAEM,cAAc;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC;IAEM,UAAU,CAAC,UAAqB;QACtC,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,IAAA,iBAAM,EACL,WAAW,KAAK,SAAS;YACxB,UAAU,CAAC,WAAW,KAAK,WAAW,CAAC,WAAW,GAAG,WAAW,CAAC,QAAQ,EAC1E,KAAK,CAAC,oDAAoD,CAC1D,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAED;;;OAGG;IACI,mBAAmB;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,OAAO,WAAW,KAAK,SAAS;YAC/B,CAAC,CAAE,CAAuB;YAC1B,CAAC,CAAE,CAAE,IAAA,gCAAkB,EAAC,WAAW,CAAY,GAAG,CAAC,CAAuB,CAAC;IAC7E,CAAC;IAED;;;OAGG;IACI,mBAAmB;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,OAAO,WAAW,KAAK,SAAS;YAC/B,CAAC,CAAE,CAAuB;YAC1B,CAAC,CAAE,CAAE,IAAA,gCAAkB,EAAC,WAAW,CAAY,GAAG,CAAC,CAAuB,CAAC;IAC7E,CAAC;IAEM,MAAM,CAAC,KAAiB;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClD,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAc,CAAC;YACjD,IAAI,CAAC,IAAA,2BAAa,EAAC,OAAO,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAc,CAAC,EAAE,CAAC;gBAChE,OAAO,KAAK,CAAC;YACd,CAAC;QACF,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;IAC7D,CAAC;CACD;AArDD,gCAqDC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport type { FinalCompressedId } from \"./identifiers.js\";\nimport {\n\ttype IdCluster,\n\tclustersEqual,\n\tlastAllocatedFinal,\n\tlastFinalizedFinal,\n} from \"./sessions.js\";\n\n/**\n * All IDs that have been finalized (acked), grouped into clusters sorted by their base final IDs.\n * These clusters span the positive integer space and are not sparse, meaning a cluster's base final\n * ID will always be one greater than the last final ID in the previous cluster (or 0 if there is not one).\n */\nexport class FinalSpace {\n\tprivate readonly clusterList: IdCluster[] = [];\n\n\tpublic get clusters(): readonly IdCluster[] {\n\t\treturn this.clusterList;\n\t}\n\n\tpublic getLastCluster(): IdCluster | undefined {\n\t\treturn this.clusterList[this.clusterList.length - 1];\n\t}\n\n\tpublic addCluster(newCluster: IdCluster): void {\n\t\tconst lastCluster = this.getLastCluster();\n\t\tassert(\n\t\t\tlastCluster === undefined ||\n\t\t\t\tnewCluster.baseFinalId === lastCluster.baseFinalId + lastCluster.capacity,\n\t\t\t0x753 /* Cluster insert to final_space is out of order. */,\n\t\t);\n\t\tthis.clusterList.push(newCluster);\n\t}\n\n\t/**\n\t * Gets the upper bound (exclusive) of finalized IDs in final space, i.e. one greater than the last final ID in the last cluster.\n\t * Note: this does not include allocated but unfinalized space in clusters.\n\t */\n\tpublic getFinalizedIdLimit(): FinalCompressedId {\n\t\tconst lastCluster = this.getLastCluster();\n\t\treturn lastCluster === undefined\n\t\t\t? (0 as FinalCompressedId)\n\t\t\t: (((lastFinalizedFinal(lastCluster) as number) + 1) as FinalCompressedId);\n\t}\n\n\t/**\n\t * Gets the upper bound (exclusive) of allocated IDs in final space, i.e. one greater than the last final ID in the last cluster.\n\t * Note: this does includes all allocated IDs in clusters.\n\t */\n\tpublic getAllocatedIdLimit(): FinalCompressedId {\n\t\tconst lastCluster = this.getLastCluster();\n\t\treturn lastCluster === undefined\n\t\t\t? (0 as FinalCompressedId)\n\t\t\t: (((lastAllocatedFinal(lastCluster) as number) + 1) as FinalCompressedId);\n\t}\n\n\tpublic equals(other: FinalSpace): boolean {\n\t\tfor (let i = 0; i < this.clusterList.length; i++) {\n\t\t\tconst cluster = this.clusterList[i] as IdCluster;\n\t\t\tif (!clustersEqual(cluster, other.clusterList[i] as IdCluster)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn this.clusterList.length === other.clusterList.length;\n\t}\n}\n"]}
|
package/dist/idCompressor.js
CHANGED
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.IdCompressor = void 0;
|
|
8
|
+
exports.createIdCompressor = createIdCompressor;
|
|
9
|
+
exports.deserializeIdCompressor = deserializeIdCompressor;
|
|
10
|
+
exports.serializeIdCompressor = serializeIdCompressor;
|
|
11
|
+
exports.toIdCompressorWithCore = toIdCompressorWithCore;
|
|
8
12
|
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
13
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
10
14
|
const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
@@ -29,37 +33,47 @@ function rangeFinalizationError(expectedStart, actualStart) {
|
|
|
29
33
|
* See {@link IIdCompressor} and {@link IIdCompressorCore}
|
|
30
34
|
*/
|
|
31
35
|
class IdCompressor {
|
|
36
|
+
logger;
|
|
37
|
+
/**
|
|
38
|
+
* Max allowed initial cluster size.
|
|
39
|
+
*/
|
|
40
|
+
static maxClusterSize = 2 ** 20;
|
|
41
|
+
// #region Local state
|
|
42
|
+
localSessionId;
|
|
43
|
+
localSession;
|
|
44
|
+
normalizer = new sessionSpaceNormalizer_js_1.SessionSpaceNormalizer();
|
|
45
|
+
// The number of IDs generated by the local session
|
|
46
|
+
localGenCount = 0;
|
|
47
|
+
// #endregion
|
|
48
|
+
// #region Final state
|
|
49
|
+
/**
|
|
50
|
+
* The gen count to be annotated on the range returned by the next call to `takeNextCreationRange`.
|
|
51
|
+
* This is advanced to `generatedIdCount` + 1 each time it is called.
|
|
52
|
+
* On the other hand, when `resetUnfinalizedCreationRange` is called,
|
|
53
|
+
* this is moved back to the start of the unfinalized range, to ensure those IDs are included in the next range.
|
|
54
|
+
*/
|
|
55
|
+
nextRangeBaseGenCount = 1;
|
|
56
|
+
sessions = new sessions_js_1.Sessions();
|
|
57
|
+
finalSpace = new finalSpace_js_1.FinalSpace();
|
|
58
|
+
// #endregion
|
|
59
|
+
// #region Ephemeral state
|
|
60
|
+
/**
|
|
61
|
+
* Roughly equates to a minimum of 1M sessions before we start allocating 64 bit IDs.
|
|
62
|
+
* Eventually, this can be adjusted dynamically to have cluster reservation policies that
|
|
63
|
+
* optimize the number of eager finals.
|
|
64
|
+
* It is not readonly as it is accessed by tests for clear-box testing.
|
|
65
|
+
*/
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly
|
|
67
|
+
nextRequestedClusterSize = 512;
|
|
68
|
+
// The number of local IDs generated since the last telemetry was sent.
|
|
69
|
+
telemetryLocalIdCount = 0;
|
|
70
|
+
// The number of eager final IDs generated since the last telemetry was sent.
|
|
71
|
+
telemetryEagerFinalIdCount = 0;
|
|
72
|
+
// The ongoing ghost session, if one exists.
|
|
73
|
+
ongoingGhostSession;
|
|
32
74
|
// #endregion
|
|
33
75
|
constructor(localSessionIdOrDeserialized, logger) {
|
|
34
76
|
this.logger = logger;
|
|
35
|
-
this.normalizer = new sessionSpaceNormalizer_js_1.SessionSpaceNormalizer();
|
|
36
|
-
// The number of IDs generated by the local session
|
|
37
|
-
this.localGenCount = 0;
|
|
38
|
-
// #endregion
|
|
39
|
-
// #region Final state
|
|
40
|
-
/**
|
|
41
|
-
* The gen count to be annotated on the range returned by the next call to `takeNextCreationRange`.
|
|
42
|
-
* This is advanced to `generatedIdCount` + 1 each time it is called.
|
|
43
|
-
* On the other hand, when `resetUnfinalizedCreationRange` is called,
|
|
44
|
-
* this is moved back to the start of the unfinalized range, to ensure those IDs are included in the next range.
|
|
45
|
-
*/
|
|
46
|
-
this.nextRangeBaseGenCount = 1;
|
|
47
|
-
this.sessions = new sessions_js_1.Sessions();
|
|
48
|
-
this.finalSpace = new finalSpace_js_1.FinalSpace();
|
|
49
|
-
// #endregion
|
|
50
|
-
// #region Ephemeral state
|
|
51
|
-
/**
|
|
52
|
-
* Roughly equates to a minimum of 1M sessions before we start allocating 64 bit IDs.
|
|
53
|
-
* Eventually, this can be adjusted dynamically to have cluster reservation policies that
|
|
54
|
-
* optimize the number of eager finals.
|
|
55
|
-
* It is not readonly as it is accessed by tests for clear-box testing.
|
|
56
|
-
*/
|
|
57
|
-
// eslint-disable-next-line @typescript-eslint/prefer-readonly
|
|
58
|
-
this.nextRequestedClusterSize = 512;
|
|
59
|
-
// The number of local IDs generated since the last telemetry was sent.
|
|
60
|
-
this.telemetryLocalIdCount = 0;
|
|
61
|
-
// The number of eager final IDs generated since the last telemetry was sent.
|
|
62
|
-
this.telemetryEagerFinalIdCount = 0;
|
|
63
77
|
if (typeof localSessionIdOrDeserialized === "string") {
|
|
64
78
|
this.localSessionId = localSessionIdOrDeserialized;
|
|
65
79
|
this.localSession = this.sessions.getOrCreate(localSessionIdOrDeserialized);
|
|
@@ -558,10 +572,6 @@ class IdCompressor {
|
|
|
558
572
|
}
|
|
559
573
|
}
|
|
560
574
|
exports.IdCompressor = IdCompressor;
|
|
561
|
-
/**
|
|
562
|
-
* Max allowed initial cluster size.
|
|
563
|
-
*/
|
|
564
|
-
IdCompressor.maxClusterSize = 2 ** 20;
|
|
565
575
|
function createIdCompressor(sessionIdOrLogger, loggerOrUndefined) {
|
|
566
576
|
let localSessionId;
|
|
567
577
|
let logger;
|
|
@@ -581,7 +591,6 @@ function createIdCompressor(sessionIdOrLogger, loggerOrUndefined) {
|
|
|
581
591
|
const compressor = new IdCompressor(localSessionId, logger === undefined ? undefined : (0, internal_2.createChildLogger)({ logger }));
|
|
582
592
|
return compressor;
|
|
583
593
|
}
|
|
584
|
-
exports.createIdCompressor = createIdCompressor;
|
|
585
594
|
function deserializeIdCompressor(serialized, sessionIdOrLogger, loggerOrUndefined) {
|
|
586
595
|
if (typeof sessionIdOrLogger === "string") {
|
|
587
596
|
return IdCompressor.deserialize({
|
|
@@ -596,12 +605,10 @@ function deserializeIdCompressor(serialized, sessionIdOrLogger, loggerOrUndefine
|
|
|
596
605
|
logger: (0, internal_2.extractTelemetryLoggerExt)(sessionIdOrLogger),
|
|
597
606
|
});
|
|
598
607
|
}
|
|
599
|
-
exports.deserializeIdCompressor = deserializeIdCompressor;
|
|
600
608
|
function serializeIdCompressor(compressor, withSession) {
|
|
601
609
|
const core = toIdCompressorWithCore(compressor);
|
|
602
610
|
return withSession ? core.serialize(true) : core.serialize(false);
|
|
603
611
|
}
|
|
604
|
-
exports.serializeIdCompressor = serializeIdCompressor;
|
|
605
612
|
/**
|
|
606
613
|
* Casts an {@link IIdCompressor} to include {@link IIdCompressorCore}.
|
|
607
614
|
*
|
|
@@ -621,5 +628,4 @@ function toIdCompressorWithCore(compressor) {
|
|
|
621
628
|
(0, internal_1.assert)("serialize" in compressor, 0xced /* Expected compressor to implement IIdCompressorCore */);
|
|
622
629
|
return compressor;
|
|
623
630
|
}
|
|
624
|
-
exports.toIdCompressorWithCore = toIdCompressorWithCore;
|
|
625
631
|
//# sourceMappingURL=idCompressor.js.map
|