@atlaspack/build-cache 2.13.7-dev-swc44-53cdb819f.0 → 2.13.8
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 +18 -0
- package/dist/LargeMap.js +59 -0
- package/dist/serializer.js +10 -2
- package/lib/LargeMap.js +63 -0
- package/lib/serializer.js +12 -2
- package/lib/types/LargeMap.d.ts +19 -0
- package/package.json +4 -2
- package/src/LargeMap.ts +67 -0
- package/src/serializer.ts +17 -2
- package/test/LargeMap.test.ts +151 -0
- package/tsconfig.json +6 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/LICENSE +0 -201
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @atlaspack/build-cache
|
|
2
2
|
|
|
3
|
+
## 2.13.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`f33f9c4`](https://github.com/atlassian-labs/atlaspack/commit/f33f9c48dd24b319df352d197e4a83cbb1b053bc), [`e15fb6c`](https://github.com/atlassian-labs/atlaspack/commit/e15fb6c885c6354c6c02283de35ce18abc8c9e18)]:
|
|
8
|
+
- @atlaspack/feature-flags@2.27.7
|
|
9
|
+
|
|
10
|
+
## 2.13.7
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- [#960](https://github.com/atlassian-labs/atlaspack/pull/960) [`565bab3`](https://github.com/atlassian-labs/atlaspack/commit/565bab3771cc334659d873cabff4cdfac0860cc7) Thanks [@mattcompiles](https://github.com/mattcompiles)! - Add LargeMap to work around Node 24's Map size limit in build cache serializer.
|
|
15
|
+
|
|
16
|
+
This change is behind the `useLargeMapInBuildCache` feature flag.
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [[`c31090c`](https://github.com/atlassian-labs/atlaspack/commit/c31090c9025f35d3fa8561b42dca170853a32e6f), [`565bab3`](https://github.com/atlassian-labs/atlaspack/commit/565bab3771cc334659d873cabff4cdfac0860cc7)]:
|
|
19
|
+
- @atlaspack/feature-flags@2.27.6
|
|
20
|
+
|
|
3
21
|
## 2.13.6
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/LargeMap.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LargeMap = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A Map implementation that can exceed Node 24's Map size limit.
|
|
6
|
+
*
|
|
7
|
+
* LargeMap works around the Maximum maps size limit by using multiple internal Maps,
|
|
8
|
+
* creating a new one when the current Map reaches the size limit.
|
|
9
|
+
*
|
|
10
|
+
* This is a minimal implementation supporting only has/get/set - intended as a
|
|
11
|
+
* temporary solution until we no longer need large JS serialization
|
|
12
|
+
*/
|
|
13
|
+
class LargeMap {
|
|
14
|
+
constructor(maxSize = Math.pow(2, 23)) {
|
|
15
|
+
this.lastMap = new Map();
|
|
16
|
+
this.maps = [this.lastMap];
|
|
17
|
+
this.singleMap = true;
|
|
18
|
+
this.maxSize = maxSize;
|
|
19
|
+
}
|
|
20
|
+
set(key, value) {
|
|
21
|
+
// Update existing key if found
|
|
22
|
+
if (!this.singleMap) {
|
|
23
|
+
for (let map of this.maps) {
|
|
24
|
+
if (map.has(key)) {
|
|
25
|
+
map.set(key, value);
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Otherwise, add to last map
|
|
31
|
+
if (this.lastMap.size >= this.maxSize) {
|
|
32
|
+
this.lastMap = new Map();
|
|
33
|
+
this.maps.push(this.lastMap);
|
|
34
|
+
this.singleMap = false;
|
|
35
|
+
}
|
|
36
|
+
this.lastMap.set(key, value);
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
get(key) {
|
|
40
|
+
if (this.singleMap) {
|
|
41
|
+
return this.lastMap.get(key);
|
|
42
|
+
}
|
|
43
|
+
for (let map of this.maps) {
|
|
44
|
+
if (map.has(key)) {
|
|
45
|
+
return map.get(key);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
has(key) {
|
|
51
|
+
for (let map of this.maps) {
|
|
52
|
+
if (map.has(key)) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.LargeMap = LargeMap;
|
package/dist/serializer.js
CHANGED
|
@@ -10,7 +10,9 @@ exports.deserialize = deserialize;
|
|
|
10
10
|
exports.cacheSerializedObject = cacheSerializedObject;
|
|
11
11
|
exports.deserializeToCache = deserializeToCache;
|
|
12
12
|
exports.removeSerializedObjectFromCache = removeSerializedObjectFromCache;
|
|
13
|
+
const feature_flags_1 = require("@atlaspack/feature-flags");
|
|
13
14
|
const buildCache_1 = require("./buildCache");
|
|
15
|
+
const LargeMap_1 = require("./LargeMap");
|
|
14
16
|
const serializerCore_1 = require("./serializerCore");
|
|
15
17
|
var serializerCore_2 = require("./serializerCore");
|
|
16
18
|
Object.defineProperty(exports, "serializeRaw", { enumerable: true, get: function () { return serializerCore_2.serializeRaw; } });
|
|
@@ -57,8 +59,14 @@ function shouldContinueMapping(value) {
|
|
|
57
59
|
return value && typeof value === 'object' && value.$$raw !== true;
|
|
58
60
|
}
|
|
59
61
|
function mapObject(object, fn, preOrder = false) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
// Use LargeMap to work around Node 24's Map size limit
|
|
63
|
+
// when the feature flag is enabled
|
|
64
|
+
let cache = (0, feature_flags_1.getFeatureFlag)('useLargeMapInBuildCache')
|
|
65
|
+
? new LargeMap_1.LargeMap()
|
|
66
|
+
: new Map();
|
|
67
|
+
let memo = (0, feature_flags_1.getFeatureFlag)('useLargeMapInBuildCache')
|
|
68
|
+
? new LargeMap_1.LargeMap()
|
|
69
|
+
: new Map();
|
|
62
70
|
// Memoize the passed function to ensure it always returns the exact same
|
|
63
71
|
// output by reference for the same input. This is important to maintain
|
|
64
72
|
// reference integrity when deserializing rather than cloning.
|
package/lib/LargeMap.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.LargeMap = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* A Map implementation that can exceed Node 24's Map size limit.
|
|
9
|
+
*
|
|
10
|
+
* LargeMap works around the Maximum maps size limit by using multiple internal Maps,
|
|
11
|
+
* creating a new one when the current Map reaches the size limit.
|
|
12
|
+
*
|
|
13
|
+
* This is a minimal implementation supporting only has/get/set - intended as a
|
|
14
|
+
* temporary solution until we no longer need large JS serialization
|
|
15
|
+
*/
|
|
16
|
+
class LargeMap {
|
|
17
|
+
constructor(maxSize = Math.pow(2, 23)) {
|
|
18
|
+
this.lastMap = new Map();
|
|
19
|
+
this.maps = [this.lastMap];
|
|
20
|
+
this.singleMap = true;
|
|
21
|
+
this.maxSize = maxSize;
|
|
22
|
+
}
|
|
23
|
+
set(key, value) {
|
|
24
|
+
// Update existing key if found
|
|
25
|
+
if (!this.singleMap) {
|
|
26
|
+
for (let map of this.maps) {
|
|
27
|
+
if (map.has(key)) {
|
|
28
|
+
map.set(key, value);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Otherwise, add to last map
|
|
35
|
+
if (this.lastMap.size >= this.maxSize) {
|
|
36
|
+
this.lastMap = new Map();
|
|
37
|
+
this.maps.push(this.lastMap);
|
|
38
|
+
this.singleMap = false;
|
|
39
|
+
}
|
|
40
|
+
this.lastMap.set(key, value);
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
get(key) {
|
|
44
|
+
if (this.singleMap) {
|
|
45
|
+
return this.lastMap.get(key);
|
|
46
|
+
}
|
|
47
|
+
for (let map of this.maps) {
|
|
48
|
+
if (map.has(key)) {
|
|
49
|
+
return map.get(key);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
has(key) {
|
|
55
|
+
for (let map of this.maps) {
|
|
56
|
+
if (map.has(key)) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.LargeMap = LargeMap;
|
package/lib/serializer.js
CHANGED
|
@@ -24,7 +24,15 @@ Object.defineProperty(exports, "serializeRaw", {
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
exports.unregisterSerializableClass = unregisterSerializableClass;
|
|
27
|
+
function _featureFlags() {
|
|
28
|
+
const data = require("@atlaspack/feature-flags");
|
|
29
|
+
_featureFlags = function () {
|
|
30
|
+
return data;
|
|
31
|
+
};
|
|
32
|
+
return data;
|
|
33
|
+
}
|
|
27
34
|
var _buildCache = require("./buildCache");
|
|
35
|
+
var _LargeMap = require("./LargeMap");
|
|
28
36
|
var _serializerCore = require("./serializerCore");
|
|
29
37
|
// flow-to-ts helpers
|
|
30
38
|
|
|
@@ -69,8 +77,10 @@ function shouldContinueMapping(value) {
|
|
|
69
77
|
return value && typeof value === 'object' && value.$$raw !== true;
|
|
70
78
|
}
|
|
71
79
|
function mapObject(object, fn, preOrder = false) {
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
// Use LargeMap to work around Node 24's Map size limit
|
|
81
|
+
// when the feature flag is enabled
|
|
82
|
+
let cache = (0, _featureFlags().getFeatureFlag)('useLargeMapInBuildCache') ? new _LargeMap.LargeMap() : new Map();
|
|
83
|
+
let memo = (0, _featureFlags().getFeatureFlag)('useLargeMapInBuildCache') ? new _LargeMap.LargeMap() : new Map();
|
|
74
84
|
|
|
75
85
|
// Memoize the passed function to ensure it always returns the exact same
|
|
76
86
|
// output by reference for the same input. This is important to maintain
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Map implementation that can exceed Node 24's Map size limit.
|
|
3
|
+
*
|
|
4
|
+
* LargeMap works around the Maximum maps size limit by using multiple internal Maps,
|
|
5
|
+
* creating a new one when the current Map reaches the size limit.
|
|
6
|
+
*
|
|
7
|
+
* This is a minimal implementation supporting only has/get/set - intended as a
|
|
8
|
+
* temporary solution until we no longer need large JS serialization
|
|
9
|
+
*/
|
|
10
|
+
export declare class LargeMap<K, V> {
|
|
11
|
+
maps: Map<K, V>[];
|
|
12
|
+
maxSize: number;
|
|
13
|
+
singleMap: boolean;
|
|
14
|
+
lastMap: Map<K, V>;
|
|
15
|
+
constructor(maxSize?: number);
|
|
16
|
+
set(key: K, value: V): this;
|
|
17
|
+
get(key: K): V | undefined;
|
|
18
|
+
has(key: K): boolean;
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/build-cache",
|
|
3
3
|
"description": "Serialize and deserialize data structures to a build cache",
|
|
4
|
-
"version": "2.13.
|
|
4
|
+
"version": "2.13.8",
|
|
5
5
|
"license": "(MIT OR Apache-2.0)",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"publishConfig": {
|
|
@@ -20,5 +20,7 @@
|
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build:lib": "gulp build --gulpfile ../../../gulpfile.js --cwd ."
|
|
22
22
|
},
|
|
23
|
-
"
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@atlaspack/feature-flags": "2.27.7"
|
|
25
|
+
}
|
|
24
26
|
}
|
package/src/LargeMap.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Map implementation that can exceed Node 24's Map size limit.
|
|
3
|
+
*
|
|
4
|
+
* LargeMap works around the Maximum maps size limit by using multiple internal Maps,
|
|
5
|
+
* creating a new one when the current Map reaches the size limit.
|
|
6
|
+
*
|
|
7
|
+
* This is a minimal implementation supporting only has/get/set - intended as a
|
|
8
|
+
* temporary solution until we no longer need large JS serialization
|
|
9
|
+
*/
|
|
10
|
+
export class LargeMap<K, V> {
|
|
11
|
+
maps: Map<K, V>[];
|
|
12
|
+
maxSize: number;
|
|
13
|
+
singleMap: boolean;
|
|
14
|
+
lastMap: Map<K, V>;
|
|
15
|
+
|
|
16
|
+
constructor(maxSize: number = Math.pow(2, 23)) {
|
|
17
|
+
this.lastMap = new Map();
|
|
18
|
+
this.maps = [this.lastMap];
|
|
19
|
+
this.singleMap = true;
|
|
20
|
+
this.maxSize = maxSize;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
set(key: K, value: V): this {
|
|
24
|
+
// Update existing key if found
|
|
25
|
+
if (!this.singleMap) {
|
|
26
|
+
for (let map of this.maps) {
|
|
27
|
+
if (map.has(key)) {
|
|
28
|
+
map.set(key, value);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Otherwise, add to last map
|
|
35
|
+
if (this.lastMap.size >= this.maxSize) {
|
|
36
|
+
this.lastMap = new Map();
|
|
37
|
+
this.maps.push(this.lastMap);
|
|
38
|
+
this.singleMap = false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.lastMap.set(key, value);
|
|
42
|
+
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get(key: K): V | undefined {
|
|
47
|
+
if (this.singleMap) {
|
|
48
|
+
return this.lastMap.get(key);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
for (let map of this.maps) {
|
|
52
|
+
if (map.has(key)) {
|
|
53
|
+
return map.get(key);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
has(key: K): boolean {
|
|
60
|
+
for (let map of this.maps) {
|
|
61
|
+
if (map.has(key)) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
package/src/serializer.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import {getFeatureFlag} from '@atlaspack/feature-flags';
|
|
2
|
+
|
|
1
3
|
import {createBuildCache} from './buildCache';
|
|
4
|
+
import {LargeMap} from './LargeMap';
|
|
2
5
|
import {serializeRaw, deserializeRaw} from './serializerCore';
|
|
3
6
|
|
|
4
7
|
export {serializeRaw, deserializeRaw} from './serializerCore';
|
|
@@ -64,9 +67,21 @@ function shouldContinueMapping(value: any) {
|
|
|
64
67
|
return value && typeof value === 'object' && value.$$raw !== true;
|
|
65
68
|
}
|
|
66
69
|
|
|
70
|
+
interface MapLike<K, V> {
|
|
71
|
+
get(key: K): V | undefined;
|
|
72
|
+
set(key: K, value: V): unknown;
|
|
73
|
+
has(key: K): boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
67
76
|
function mapObject(object: any, fn: (val?: any) => any, preOrder = false): any {
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
// Use LargeMap to work around Node 24's Map size limit
|
|
78
|
+
// when the feature flag is enabled
|
|
79
|
+
let cache: MapLike<any, any> = getFeatureFlag('useLargeMapInBuildCache')
|
|
80
|
+
? new LargeMap<any, any>()
|
|
81
|
+
: new Map<any, any>();
|
|
82
|
+
let memo: MapLike<any, any> = getFeatureFlag('useLargeMapInBuildCache')
|
|
83
|
+
? new LargeMap<any, any>()
|
|
84
|
+
: new Map<any, any>();
|
|
70
85
|
|
|
71
86
|
// Memoize the passed function to ensure it always returns the exact same
|
|
72
87
|
// output by reference for the same input. This is important to maintain
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import assert from 'assert';
|
|
2
|
+
import {LargeMap} from '../src/LargeMap';
|
|
3
|
+
|
|
4
|
+
describe('LargeMap', () => {
|
|
5
|
+
describe('basic operations', () => {
|
|
6
|
+
it('should set and get values', () => {
|
|
7
|
+
const map = new LargeMap<string, number>();
|
|
8
|
+
map.set('a', 1);
|
|
9
|
+
map.set('b', 2);
|
|
10
|
+
|
|
11
|
+
assert.equal(map.get('a'), 1);
|
|
12
|
+
assert.equal(map.get('b'), 2);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should return undefined for missing keys', () => {
|
|
16
|
+
const map = new LargeMap<string, number>();
|
|
17
|
+
assert.equal(map.get('missing'), undefined);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should check if key exists with has()', () => {
|
|
21
|
+
const map = new LargeMap<string, number>();
|
|
22
|
+
map.set('a', 1);
|
|
23
|
+
|
|
24
|
+
assert.equal(map.has('a'), true);
|
|
25
|
+
assert.equal(map.has('b'), false);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should update existing key in single map', () => {
|
|
29
|
+
const map = new LargeMap<string, number>();
|
|
30
|
+
map.set('a', 1);
|
|
31
|
+
map.set('a', 2);
|
|
32
|
+
|
|
33
|
+
assert.equal(map.get('a'), 2);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should return this from set() for chaining', () => {
|
|
37
|
+
const map = new LargeMap<string, number>();
|
|
38
|
+
const result = map.set('a', 1).set('b', 2).set('c', 3);
|
|
39
|
+
|
|
40
|
+
assert.equal(result, map);
|
|
41
|
+
assert.equal(map.get('a'), 1);
|
|
42
|
+
assert.equal(map.get('b'), 2);
|
|
43
|
+
assert.equal(map.get('c'), 3);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('multiple internal maps', () => {
|
|
48
|
+
it('should create new internal map when maxSize is reached', () => {
|
|
49
|
+
const map = new LargeMap<number, number>(3); // Small maxSize for testing
|
|
50
|
+
|
|
51
|
+
map.set(1, 1);
|
|
52
|
+
map.set(2, 2);
|
|
53
|
+
map.set(3, 3);
|
|
54
|
+
assert.equal(map.maps.length, 1);
|
|
55
|
+
|
|
56
|
+
map.set(4, 4); // Should trigger new internal map
|
|
57
|
+
assert.equal(map.maps.length, 2);
|
|
58
|
+
|
|
59
|
+
map.set(5, 5);
|
|
60
|
+
map.set(6, 6);
|
|
61
|
+
assert.equal(map.maps.length, 2);
|
|
62
|
+
|
|
63
|
+
map.set(7, 7); // Should trigger another new internal map
|
|
64
|
+
assert.equal(map.maps.length, 3);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should find values across multiple internal maps', () => {
|
|
68
|
+
const map = new LargeMap<number, string>(2);
|
|
69
|
+
|
|
70
|
+
map.set(1, 'one');
|
|
71
|
+
map.set(2, 'two');
|
|
72
|
+
map.set(3, 'three');
|
|
73
|
+
map.set(4, 'four');
|
|
74
|
+
map.set(5, 'five');
|
|
75
|
+
|
|
76
|
+
assert.equal(map.get(1), 'one');
|
|
77
|
+
assert.equal(map.get(2), 'two');
|
|
78
|
+
assert.equal(map.get(3), 'three');
|
|
79
|
+
assert.equal(map.get(4), 'four');
|
|
80
|
+
assert.equal(map.get(5), 'five');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should check has() across multiple internal maps', () => {
|
|
84
|
+
const map = new LargeMap<number, string>(2);
|
|
85
|
+
|
|
86
|
+
map.set(1, 'one');
|
|
87
|
+
map.set(2, 'two');
|
|
88
|
+
map.set(3, 'three');
|
|
89
|
+
|
|
90
|
+
assert.equal(map.has(1), true);
|
|
91
|
+
assert.equal(map.has(2), true);
|
|
92
|
+
assert.equal(map.has(3), true);
|
|
93
|
+
assert.equal(map.has(4), false);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should update existing key in earlier internal map', () => {
|
|
97
|
+
const map = new LargeMap<number, string>(2);
|
|
98
|
+
|
|
99
|
+
map.set(1, 'one');
|
|
100
|
+
map.set(2, 'two');
|
|
101
|
+
map.set(3, 'three'); // Goes to second map
|
|
102
|
+
|
|
103
|
+
// Update key in first map
|
|
104
|
+
map.set(1, 'ONE');
|
|
105
|
+
|
|
106
|
+
assert.equal(map.get(1), 'ONE');
|
|
107
|
+
assert.equal(map.maps.length, 2); // Should not create new map
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('type handling', () => {
|
|
112
|
+
it('should work with object keys', () => {
|
|
113
|
+
const map = new LargeMap<object, string>();
|
|
114
|
+
const key1 = {id: 1};
|
|
115
|
+
const key2 = {id: 2};
|
|
116
|
+
|
|
117
|
+
map.set(key1, 'first');
|
|
118
|
+
map.set(key2, 'second');
|
|
119
|
+
|
|
120
|
+
assert.equal(map.get(key1), 'first');
|
|
121
|
+
assert.equal(map.get(key2), 'second');
|
|
122
|
+
assert.equal(map.get({id: 1}), undefined); // Different reference
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should work with null and undefined values', () => {
|
|
126
|
+
const map = new LargeMap<string, any>();
|
|
127
|
+
|
|
128
|
+
map.set('null', null);
|
|
129
|
+
map.set('undefined', undefined);
|
|
130
|
+
|
|
131
|
+
assert.equal(map.get('null'), null);
|
|
132
|
+
assert.equal(map.get('undefined'), undefined);
|
|
133
|
+
assert.equal(map.has('null'), true);
|
|
134
|
+
assert.equal(map.has('undefined'), true);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('should work with various key types', () => {
|
|
138
|
+
const map = new LargeMap<any, string>();
|
|
139
|
+
|
|
140
|
+
map.set(1, 'number');
|
|
141
|
+
map.set('str', 'string');
|
|
142
|
+
map.set(true, 'boolean');
|
|
143
|
+
map.set(null, 'null');
|
|
144
|
+
|
|
145
|
+
assert.equal(map.get(1), 'number');
|
|
146
|
+
assert.equal(map.get('str'), 'string');
|
|
147
|
+
assert.equal(map.get(true), 'boolean');
|
|
148
|
+
assert.equal(map.get(null), 'null');
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
});
|