Skip to content

Commit e5eaeda

Browse files
committed
Add LegacyAdapters.sortStable()
1 parent c9d9366 commit e5eaeda

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

libraries/node-core-library/src/LegacyAdapters.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22
// See LICENSE in the project root for license information.
33

4+
import { sort as timsort } from 'timsort';
5+
import * as semver from 'semver';
6+
47
/**
58
* Callback used by {@link LegacyAdapters}.
69
* @public
@@ -12,6 +15,8 @@ export type LegacyCallback<TResult, TError> = (error: TError, result: TResult) =
1215
* @public
1316
*/
1417
export class LegacyAdapters {
18+
private static _useTimsort: boolean | undefined = undefined;
19+
1520
/**
1621
* This function wraps a function with a callback in a promise.
1722
*/
@@ -94,4 +99,23 @@ export class LegacyAdapters {
9499
return errorObject;
95100
}
96101
}
102+
103+
/**
104+
* Prior to Node 11.x, the `Array.sort()` algorithm is not guaranteed to be stable.
105+
* If you need a stable sort, you can use the `sortStable()` as a workaround.
106+
*
107+
* @remarks
108+
* On NodeJS 11.x and later, this method simply calls the native `Array.sort()`.
109+
* For earlier versions, it uses an implementation of Timsort, which is the same algorithm used by modern NodeJS.
110+
*/
111+
public static sortStable<T>(array: T[], compare?: (a: T, b: T) => number): void {
112+
if (LegacyAdapters._useTimsort === undefined) {
113+
LegacyAdapters._useTimsort = semver.major(process.versions.node) < 11;
114+
}
115+
if (LegacyAdapters._useTimsort) {
116+
timsort(array, compare);
117+
} else {
118+
Array.prototype.sort.call(array, compare);
119+
}
120+
}
97121
}

0 commit comments

Comments
 (0)