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 */
1417export 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