Skip to content

Commit b2bb350

Browse files
use private property
1 parent 883f238 commit b2bb350

File tree

5 files changed

+81
-19
lines changed

5 files changed

+81
-19
lines changed

.evergreen/run-typescript.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ echo "Typescript $($TSC -v)"
2222
echo "import * as BSON from '.'" > file.ts && node $TSC --noEmit --traceResolution file.ts | grep 'bson.d.ts' && rm file.ts
2323

2424
# check compilation
25-
rm -rf node_modules/@types/eslint # not a dependency we use, but breaks the build :(
26-
node $TSC bson.d.ts
25+
node $TSC bson.d.ts --target es2022 --module nodenext
2726

2827
if [[ $TRY_COMPILING_LIBRARY != "false" ]]; then
2928
npm run build:ts

package-lock.json

Lines changed: 11 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"tar": "^7.4.3",
5858
"ts-node": "^10.9.2",
5959
"tsd": "^0.33.0",
60+
"tslib": "^2.8.1",
6061
"typescript": "^5.8.3",
6162
"typescript-cached-transpile": "0.0.6",
6263
"uuid": "^11.1.0"

src/objectid.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import { NumberUtils } from './utils/number_utils';
77
// Unique sequence for the current process (initialized on first use)
88
let PROCESS_UNIQUE: Uint8Array | null = null;
99

10-
/** ObjectId hexString cache @internal */
11-
const __idCache = new WeakMap(); // TODO(NODE-6549): convert this to #__id private field when target updated to ES2022
12-
1310
/** @public */
1411
export interface ObjectIdLike {
1512
id: string | Uint8Array;
@@ -35,11 +32,20 @@ export class ObjectId extends BSONValue {
3532
/** @internal */
3633
private static index = Math.floor(Math.random() * 0xffffff);
3734

38-
static cacheHexString: boolean;
35+
static cacheHexString: boolean = false;
3936

4037
/** ObjectId Bytes @internal */
4138
private buffer!: Uint8Array;
4239

40+
/**
41+
* If hex string caching is enabled, contains the cached hex string. Otherwise, is null.
42+
*
43+
* Note that #hexString is populated lazily, and as a result simply checking `this.#hexString != null` is
44+
* not sufficient to determine if caching is enabled. `ObjectId.prototype.isCached()` can be used to
45+
* determine if the hex string has been cached yet for an ObjectId.
46+
*/
47+
#cachedHexString: string | null = null;
48+
4349
/** To generate a new ObjectId, use ObjectId() with no argument. */
4450
constructor();
4551
/**
@@ -107,7 +113,7 @@ export class ObjectId extends BSONValue {
107113
this.buffer = ByteUtils.fromHex(workingId);
108114
// If we are caching the hex string
109115
if (ObjectId.cacheHexString) {
110-
__idCache.set(this, workingId);
116+
this.#cachedHexString = workingId;
111117
}
112118
} else {
113119
throw new BSONError(
@@ -130,7 +136,7 @@ export class ObjectId extends BSONValue {
130136
set id(value: Uint8Array) {
131137
this.buffer = value;
132138
if (ObjectId.cacheHexString) {
133-
__idCache.set(this, ByteUtils.toHex(value));
139+
this.#cachedHexString = ByteUtils.toHex(value);
134140
}
135141
}
136142

@@ -159,15 +165,12 @@ export class ObjectId extends BSONValue {
159165

160166
/** Returns the ObjectId id as a 24 lowercase character hex string representation */
161167
toHexString(): string {
162-
if (ObjectId.cacheHexString) {
163-
const __id = __idCache.get(this);
164-
if (__id) return __id;
165-
}
168+
if (this.#cachedHexString) return this.#cachedHexString.toLowerCase();
166169

167170
const hexString = ByteUtils.toHex(this.id);
168171

169172
if (ObjectId.cacheHexString) {
170-
__idCache.set(this, hexString);
173+
this.#cachedHexString = hexString;
171174
}
172175

173176
return hexString;
@@ -365,9 +368,13 @@ export class ObjectId extends BSONValue {
365368
return new ObjectId(doc.$oid);
366369
}
367370

368-
/** @internal */
371+
/**
372+
* @internal
373+
*
374+
* used for testing
375+
*/
369376
private isCached(): boolean {
370-
return ObjectId.cacheHexString && __idCache.has(this);
377+
return ObjectId.cacheHexString && this.#cachedHexString != null;
371378
}
372379

373380
/**

test/node/object_id.test.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,55 @@ import * as util from 'util';
44
import { expect } from 'chai';
55
import { bufferFromHexArray } from './tools/utils';
66
import { isBufferOrUint8Array } from './tools/utils';
7+
import { test } from 'mocha';
78

89
describe('ObjectId', function () {
10+
describe('hex string caching does not impact deep equality', function () {
11+
const original = ObjectId.cacheHexString;
12+
before(function () {
13+
ObjectId.cacheHexString = true;
14+
});
15+
after(function () {
16+
ObjectId.cacheHexString = original;
17+
});
18+
test('no hex strings cached', function () {
19+
const id = new ObjectId();
20+
const id2 = new ObjectId(id.id);
21+
22+
// @ts-expect-error isCached() is internal
23+
expect(id.isCached()).to.be.false;
24+
// @ts-expect-error isCached() is internal
25+
expect(id2.isCached()).to.be.false;
26+
27+
expect(new ObjectId(id.id)).to.deep.equal(id);
28+
});
29+
30+
test('one id with cached hex string, one without', function () {
31+
const id = new ObjectId();
32+
const id2 = new ObjectId(id.id);
33+
id2.toHexString();
34+
35+
// @ts-expect-error isCached() is internal
36+
expect(id.isCached()).to.be.false;
37+
// @ts-expect-error isCached() is internal
38+
expect(id2.isCached()).to.be.true;
39+
40+
expect(id).to.deep.equal(id2);
41+
});
42+
43+
test('both with cached hex string', function () {
44+
const id = new ObjectId();
45+
const id2 = new ObjectId(id.toHexString());
46+
47+
// @ts-expect-error isCached() is internal
48+
expect(id.isCached()).to.be.true;
49+
// @ts-expect-error isCached() is internal
50+
expect(id2.isCached()).to.be.true;
51+
52+
expect(id).to.deep.equal(id2);
53+
});
54+
});
55+
956
describe('static createFromTime()', () => {
1057
it('creates an objectId with user defined value in the timestamp field', function () {
1158
const a = ObjectId.createFromTime(1);
@@ -265,7 +312,7 @@ describe('ObjectId', function () {
265312
let a = 'AAAAAAAAAAAAAAAAAAAAAAAA';
266313
let b = new ObjectId(a);
267314
let c = b.equals(a); // => false
268-
expect(true).to.equal(c);
315+
expect(c).to.be.true;
269316

270317
a = 'aaaaaaaaaaaaaaaaaaaaaaaa';
271318
b = new ObjectId(a);

0 commit comments

Comments
 (0)