@fluidframework/id-compressor 2.0.0-rc.1.0.6 → 2.0.0-rc.2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{.eslintrc.js → .eslintrc.cjs} +5 -5
- package/{.mocharc.js → .mocharc.cjs} +1 -1
- package/CHANGELOG.md +8 -0
- package/{api-extractor-esm.json → api-extractor-cjs.json} +5 -1
- package/api-extractor-lint.json +1 -1
- package/api-extractor.json +1 -1
- package/api-report/id-compressor.api.md +5 -42
- package/dist/finalSpace.d.ts +2 -2
- package/dist/finalSpace.d.ts.map +1 -1
- package/dist/finalSpace.js +4 -4
- package/dist/finalSpace.js.map +1 -1
- package/dist/id-compressor-alpha.d.ts +117 -112
- package/dist/id-compressor-beta.d.ts +84 -77
- package/dist/id-compressor-public.d.ts +84 -77
- package/dist/id-compressor-untrimmed.d.ts +117 -112
- package/dist/idCompressor.d.ts +15 -19
- package/dist/idCompressor.d.ts.map +1 -1
- package/dist/idCompressor.js +107 -94
- package/dist/idCompressor.js.map +1 -1
- package/dist/identifiers.d.ts +1 -1
- package/dist/identifiers.d.ts.map +1 -1
- package/dist/identifiers.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -10
- package/dist/index.js.map +1 -1
- package/dist/package.json +3 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/persistanceUtilities.d.ts +1 -1
- package/dist/persistanceUtilities.d.ts.map +1 -1
- package/dist/persistanceUtilities.js.map +1 -1
- package/dist/sessionSpaceNormalizer.d.ts +2 -2
- package/dist/sessionSpaceNormalizer.d.ts.map +1 -1
- package/dist/sessionSpaceNormalizer.js +4 -4
- package/dist/sessionSpaceNormalizer.js.map +1 -1
- package/dist/sessions.d.ts +2 -2
- package/dist/sessions.d.ts.map +1 -1
- package/dist/sessions.js +12 -12
- package/dist/sessions.js.map +1 -1
- package/dist/test/appendOnlySortedMap.perf.spec.d.ts +6 -0
- package/dist/test/appendOnlySortedMap.perf.spec.d.ts.map +1 -0
- package/dist/test/appendOnlySortedMap.perf.spec.js.map +1 -0
- package/dist/test/appendOnlySortedMap.spec.d.ts +6 -0
- package/dist/test/appendOnlySortedMap.spec.d.ts.map +1 -0
- package/dist/test/appendOnlySortedMap.spec.js.map +1 -0
- package/dist/test/idCompressor.perf.spec.d.ts +6 -0
- package/dist/test/idCompressor.perf.spec.d.ts.map +1 -0
- package/dist/test/idCompressor.perf.spec.js.map +1 -0
- package/dist/test/idCompressor.spec.d.ts +6 -0
- package/dist/test/idCompressor.spec.d.ts.map +1 -0
- package/dist/test/idCompressor.spec.js.map +1 -0
- package/dist/test/idCompressorTestUtilities.d.ts +245 -0
- package/dist/test/idCompressorTestUtilities.d.ts.map +1 -0
- package/dist/test/idCompressorTestUtilities.js +589 -0
- package/dist/test/idCompressorTestUtilities.js.map +1 -0
- package/dist/test/index.d.ts +9 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +13 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test/numericUuid.spec.d.ts +6 -0
- package/dist/test/numericUuid.spec.d.ts.map +1 -0
- package/dist/test/numericUuid.spec.js.map +1 -0
- package/dist/test/sessionSpaceNormalizer.spec.d.ts +6 -0
- package/dist/test/sessionSpaceNormalizer.spec.d.ts.map +1 -0
- package/dist/test/sessionSpaceNormalizer.spec.js.map +1 -0
- package/dist/test/snapshots/dirname.cjs +16 -0
- package/dist/test/snapshots/dirname.cjs.map +1 -0
- package/dist/test/snapshots/dirname.d.cts +6 -0
- package/dist/test/snapshots/dirname.d.cts.map +1 -0
- package/{lib/types/idCompressor.mjs → dist/test/snapshots/summary.spec.d.ts} +1 -1
- package/dist/test/snapshots/summary.spec.d.ts.map +1 -0
- package/dist/test/snapshots/summary.spec.js.map +1 -0
- package/dist/test/testCommon.d.ts +90 -0
- package/dist/test/testCommon.d.ts.map +1 -0
- package/dist/test/testCommon.js +90 -0
- package/dist/test/testCommon.js.map +1 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/types/idCompressor.d.ts +134 -67
- package/dist/types/idCompressor.d.ts.map +1 -1
- package/dist/types/idCompressor.js.map +1 -1
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/persisted-types/0.0.1.d.ts +1 -1
- package/dist/types/persisted-types/0.0.1.d.ts.map +1 -1
- package/dist/types/persisted-types/0.0.1.js.map +1 -1
- package/dist/types/persisted-types/index.d.ts +1 -1
- package/dist/types/persisted-types/index.d.ts.map +1 -1
- package/dist/types/persisted-types/index.js.map +1 -1
- package/dist/utilities.d.ts +2 -2
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js.map +1 -1
- package/lib/{appendOnlySortedMap.d.mts → appendOnlySortedMap.d.ts} +1 -1
- package/lib/appendOnlySortedMap.d.ts.map +1 -0
- package/lib/{appendOnlySortedMap.mjs → appendOnlySortedMap.js} +3 -1
- package/lib/appendOnlySortedMap.js.map +1 -0
- package/lib/{finalSpace.d.mts → finalSpace.d.ts} +3 -3
- package/lib/finalSpace.d.ts.map +1 -0
- package/lib/{finalSpace.mjs → finalSpace.js} +2 -2
- package/lib/finalSpace.js.map +1 -0
- package/lib/{id-compressor-alpha.d.mts → id-compressor-alpha.d.ts} +117 -112
- package/lib/id-compressor-beta.d.ts +179 -0
- package/lib/id-compressor-public.d.ts +179 -0
- package/lib/{id-compressor-untrimmed.d.mts → id-compressor-untrimmed.d.ts} +117 -112
- package/lib/{idCompressor.d.mts → idCompressor.d.ts} +16 -20
- package/lib/idCompressor.d.ts.map +1 -0
- package/lib/{idCompressor.mjs → idCompressor.js} +54 -41
- package/lib/idCompressor.js.map +1 -0
- package/lib/{identifiers.d.mts → identifiers.d.ts} +2 -2
- package/lib/identifiers.d.ts.map +1 -0
- package/lib/{identifiers.mjs → identifiers.js} +1 -1
- package/lib/identifiers.js.map +1 -0
- package/lib/{index.d.mts → index.d.ts} +7 -4
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +10 -0
- package/lib/index.js.map +1 -0
- package/lib/{packageVersion.d.mts → packageVersion.d.ts} +2 -2
- package/lib/packageVersion.d.ts.map +1 -0
- package/lib/{packageVersion.mjs → packageVersion.js} +2 -2
- package/lib/packageVersion.js.map +1 -0
- package/lib/{persistanceUtilities.d.mts → persistanceUtilities.d.ts} +2 -2
- package/lib/persistanceUtilities.d.ts.map +1 -0
- package/lib/{persistanceUtilities.mjs → persistanceUtilities.js} +1 -1
- package/lib/persistanceUtilities.js.map +1 -0
- package/lib/{sessionSpaceNormalizer.d.mts → sessionSpaceNormalizer.d.ts} +3 -3
- package/lib/sessionSpaceNormalizer.d.ts.map +1 -0
- package/lib/{sessionSpaceNormalizer.mjs → sessionSpaceNormalizer.js} +3 -3
- package/lib/sessionSpaceNormalizer.js.map +1 -0
- package/lib/{sessions.d.mts → sessions.d.ts} +3 -3
- package/lib/sessions.d.ts.map +1 -0
- package/lib/{sessions.mjs → sessions.js} +2 -2
- package/lib/sessions.js.map +1 -0
- package/lib/test/appendOnlySortedMap.perf.spec.d.ts +6 -0
- package/lib/test/appendOnlySortedMap.perf.spec.d.ts.map +1 -0
- package/lib/test/appendOnlySortedMap.perf.spec.js +49 -0
- package/lib/test/appendOnlySortedMap.perf.spec.js.map +1 -0
- package/lib/test/appendOnlySortedMap.spec.d.ts +6 -0
- package/lib/test/appendOnlySortedMap.spec.d.ts.map +1 -0
- package/lib/test/appendOnlySortedMap.spec.js +166 -0
- package/lib/test/appendOnlySortedMap.spec.js.map +1 -0
- package/lib/test/idCompressor.perf.spec.d.ts +6 -0
- package/lib/test/idCompressor.perf.spec.d.ts.map +1 -0
- package/lib/test/idCompressor.perf.spec.js +281 -0
- package/lib/test/idCompressor.perf.spec.js.map +1 -0
- package/lib/test/idCompressor.spec.d.ts +6 -0
- package/lib/test/idCompressor.spec.d.ts.map +1 -0
- package/lib/test/idCompressor.spec.js +953 -0
- package/lib/test/idCompressor.spec.js.map +1 -0
- package/lib/test/idCompressorTestUtilities.d.ts +245 -0
- package/lib/test/idCompressorTestUtilities.d.ts.map +1 -0
- package/lib/test/idCompressorTestUtilities.js +576 -0
- package/lib/test/idCompressorTestUtilities.js.map +1 -0
- package/lib/test/index.d.ts +9 -0
- package/lib/test/index.d.ts.map +1 -0
- package/lib/test/index.js +9 -0
- package/lib/test/index.js.map +1 -0
- package/lib/test/numericUuid.spec.d.ts +6 -0
- package/lib/test/numericUuid.spec.d.ts.map +1 -0
- package/lib/test/numericUuid.spec.js +74 -0
- package/lib/test/numericUuid.spec.js.map +1 -0
- package/lib/test/sessionSpaceNormalizer.spec.d.ts +6 -0
- package/lib/test/sessionSpaceNormalizer.spec.d.ts.map +1 -0
- package/lib/test/sessionSpaceNormalizer.spec.js +43 -0
- package/lib/test/sessionSpaceNormalizer.spec.js.map +1 -0
- package/lib/test/snapshots/dirname.cjs +16 -0
- package/lib/test/snapshots/dirname.cjs.map +1 -0
- package/lib/test/snapshots/dirname.d.cts +6 -0
- package/lib/test/snapshots/dirname.d.cts.map +1 -0
- package/lib/test/snapshots/summary.spec.d.ts +6 -0
- package/lib/test/snapshots/summary.spec.d.ts.map +1 -0
- package/lib/test/snapshots/summary.spec.js +127 -0
- package/lib/test/snapshots/summary.spec.js.map +1 -0
- package/lib/test/testCommon.d.ts +90 -0
- package/lib/test/testCommon.d.ts.map +1 -0
- package/lib/test/testCommon.js +80 -0
- package/lib/test/testCommon.js.map +1 -0
- package/lib/types/{idCompressor.d.mts → idCompressor.d.ts} +135 -68
- package/lib/types/idCompressor.d.ts.map +1 -0
- package/lib/types/{identifiers.mjs → idCompressor.js} +1 -1
- package/lib/types/idCompressor.js.map +1 -0
- package/lib/types/{identifiers.d.mts → identifiers.d.ts} +1 -1
- package/lib/types/identifiers.d.ts.map +1 -0
- package/lib/types/identifiers.js +6 -0
- package/lib/types/identifiers.js.map +1 -0
- package/lib/types/{index.d.mts → index.d.ts} +4 -4
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/{persisted-types/0.0.1.mjs → index.js} +1 -1
- package/lib/types/index.js.map +1 -0
- package/lib/types/persisted-types/{0.0.1.d.mts → 0.0.1.d.ts} +2 -2
- package/lib/types/persisted-types/0.0.1.d.ts.map +1 -0
- package/lib/types/persisted-types/{index.mjs → 0.0.1.js} +1 -1
- package/lib/types/persisted-types/0.0.1.js.map +1 -0
- package/lib/types/persisted-types/{index.d.mts → index.d.ts} +2 -2
- package/lib/types/persisted-types/index.d.ts.map +1 -0
- package/lib/types/{index.mjs → persisted-types/index.js} +1 -1
- package/lib/types/persisted-types/index.js.map +1 -0
- package/lib/{utilities.d.mts → utilities.d.ts} +3 -3
- package/lib/utilities.d.ts.map +1 -0
- package/lib/{utilities.mjs → utilities.js} +2 -1
- package/lib/utilities.js.map +1 -0
- package/package.json +87 -21
- package/src/finalSpace.ts +2 -2
- package/src/idCompressor.ts +75 -59
- package/src/identifiers.ts +1 -1
- package/src/index.ts +3 -3
- package/src/packageVersion.ts +1 -1
- package/src/persistanceUtilities.ts +1 -1
- package/src/sessionSpaceNormalizer.ts +3 -3
- package/src/sessions.ts +3 -3
- package/src/test/idCompressorTestUtilities.ts +921 -0
- package/src/test/index.ts +10 -0
- package/src/test/snapshots/dirname.cts +13 -0
- package/src/test/snapshots/files/compressor-with-finalized-range-from-one-client +1 -0
- package/src/test/snapshots/files/compressor-with-finalized-range-from-one-client-client2 +1 -0
- package/src/test/snapshots/files/compressors-with-finalized-ranges-from-two-clients +1 -0
- package/src/test/snapshots/files/compressors-with-finalized-ranges-from-two-clients-client2 +1 -0
- package/src/test/snapshots/files/empty-compressor-summary +1 -0
- package/src/test/snapshots/files/expansion-semantics +1 -0
- package/src/test/snapshots/files/expansion-semantics-client2 +1 -0
- package/src/test/testCommon.ts +143 -0
- package/src/test/tsconfig.cjs.json +12 -0
- package/src/test/tsconfig.json +20 -0
- package/src/types/idCompressor.ts +147 -72
- package/src/types/index.ts +8 -3
- package/src/types/persisted-types/0.0.1.ts +1 -1
- package/src/types/persisted-types/index.ts +1 -1
- package/src/utilities.ts +2 -2
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.json +2 -5
- package/lib/appendOnlySortedMap.d.mts.map +0 -1
- package/lib/appendOnlySortedMap.mjs.map +0 -1
- package/lib/finalSpace.d.mts.map +0 -1
- package/lib/finalSpace.mjs.map +0 -1
- package/lib/id-compressor-beta.d.mts +0 -172
- package/lib/id-compressor-public.d.mts +0 -172
- package/lib/idCompressor.d.mts.map +0 -1
- package/lib/idCompressor.mjs.map +0 -1
- package/lib/identifiers.d.mts.map +0 -1
- package/lib/identifiers.mjs.map +0 -1
- package/lib/index.d.mts.map +0 -1
- package/lib/index.mjs +0 -7
- package/lib/index.mjs.map +0 -1
- package/lib/packageVersion.d.mts.map +0 -1
- package/lib/packageVersion.mjs.map +0 -1
- package/lib/persistanceUtilities.d.mts.map +0 -1
- package/lib/persistanceUtilities.mjs.map +0 -1
- package/lib/sessionSpaceNormalizer.d.mts.map +0 -1
- package/lib/sessionSpaceNormalizer.mjs.map +0 -1
- package/lib/sessions.d.mts.map +0 -1
- package/lib/sessions.mjs.map +0 -1
- package/lib/types/idCompressor.d.mts.map +0 -1
- package/lib/types/idCompressor.mjs.map +0 -1
- package/lib/types/identifiers.d.mts.map +0 -1
- package/lib/types/identifiers.mjs.map +0 -1
- package/lib/types/index.d.mts.map +0 -1
- package/lib/types/index.mjs.map +0 -1
- package/lib/types/persisted-types/0.0.1.d.mts.map +0 -1
- package/lib/types/persisted-types/0.0.1.mjs.map +0 -1
- package/lib/types/persisted-types/index.d.mts.map +0 -1
- package/lib/types/persisted-types/index.mjs.map +0 -1
- package/lib/utilities.d.mts.map +0 -1
- package/lib/utilities.mjs.map +0 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Exports for test utilities for `id-compressor`
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { createAlwaysFinalizedIdCompressor } from "./idCompressorTestUtilities.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Problem:
|
|
7
|
+
// - `__dirname` is not defined in ESM
|
|
8
|
+
// - `import.meta.url` is not defined in CJS
|
|
9
|
+
// Solution:
|
|
10
|
+
// - Export '__dirname' from a .cjs file in the same directory.
|
|
11
|
+
//
|
|
12
|
+
// Note that *.cjs files are always CommonJS, but can be imported from ESM.
|
|
13
|
+
export const _dirname = __dirname;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AAAAAAAAAEAAAAAAAAAAAAAAAAAAAPA/AAAAAAAA8D/pXqCZfUEHBR2USVl4/AABAAAAAAAAAAAAAAAAAFCAQAAAAAAAACRA
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEDpXqCZfUEHBR2USVl4/AAB3r8WOsPYt3ejBGppnQksAQAAAAAAAAAAAAAAAABQgEAAAAAAAAAkQAAAAAAAAPA/AAAAAABQgEAAAAAAAAAkQA==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEDevxY6w9i3d6MEammdCSwB6V6gmX1BBwUdlElZePwAAQAAAAAAAPA/AAAAAABQgEAAAAAAAAAkQAAAAAAAAAAAAAAAAABQgEAAAAAAAAAkQA==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AAAAAAAAAEAAAAAAAAAAAAAAAAAAAPA/AAAAAAAA8D/pXqCZfUEHBR2USVl4/AABAAAAAAAAAAAAAAAAAAAYQAAAAAAAABBA
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
AAAAAAAAAEAAAAAAAAAAAAAAAAAAAPA/AAAAAAAA8D/pXqCZfUEHBR2USVl4/AABAAAAAAAAAAAAAAAAAAAYQAAAAAAAABBA
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { assert } from "@fluidframework/core-utils";
|
|
7
|
+
import { SessionSpaceCompressedId, StableId, OpSpaceCompressedId } from "..//index.js";
|
|
8
|
+
import {
|
|
9
|
+
numericUuidFromStableId,
|
|
10
|
+
offsetNumericUuid,
|
|
11
|
+
stableIdFromNumericUuid,
|
|
12
|
+
} from "../utilities.js";
|
|
13
|
+
import { IdCompressor } from "../idCompressor.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* An identifier (v4 UUID) that has been shortened by a distributed compression algorithm.
|
|
17
|
+
* Lacks a space (session/op), meaning its scope is the same as the space-specific ID from which it was derived.
|
|
18
|
+
* @alpha
|
|
19
|
+
*/
|
|
20
|
+
export type CompressedId =
|
|
21
|
+
| SessionSpaceCompressedId
|
|
22
|
+
| OpSpaceCompressedId
|
|
23
|
+
| FinalCompressedId
|
|
24
|
+
| LocalCompressedId;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A compressed ID that is stable and unique within the scope of network of compressors (i.e. a document).
|
|
28
|
+
* It can only be used/decompressed in the context of the originating document.
|
|
29
|
+
* @alpha
|
|
30
|
+
*/
|
|
31
|
+
export type FinalCompressedId = number & {
|
|
32
|
+
readonly FinalCompressedId: "5d83d1e2-98b7-4e4e-a889-54c855cfa73d";
|
|
33
|
+
|
|
34
|
+
// Same brand as OpNormalizedCompressedId, as final IDs are always finally normalized
|
|
35
|
+
readonly OpNormalized: "9209432d-a959-4df7-b2ad-767ead4dbcae";
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A compressed ID that is local to a session (can only be decompressed when paired with a SessionId).
|
|
40
|
+
* Internally, it should not be persisted outside a scope annotated with the originating SessionId in order to be unambiguous.
|
|
41
|
+
* If external persistence is needed (e.g. by a client), a StableId should be used instead.
|
|
42
|
+
* @alpha
|
|
43
|
+
*/
|
|
44
|
+
export type LocalCompressedId = number & {
|
|
45
|
+
readonly LocalCompressedId: "6fccb42f-e2a4-4243-bd29-f13d12b9c6d1";
|
|
46
|
+
} & SessionSpaceCompressedId; // Same brand as CompressedId, as local IDs are always locally normalized
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @returns true if the supplied ID is a final ID.
|
|
50
|
+
*/
|
|
51
|
+
export function isFinalId(id: CompressedId): id is FinalCompressedId {
|
|
52
|
+
return id >= 0;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @returns true if the supplied ID is a local ID.
|
|
57
|
+
*/
|
|
58
|
+
export function isLocalId(id: CompressedId): id is LocalCompressedId {
|
|
59
|
+
return id < 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Turns a negative integer into a local compressed ID. For testing only.
|
|
64
|
+
*/
|
|
65
|
+
export function makeLocalId(negativeInteger: number): LocalCompressedId {
|
|
66
|
+
const id = negativeInteger as CompressedId;
|
|
67
|
+
assert(isLocalId(id), "Not a negative integer.");
|
|
68
|
+
return id;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Remove `readonly` from all fields.
|
|
73
|
+
*/
|
|
74
|
+
export type Mutable<T> = { -readonly [P in keyof T]: T[P] };
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Retrieve a value from a map with the given key, or create a new entry if the key is not in the map.
|
|
78
|
+
* @param map - The map to query/update
|
|
79
|
+
* @param key - The key to lookup in the map
|
|
80
|
+
* @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
|
|
81
|
+
* @returns either the existing value for the given key, or the newly-created value (the result of `defaultValue`)
|
|
82
|
+
*/
|
|
83
|
+
export function getOrCreate<K, V>(map: Map<K, V>, key: K, defaultValue: (key: K) => V): V {
|
|
84
|
+
let value = map.get(key);
|
|
85
|
+
if (value === undefined) {
|
|
86
|
+
value = defaultValue(key);
|
|
87
|
+
map.set(key, value);
|
|
88
|
+
}
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function incrementStableId(stableId: StableId, offset: number): StableId {
|
|
93
|
+
return stableIdFromNumericUuid(offsetNumericUuid(numericUuidFromStableId(stableId), offset));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** An immutable view of an `IdCompressor` */
|
|
97
|
+
export type ReadonlyIdCompressor = Omit<
|
|
98
|
+
IdCompressor,
|
|
99
|
+
| "generateCompressedId"
|
|
100
|
+
| "generateCompressedIdRange"
|
|
101
|
+
| "takeNextCreationRange"
|
|
102
|
+
| "finalizeCreationRange"
|
|
103
|
+
>;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Asserts a value is not undefined, and returns the value.
|
|
107
|
+
* Use when violations are logic errors in the program.
|
|
108
|
+
*
|
|
109
|
+
* @remarks
|
|
110
|
+
* When practical, prefer the pattern `x ?? fail('message')` over `assertNotUndefined(x, 'message')`.
|
|
111
|
+
* Using `?? fail` allows for message formatting without incurring the cost of formatting the message
|
|
112
|
+
* in the non failing case.
|
|
113
|
+
*
|
|
114
|
+
* Example:
|
|
115
|
+
* ```typescript
|
|
116
|
+
* x ?? fail(`x should exist for ${y}`)
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* Additionally the `?? fail` avoids an extra call/stack frame in the non failing case.
|
|
120
|
+
*
|
|
121
|
+
* Another pattern to prefer over `assertNotUndefined(x, 'message')` is `assert(x !== undefined)`.
|
|
122
|
+
* This pattern is preferred because it is more general (same approach works with typeof, instance of,
|
|
123
|
+
* comparison to other values etc.).
|
|
124
|
+
*
|
|
125
|
+
* @param value - Value to assert against is non undefined.
|
|
126
|
+
* @param message - Message to be printed if assertion fails.
|
|
127
|
+
*/
|
|
128
|
+
export function assertNotUndefined<T>(
|
|
129
|
+
value: T | undefined,
|
|
130
|
+
message = "value must not be undefined",
|
|
131
|
+
): T {
|
|
132
|
+
assert(value !== undefined, message);
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Fails an assertion. Throws an Error that the assertion failed.
|
|
138
|
+
* Use when violations are logic errors in the program.
|
|
139
|
+
* @param message - Message to be printed if assertion fails.
|
|
140
|
+
*/
|
|
141
|
+
export function fail(message: string): never {
|
|
142
|
+
assert(false, message);
|
|
143
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
// This config must be used in a "type": "commonjs" environment. (Use fluid-tsc commonjs.)
|
|
3
|
+
"extends": "./tsconfig.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"outDir": "../../dist/test",
|
|
6
|
+
},
|
|
7
|
+
"references": [
|
|
8
|
+
{
|
|
9
|
+
"path": "../../tsconfig.cjs.json",
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../../../common/build/build-common/tsconfig.test.node16.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": "./",
|
|
5
|
+
"outDir": "../../lib/test",
|
|
6
|
+
"types": ["mocha"],
|
|
7
|
+
|
|
8
|
+
// The package exports utilities for test code from the test folder, so we need to build types for test files, which we typically
|
|
9
|
+
// don't do.
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"declarationMap": true,
|
|
12
|
+
"noImplicitAny": false,
|
|
13
|
+
},
|
|
14
|
+
"include": ["./**/*"],
|
|
15
|
+
"references": [
|
|
16
|
+
{
|
|
17
|
+
"path": "../..",
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
}
|
|
@@ -3,65 +3,17 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
SessionSpaceCompressedId,
|
|
8
|
+
OpSpaceCompressedId,
|
|
9
|
+
SessionId,
|
|
10
|
+
StableId,
|
|
11
|
+
} from "./identifiers.js";
|
|
7
12
|
import {
|
|
8
13
|
IdCreationRange,
|
|
9
14
|
SerializedIdCompressorWithNoSession,
|
|
10
15
|
SerializedIdCompressorWithOngoingSession,
|
|
11
|
-
} from "./persisted-types";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @alpha
|
|
15
|
-
*/
|
|
16
|
-
export interface IIdCompressorCore {
|
|
17
|
-
/**
|
|
18
|
-
* Returns a range of IDs created by this session in a format for sending to the server for finalizing.
|
|
19
|
-
* The range will include all IDs generated via calls to `generateCompressedId` since the last time this method was called.
|
|
20
|
-
* @returns the range of IDs, which may be empty. This range must be sent to the server for ordering before
|
|
21
|
-
* it is finalized. Ranges must be sent to the server in the order that they are taken via calls to this method.
|
|
22
|
-
*/
|
|
23
|
-
takeNextCreationRange(): IdCreationRange;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Finalizes the supplied range of IDs (which may be from either a remote or local session).
|
|
27
|
-
* @param range - the range of session-local IDs to finalize.
|
|
28
|
-
*/
|
|
29
|
-
finalizeCreationRange(range: IdCreationRange): void;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Run a callback that is performed from the perspective of a special "ghost" session.
|
|
33
|
-
* Any ids generated by this session will be immediately finalized on the local client as if
|
|
34
|
-
* they were created by a remote client with `ghostSessionId`.
|
|
35
|
-
*
|
|
36
|
-
* *WARNING:* This API requires an external consensus mechanism to safely use:
|
|
37
|
-
* In an attached container (i.e. multiple clients may have the document loaded), all clients must guarantee that:
|
|
38
|
-
* - They invoke this API starting from the same finalized creation ranges
|
|
39
|
-
* - This API is invoked with the same ghost session id
|
|
40
|
-
* - `ghostSessionCallback` deterministically mints the same number of ids on each client within the ghost session
|
|
41
|
-
* Failure to meet these requirement will result in divergence across clients and eventual consistency errors.
|
|
42
|
-
* While the ghost sesion callback is running, IdCompressor does not support serialization.
|
|
43
|
-
* @remarks This API is primarily intended for data migration scenarios which are able to deterministically transform
|
|
44
|
-
* data in some format into data in a new format.
|
|
45
|
-
* The first requirement (that all clients must invoke the API with the same finalized creation ranges) is guaranteed
|
|
46
|
-
* for this scenario because the data transformation callback occurs at a specific ack within the op stream on all
|
|
47
|
-
* clients, and clients don't finalize creation ranges for local changes they might have at this point in time.
|
|
48
|
-
* @param ghostSessionId - The session id that minted ids generated within `ghostSessionCallback` should be attributed to.
|
|
49
|
-
* @param ghostSessionCallback - Callback which mints ids attributed to the ghost session.
|
|
50
|
-
*/
|
|
51
|
-
beginGhostSession(ghostSessionId: SessionId, ghostSessionCallback: () => void);
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.
|
|
55
|
-
* This includes finalized state as well as un-finalized state and is therefore suitable for use in offline scenarios.
|
|
56
|
-
*/
|
|
57
|
-
serialize(withSession: true): SerializedIdCompressorWithOngoingSession;
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.
|
|
61
|
-
* This only includes finalized state and is therefore suitable for use in summaries.
|
|
62
|
-
*/
|
|
63
|
-
serialize(withSession: false): SerializedIdCompressorWithNoSession;
|
|
64
|
-
}
|
|
16
|
+
} from "./persisted-types/index.js";
|
|
65
17
|
|
|
66
18
|
/**
|
|
67
19
|
* A distributed UUID generator and compressor.
|
|
@@ -123,31 +75,152 @@ export interface IIdCompressorCore {
|
|
|
123
75
|
*
|
|
124
76
|
* These two spaces naturally define a rule: consumers of compressed IDs should use session-space IDs, but serialized forms such as ops
|
|
125
77
|
* should use op-space IDs.
|
|
78
|
+
* @alpha
|
|
79
|
+
*/
|
|
80
|
+
export interface IIdCompressorCore {
|
|
81
|
+
/**
|
|
82
|
+
* Returns a range of IDs created by this session in a format for sending to the server for finalizing.
|
|
83
|
+
* The range will include all IDs generated via calls to `generateCompressedId` since the last time this method was called.
|
|
84
|
+
* @returns the range of IDs, which may be empty. This range must be sent to the server for ordering before
|
|
85
|
+
* it is finalized. Ranges must be sent to the server in the order that they are taken via calls to this method.
|
|
86
|
+
*/
|
|
87
|
+
takeNextCreationRange(): IdCreationRange;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Finalizes the supplied range of IDs (which may be from either a remote or local session).
|
|
91
|
+
* @param range - the range of session-local IDs to finalize.
|
|
92
|
+
*/
|
|
93
|
+
finalizeCreationRange(range: IdCreationRange): void;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Run a callback that is performed from the perspective of a special "ghost" session.
|
|
97
|
+
* Any ids generated by this session will be immediately finalized on the local client as if
|
|
98
|
+
* they were created by a remote client with `ghostSessionId`.
|
|
99
|
+
*
|
|
100
|
+
* *WARNING:* This API requires an external consensus mechanism to safely use:
|
|
101
|
+
* In an attached container (i.e. multiple clients may have the document loaded), all clients must guarantee that:
|
|
102
|
+
* - They invoke this API starting from the same finalized creation ranges
|
|
103
|
+
* - This API is invoked with the same ghost session id
|
|
104
|
+
* - `ghostSessionCallback` deterministically mints the same number of ids on each client within the ghost session
|
|
105
|
+
* Failure to meet these requirement will result in divergence across clients and eventual consistency errors.
|
|
106
|
+
* While the ghost sesion callback is running, IdCompressor does not support serialization.
|
|
107
|
+
* @remarks This API is primarily intended for data migration scenarios which are able to deterministically transform
|
|
108
|
+
* data in some format into data in a new format.
|
|
109
|
+
* The first requirement (that all clients must invoke the API with the same finalized creation ranges) is guaranteed
|
|
110
|
+
* for this scenario because the data transformation callback occurs at a specific ack within the op stream on all
|
|
111
|
+
* clients, and clients don't finalize creation ranges for local changes they might have at this point in time.
|
|
112
|
+
* @param ghostSessionId - The session id that minted ids generated within `ghostSessionCallback` should be attributed to.
|
|
113
|
+
* @param ghostSessionCallback - Callback which mints ids attributed to the ghost session.
|
|
114
|
+
*/
|
|
115
|
+
beginGhostSession(ghostSessionId: SessionId, ghostSessionCallback: () => void);
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.
|
|
119
|
+
* This includes finalized state as well as un-finalized state and is therefore suitable for use in offline scenarios.
|
|
120
|
+
*/
|
|
121
|
+
serialize(withSession: true): SerializedIdCompressorWithOngoingSession;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Returns a persistable form of the current state of this `IdCompressor` which can be rehydrated via `IdCompressor.deserialize()`.
|
|
125
|
+
* This only includes finalized state and is therefore suitable for use in summaries.
|
|
126
|
+
*/
|
|
127
|
+
serialize(withSession: false): SerializedIdCompressorWithNoSession;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* A distributed UUID generator and compressor.
|
|
132
|
+
* `IdCompressor` offers the ability to generate arbitrary non-colliding v4 UUIDs, called stable IDs, while compressing them into small integers
|
|
133
|
+
* for efficient storage and transmission. It also provides the ability to decompress these integers back into their original UUIDs.
|
|
134
|
+
*
|
|
135
|
+
* The compressor is designed to be used in a distributed environment, where multiple clients may be generating IDs concurrently.
|
|
136
|
+
* IDs generated by a compressor, via calls to `generateCompressedId`, are created in the compressor's "local" session.
|
|
137
|
+
* These IDs are unique within the session, but may not be unique across sessions. In the context of Fluid, the scope of a session
|
|
138
|
+
* is the same as the scope of a container. This means that anytime IDs are transferred between sessions, they must be translated
|
|
139
|
+
* through a process called "normalization":
|
|
140
|
+
* - The scope of a local session (in which local IDs are unique) is called the "session space" of the client.
|
|
141
|
+
* - The context of persisted state (in Fluid, this is the context of ops and summaries) is called "op space".
|
|
142
|
+
* - `SessionSpaceCompressedId`s, generated via calls to `generateCompressedId`, should NEVER be serialized directly.
|
|
143
|
+
* In Fluid, this means they should not be included in ops or summaries.
|
|
144
|
+
* - Before serialization, IDs must be normalized to op space to ensure they are interpretable by other clients.
|
|
145
|
+
* - Upon receipt, IDs should be normalized back to session space before use.
|
|
146
|
+
*
|
|
147
|
+
* Example Usage:
|
|
148
|
+
*
|
|
149
|
+
* ### Client A (Sender)
|
|
150
|
+
*
|
|
151
|
+
* ```typescript
|
|
152
|
+
* // Generate several local IDs
|
|
153
|
+
* const localId1 = idCompressor.generateCompressedId();
|
|
154
|
+
* const localId2 = idCompressor.generateCompressedId();
|
|
155
|
+
* const localId3 = idCompressor.generateCompressedId();
|
|
156
|
+
*
|
|
157
|
+
* // Normalize these IDs to op space for inclusion in a message
|
|
158
|
+
* const opSpaceId1 = idCompressor.normalizeToOpSpace(localId1);
|
|
159
|
+
* const opSpaceId2 = idCompressor.normalizeToOpSpace(localId2);
|
|
160
|
+
* const opSpaceId3 = idCompressor.normalizeToOpSpace(localId3);
|
|
161
|
+
*
|
|
162
|
+
* // Create and send a message containing these op space IDs along with the sender's session ID
|
|
163
|
+
* // In Fluid, this would be an op or summary
|
|
164
|
+
* const message = {
|
|
165
|
+
* sessionID: idCompressor.localSessionId,
|
|
166
|
+
* ids: [opSpaceId1, opSpaceId2, opSpaceId3]
|
|
167
|
+
* };
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* ### Client B (Receiver)
|
|
171
|
+
*
|
|
172
|
+
* ```typescript
|
|
173
|
+
* // Receive the message from Client A
|
|
174
|
+
* const receivedMessage = ...; // In Fluid, this would be an op or summary
|
|
175
|
+
*
|
|
176
|
+
* // Normalize the received IDs back to session space, utilizing the sender's session ID
|
|
177
|
+
* const sessionSpaceId1 = idCompressor.normalizeToSessionSpace(receivedMessage.ids[0], receivedMessage.sessionID);
|
|
178
|
+
* const sessionSpaceId2 = idCompressor.normalizeToSessionSpace(receivedMessage.ids[1], receivedMessage.sessionID);
|
|
179
|
+
* const sessionSpaceId3 = idCompressor.normalizeToSessionSpace(receivedMessage.ids[2], receivedMessage.sessionID);
|
|
180
|
+
* ```
|
|
126
181
|
* @public
|
|
127
182
|
*/
|
|
128
183
|
export interface IIdCompressor {
|
|
184
|
+
/**
|
|
185
|
+
* The local session ID.
|
|
186
|
+
*/
|
|
129
187
|
localSessionId: SessionId;
|
|
130
188
|
|
|
131
189
|
/**
|
|
132
|
-
* Generates a new compressed ID
|
|
133
|
-
*
|
|
190
|
+
* Generates a new compressed ID.
|
|
191
|
+
* The returned ID is in session space and should not be serialized directly. See `IIdCompressor` for more details.
|
|
134
192
|
* @returns A new local ID in session space.
|
|
135
193
|
*/
|
|
136
194
|
generateCompressedId(): SessionSpaceCompressedId;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Generates a new ID that is guaranteed to be unique across all sessions known to this compressor without the need for any
|
|
198
|
+
* normalization. The returned ID is not guaranteed to be a compressed ID (small number); it may be a stable ID (UUID string).
|
|
199
|
+
* In Fluid, the likelihood of generating the bulkier stable ID is dictated by network conditions and is highly probably in
|
|
200
|
+
* scenarios such as offline. This is still useful for use cases where simplicity is more important than performance and
|
|
201
|
+
* this approach will often be superior to generating a UUID.
|
|
202
|
+
* If small numbers are a requirement, `generateCompressedId` and normalization should be used instead.
|
|
203
|
+
* See `IIdCompressor` for more details.
|
|
204
|
+
* @returns A new local ID in session space.
|
|
205
|
+
*/
|
|
206
|
+
generateDocumentUniqueId(): (SessionSpaceCompressedId & OpSpaceCompressedId) | StableId;
|
|
207
|
+
|
|
137
208
|
/**
|
|
138
209
|
* Normalizes a session space ID into op space.
|
|
139
|
-
*
|
|
140
|
-
*
|
|
210
|
+
* The returned ID is in op space and can be safely serialized. However, it should be normalized back to session space before use.
|
|
211
|
+
* See `IIdCompressor` for more details.
|
|
212
|
+
* @param id - The local ID to normalize.
|
|
213
|
+
* @returns The ID in op space.
|
|
141
214
|
*/
|
|
142
215
|
normalizeToOpSpace(id: SessionSpaceCompressedId): OpSpaceCompressedId;
|
|
216
|
+
|
|
143
217
|
/**
|
|
144
218
|
* Normalizes an ID into session space.
|
|
145
|
-
* @param id -
|
|
146
|
-
* to
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* range that contained it from the server.
|
|
219
|
+
* @param id - The ID to normalize.
|
|
220
|
+
* @param originSessionId - The session from which `id` originated. This should be the ID of the client that normalized `id` to op space.
|
|
221
|
+
* This means that it may not be the client that created `id` in the first place, but rather the client that serialized it.
|
|
222
|
+
* This is an important distinction in the case of a reference, where a client might refer to an ID created by another client.
|
|
223
|
+
* @returns The session-space ID in the local session corresponding to `id`.
|
|
151
224
|
*/
|
|
152
225
|
normalizeToSessionSpace(
|
|
153
226
|
id: OpSpaceCompressedId,
|
|
@@ -156,22 +229,24 @@ export interface IIdCompressor {
|
|
|
156
229
|
|
|
157
230
|
/**
|
|
158
231
|
* Decompresses a previously compressed ID into a UUID.
|
|
159
|
-
* @param id -
|
|
160
|
-
* @returns
|
|
232
|
+
* @param id - The compressed ID to be decompressed.
|
|
233
|
+
* @returns The UUID associated with the compressed ID.
|
|
234
|
+
* @throws If the ID was not generated by any session known to this compressor.
|
|
161
235
|
*/
|
|
162
236
|
decompress(id: SessionSpaceCompressedId): StableId;
|
|
163
237
|
|
|
164
238
|
/**
|
|
165
239
|
* Recompresses a UUID.
|
|
166
|
-
* @param uncompressed -
|
|
167
|
-
* @returns
|
|
240
|
+
* @param uncompressed - The UUID to recompress.
|
|
241
|
+
* @returns The `CompressedId` associated with `uncompressed`.
|
|
242
|
+
* @throws If the UUID was not generated by any session known to this compressor.
|
|
168
243
|
*/
|
|
169
244
|
recompress(uncompressed: StableId): SessionSpaceCompressedId;
|
|
170
245
|
|
|
171
246
|
/**
|
|
172
|
-
* Attempts to
|
|
173
|
-
* @param uncompressed -
|
|
174
|
-
* @returns
|
|
247
|
+
* Attempts to recompress a UUID.
|
|
248
|
+
* @param uncompressed - The UUID to recompress.
|
|
249
|
+
* @returns The `CompressedId` associated with `uncompressed` or undefined if the UUID was not generated by any session known to this compressor.
|
|
175
250
|
*/
|
|
176
251
|
tryRecompress(uncompressed: StableId): SessionSpaceCompressedId | undefined;
|
|
177
252
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -8,8 +8,13 @@ export {
|
|
|
8
8
|
SerializedIdCompressor,
|
|
9
9
|
SerializedIdCompressorWithNoSession,
|
|
10
10
|
SerializedIdCompressorWithOngoingSession,
|
|
11
|
-
} from "./persisted-types";
|
|
11
|
+
} from "./persisted-types/index.js";
|
|
12
12
|
|
|
13
|
-
export { IIdCompressorCore, IIdCompressor } from "./idCompressor";
|
|
13
|
+
export { IIdCompressorCore, IIdCompressor } from "./idCompressor.js";
|
|
14
14
|
|
|
15
|
-
export {
|
|
15
|
+
export {
|
|
16
|
+
SessionSpaceCompressedId,
|
|
17
|
+
OpSpaceCompressedId,
|
|
18
|
+
SessionId,
|
|
19
|
+
StableId,
|
|
20
|
+
} from "./identifiers.js";
|
package/src/utilities.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
/* eslint-disable no-bitwise */
|
|
7
7
|
import { assert } from "@fluidframework/core-utils";
|
|
8
8
|
import { v4 } from "uuid";
|
|
9
|
-
import { SessionId, StableId } from "./types";
|
|
10
|
-
import { LocalCompressedId, NumericUuid } from "./identifiers";
|
|
9
|
+
import { SessionId, StableId } from "./types/index.js";
|
|
10
|
+
import { LocalCompressedId, NumericUuid } from "./identifiers.js";
|
|
11
11
|
|
|
12
12
|
const hexadecimalCharCodes = Array.from("09afAF").map((c) => c.charCodeAt(0)) as [
|
|
13
13
|
zero: number,
|
package/tsconfig.json
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"extends":
|
|
3
|
-
"../../../common/build/build-common/tsconfig.base.json",
|
|
4
|
-
"../../../common/build/build-common/tsconfig.cjs.json",
|
|
5
|
-
],
|
|
2
|
+
"extends": "../../../common/build/build-common/tsconfig.node16.json",
|
|
6
3
|
"compilerOptions": {
|
|
7
4
|
"rootDir": "./src",
|
|
8
|
-
"outDir": "./
|
|
5
|
+
"outDir": "./lib",
|
|
9
6
|
},
|
|
10
7
|
"include": ["src/**/*"],
|
|
11
8
|
"exclude": ["src/test/**/*"],
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"appendOnlySortedMap.d.mts","sourceRoot":"","sources":["../src/appendOnlySortedMap.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"appendOnlySortedMap.mjs","sourceRoot":"","sources":["../src/appendOnlySortedMap.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable tsdoc/syntax */\n/* eslint-disable no-bitwise */\nimport { assert } from \"@fluidframework/core-utils\";\n\n/**\n * A map in which entries are always added in key-sorted order.\n * Supports appending and searching.\n */\nexport class AppendOnlySortedMap<K, V> {\n\tprotected readonly elements: (K | V)[] = [];\n\n\t/**\n\t * @param comparator - a comparator for keys\n\t */\n\tpublic constructor(protected readonly comparator: (a: K, b: K) => number) {}\n\n\t/**\n\t * @returns the number of entries in this map\n\t */\n\tpublic get size(): number {\n\t\treturn this.elements.length / 2;\n\t}\n\n\t/**\n\t * @returns the min key in the map.\n\t */\n\tpublic minKey(): K | undefined {\n\t\treturn this.elements[0] as K | undefined;\n\t}\n\n\t/**\n\t * @returns the max key in the map.\n\t */\n\tpublic maxKey(): K | undefined {\n\t\treturn this.elements[this.elements.length - 2] as K | undefined;\n\t}\n\n\t/**\n\t * @returns the min value in the map.\n\t */\n\tpublic minValue(): V | undefined {\n\t\treturn this.elements[1] as V | undefined;\n\t}\n\n\t/**\n\t * @returns the min value in the map.\n\t */\n\tpublic maxValue(): V | undefined {\n\t\treturn this.elements[this.elements.length - 1] as V | undefined;\n\t}\n\n\t/**\n\t * @returns the min key in the map.\n\t */\n\tpublic first(): [K, V] | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [elements[0] as K, elements[1] as V];\n\t}\n\n\t/**\n\t * @returns the max key in the map.\n\t */\n\tpublic last(): [K, V] | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst lastKeyIndex = length - 2;\n\t\treturn [elements[lastKeyIndex] as K, elements[lastKeyIndex + 1] as V];\n\t}\n\n\t/**\n\t * Returns the element at the insertion index.\n\t */\n\tpublic getAtIndex(index: number): [K, V] | undefined {\n\t\tconst realIndex = index * 2;\n\t\tconst { elements } = this;\n\t\tif (realIndex < 0 || realIndex > elements.length - 1) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [elements[realIndex] as K, elements[realIndex + 1] as V];\n\t}\n\n\t/**\n\t * @returns an iterable of the entries in the map.\n\t */\n\tpublic *entries(): IterableIterator<readonly [K, V]> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield [elements[i] as K, elements[i + 1] as V];\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the keys in the map.\n\t */\n\tpublic *keys(): IterableIterator<K> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield elements[i] as K;\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the values in the map.\n\t */\n\tpublic *values(): IterableIterator<V> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield elements[i + 1] as V;\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the entries in the map, reversed.\n\t */\n\tpublic *entriesReversed(): IterableIterator<readonly [K, V]> {\n\t\tconst { elements } = this;\n\t\tfor (let i = elements.length - 2; i >= 0; i -= 2) {\n\t\t\tyield [elements[i] as K, elements[i + 1] as V];\n\t\t}\n\t}\n\n\t/**\n\t * Adds a new key/value pair to the map. `key` must be > to all keys in the map.\n\t * @param key - the key to add.\n\t * @param value - the value to add.\n\t */\n\tpublic append(key: K, value: V): void {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length !== 0 && this.comparator(key, this.maxKey() as K) <= 0) {\n\t\t\tthrow new Error(\"Inserted key must be > all others in the map.\");\n\t\t}\n\t\telements.push(key);\n\t\telements.push(value);\n\t}\n\n\t/**\n\t * Replaces the last key/value pair with the given one. If the map is empty, it simply appends.\n\t * `key` must be > to all keys in the map prior to the one replaced.\n\t * @param key - the key to add.\n\t * @param value - the value to add.\n\t */\n\tpublic replaceLast(key: K, value: V): void {\n\t\tconst { elements, comparator } = this;\n\t\tconst { length } = elements;\n\t\tif (length !== 0) {\n\t\t\telements.pop();\n\t\t\telements.pop();\n\t\t\tif (comparator(key, this.maxKey() as K) <= 0) {\n\t\t\t\tthrow new Error(\"Inserted key must be > all others in the map.\");\n\t\t\t}\n\t\t}\n\t\telements.push(key);\n\t\telements.push(value);\n\t}\n\n\t/**\n\t * @param key - the key to lookup.\n\t * @returns the value associated with `key` if such an entry exists, and undefined otherwise.\n\t */\n\tpublic get(key: K): V | undefined {\n\t\tconst index = AppendOnlySortedMap.keyIndexOf(this.elements, key, this.comparator);\n\t\tif (index < 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.elements[index + 1] as V;\n\t}\n\n\t/**\n\t * @param key - the key to lookup.\n\t * @returns the entry associated with `key` if such an entry exists, the entry associated with the next lower key if such an entry\n\t * exists, and undefined otherwise.\n\t */\n\tpublic getPairOrNextLower(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextLowerBy(key, this.comparator);\n\t}\n\n\t/**\n\t * @param key - the key to lookup.\n\t * @returns the entry associated with `key` if such an entry exists, the entry associated with the next higher key if such an entry\n\t * exists, and undefined otherwise.\n\t */\n\tpublic getPairOrNextHigher(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextHigherBy(key, this.comparator);\n\t}\n\n\t/**\n\t * Compares two `AppendOnlySortedMap`s.\n\t */\n\tpublic equals(\n\t\tother: AppendOnlySortedMap<K, V>,\n\t\tcompareValues: (a: V, b: V) => boolean,\n\t): boolean {\n\t\tif (other === this) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (this.elements.length !== other.elements.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (let i = this.elements.length - 2; i >= 0; i -= 2) {\n\t\t\tconst keyThis = this.elements[i] as K;\n\t\t\tconst valueThis = this.elements[i + 1] as V;\n\t\t\tconst keyOther = other.elements[i] as K;\n\t\t\tconst valueOther = other.elements[i + 1] as V;\n\t\t\tif (this.comparator(keyThis, keyOther) !== 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!compareValues(valueThis, valueOther)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Test-only expensive assertions to check the internal validity of the data structure.\n\t */\n\tpublic assertValid(): void {\n\t\tlet prev: readonly [K, unknown] | undefined;\n\t\tfor (const kv of this.entries()) {\n\t\t\tif (prev !== undefined) {\n\t\t\t\tassert(\n\t\t\t\t\tthis.comparator(kv[0], prev[0]) > 0,\n\t\t\t\t\t0x752 /* Keys in map must be sorted. */,\n\t\t\t\t);\n\t\t\t}\n\t\t\tprev = kv;\n\t\t}\n\t}\n\n\t/**\n\t * Queries a range of entries.\n\t * @param from - the key to start the range query at, inclusive.\n\t * @param to - the key to end the range query at, inclusive.\n\t * @returns the range of entries.\n\t */\n\tpublic *getRange(from: K, to: K): IterableIterator<readonly [K, V]> {\n\t\tconst keyIndexFrom = this.getKeyIndexOfOrNextHigher(from, this.comparator);\n\t\tif (keyIndexFrom === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst keyIndexTo = this.getKeyIndexOfOrNextLower(to, this.comparator);\n\t\tif (keyIndexTo === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = keyIndexFrom; i <= keyIndexTo; i += 2) {\n\t\t\tyield [this.elements[i] as K, this.elements[i + 1] as V];\n\t\t}\n\t}\n\n\tprotected getPairOrNextLowerBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): readonly [K, V] | undefined {\n\t\tconst keyIndex = this.getKeyIndexOfOrNextLower(search, comparator);\n\t\tif (keyIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn [this.elements[keyIndex] as K, this.elements[keyIndex + 1] as V];\n\t}\n\n\tprivate getKeyIndexOfOrNextLower<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number | undefined {\n\t\tconst { elements } = this;\n\t\tif (elements.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);\n\t\tif (keyIndex < 0) {\n\t\t\tkeyIndex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (keyIndex > 0) {\n\t\t\t\treturn keyIndex - 2;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn keyIndex;\n\t}\n\n\tprotected getPairOrNextHigherBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): readonly [K, V] | undefined {\n\t\tconst keyIndex = this.getKeyIndexOfOrNextHigher(search, comparator);\n\t\tif (keyIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn [this.elements[keyIndex] as K, this.elements[keyIndex + 1] as V];\n\t}\n\n\tprivate getKeyIndexOfOrNextHigher<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);\n\t\tif (keyIndex < 0) {\n\t\t\tkeyIndex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (keyIndex < length) {\n\t\t\t\treturn keyIndex;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn keyIndex;\n\t}\n\n\t/**\n\t * The value xor'd with the result index when a search fails.\n\t */\n\tpublic static readonly failureXor = -1;\n\n\t/**\n\t * Performs a binary search on the sorted array.\n\t * @returns the index of the key for `search`, or (if not present) the index it would have been inserted into xor'd\n\t * with `failureXor`. Note that negating is not an adequate solution as that could result in -0.\n\t */\n\tpublic static keyIndexOf<T, K, V>(\n\t\telements: readonly (K | V)[],\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number,\n\t): number {\n\t\t// Low, high, and mid are addresses of [K,V] pairs and *not* key indices\n\t\tlet low = 0;\n\t\tlet high = elements.length / 2;\n\t\tlet mid = high >> 1;\n\t\twhile (low < high) {\n\t\t\tconst keyIndex = mid * 2;\n\t\t\tconst c = comparator(search, elements[keyIndex] as K, elements[keyIndex + 1] as V);\n\t\t\tif (c > 0) {\n\t\t\t\tlow = mid + 1;\n\t\t\t} else if (c < 0) {\n\t\t\t\thigh = mid;\n\t\t\t} else if (c === 0) {\n\t\t\t\treturn keyIndex;\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Invalid comparator.\");\n\t\t\t}\n\t\t\tmid = (low + high) >> 1;\n\t\t}\n\t\treturn (mid * 2) ^ AppendOnlySortedMap.failureXor;\n\t}\n}\n"]}
|
package/lib/finalSpace.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"finalSpace.d.mts","sourceRoot":"","sources":["../src/finalSpace.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAGI,EAAE,SAAS,EAAyD;OACpE,EAAE,iBAAiB,EAAE;AAE5B;;;;GAIG;AACH,qBAAa,UAAU;IACtB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmB;IAE/C,IAAW,QAAQ,IAAI,SAAS,SAAS,EAAE,CAE1C;IAEM,cAAc,IAAI,SAAS,GAAG,SAAS;IAIvC,UAAU,CAAC,UAAU,EAAE,SAAS;IAWvC;;;OAGG;IACI,mBAAmB,IAAI,iBAAiB;IAO/C;;;OAGG;IACI,mBAAmB,IAAI,iBAAiB;IAOxC,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO;CAQzC"}
|
package/lib/finalSpace.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"finalSpace.mjs","sourceRoot":"","sources":["../src/finalSpace.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAEI,EAAE,MAAM,EAAE,MAAM,4BAA4B;OAC5C,EAAa,aAAa,EAAE,kBAAkB,EAAE,kBAAkB,EAAE;AAG3E;;;;GAIG;AACH,MAAM,OAAO,UAAU;IAAvB;QACkB,gBAAW,GAAgB,EAAE,CAAC;IAmDhD,CAAC;IAjDA,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAEM,cAAc;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC;IAEM,UAAU,CAAC,UAAqB;QACtC,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,MAAM,CACL,WAAW,KAAK,SAAS;YACxB,qEAAqE;YACrE,UAAU,CAAC,WAAW,KAAK,WAAW,CAAC,WAAW,GAAG,WAAW,CAAC,QAAQ,EAC1E,KAAK,CAAC,oDAAoD,CAC1D,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAED;;;OAGG;IACI,mBAAmB;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,OAAO,WAAW,KAAK,SAAS;YAC/B,CAAC,CAAE,CAAuB;YAC1B,CAAC,CAAE,CAAE,kBAAkB,CAAC,WAAW,CAAY,GAAG,CAAC,CAAuB,CAAC;IAC7E,CAAC;IAED;;;OAGG;IACI,mBAAmB;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,OAAO,WAAW,KAAK,SAAS;YAC/B,CAAC,CAAE,CAAuB;YAC1B,CAAC,CAAE,CAAE,kBAAkB,CAAC,WAAW,CAAY,GAAG,CAAC,CAAuB,CAAC;IAC7E,CAAC;IAEM,MAAM,CAAC,KAAiB;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACjD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE;gBAC9D,OAAO,KAAK,CAAC;aACb;SACD;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;IAC7D,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IdCluster, clustersEqual, lastAllocatedFinal, lastFinalizedFinal } from \"./sessions\";\nimport { FinalCompressedId } from \"./identifiers\";\n\n/**\n * All IDs that have been finalized (acked), grouped into clusters sorted by their base final IDs.\n * These clusters span the positive integer space and are not sparse, meaning a cluster's base final\n * ID will always be one greater than the last final ID in the previous cluster (or 0 if there is not one).\n */\nexport class FinalSpace {\n\tprivate readonly clusterList: IdCluster[] = [];\n\n\tpublic get clusters(): readonly IdCluster[] {\n\t\treturn this.clusterList;\n\t}\n\n\tpublic getLastCluster(): IdCluster | undefined {\n\t\treturn this.clusterList[this.clusterList.length - 1];\n\t}\n\n\tpublic addCluster(newCluster: IdCluster) {\n\t\tconst lastCluster = this.getLastCluster();\n\t\tassert(\n\t\t\tlastCluster === undefined ||\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n\t\t\t\tnewCluster.baseFinalId === lastCluster.baseFinalId + lastCluster.capacity,\n\t\t\t0x753 /* Cluster insert to final_space is out of order. */,\n\t\t);\n\t\tthis.clusterList.push(newCluster);\n\t}\n\n\t/**\n\t * @returns the upper bound (exclusive) of finalized IDs in final space, i.e. one greater than the last final ID in the last cluster.\n\t * Note: this does not include allocated but unfinalized space in clusters.\n\t */\n\tpublic getFinalizedIdLimit(): FinalCompressedId {\n\t\tconst lastCluster = this.getLastCluster();\n\t\treturn lastCluster === undefined\n\t\t\t? (0 as FinalCompressedId)\n\t\t\t: (((lastFinalizedFinal(lastCluster) as number) + 1) as FinalCompressedId);\n\t}\n\n\t/**\n\t * @returns the upper bound (exclusive) of allocated IDs in final space, i.e. one greater than the last final ID in the last cluster.\n\t * Note: this does includes all allocated IDs in clusters.\n\t */\n\tpublic getAllocatedIdLimit(): FinalCompressedId {\n\t\tconst lastCluster = this.getLastCluster();\n\t\treturn lastCluster === undefined\n\t\t\t? (0 as FinalCompressedId)\n\t\t\t: (((lastAllocatedFinal(lastCluster) as number) + 1) as FinalCompressedId);\n\t}\n\n\tpublic equals(other: FinalSpace): boolean {\n\t\tfor (let i = 0; i < this.clusterList.length; i++) {\n\t\t\tif (!clustersEqual(this.clusterList[i], other.clusterList[i])) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn this.clusterList.length === other.clusterList.length;\n\t}\n}\n"]}
|