mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-24 19:11:44 +01:00
158 lines
5.5 KiB
JavaScript
158 lines
5.5 KiB
JavaScript
|
(function (global, factory) {
|
||
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['fast-sort'] = {}));
|
||
|
}(this, (function (exports) {
|
||
|
'use strict';
|
||
|
|
||
|
// >>> INTERFACES <<<
|
||
|
// >>> HELPERS <<<
|
||
|
var castComparer = function (comparer) { return function (a, b, order) { return comparer(a, b, order) * order; }; };
|
||
|
var throwInvalidConfigErrorIfTrue = function (condition, context) {
|
||
|
if (condition)
|
||
|
throw Error("Invalid sort config: " + context);
|
||
|
};
|
||
|
var unpackObjectSorter = function (sortByObj) {
|
||
|
var _a = sortByObj || {}, asc = _a.asc, desc = _a.desc;
|
||
|
var order = asc ? 1 : -1;
|
||
|
var sortBy = (asc || desc);
|
||
|
// Validate object config
|
||
|
throwInvalidConfigErrorIfTrue(!sortBy, 'Expected `asc` or `desc` property');
|
||
|
throwInvalidConfigErrorIfTrue(asc && desc, 'Ambiguous object with `asc` and `desc` config properties');
|
||
|
var comparer = sortByObj.comparer && castComparer(sortByObj.comparer);
|
||
|
return { order: order, sortBy: sortBy, comparer: comparer };
|
||
|
};
|
||
|
// >>> SORTERS <<<
|
||
|
var multiPropertySorterProvider = function (defaultComparer) {
|
||
|
return function multiPropertySorter(sortBy, sortByArr, depth, order, comparer, a, b) {
|
||
|
var valA;
|
||
|
var valB;
|
||
|
if (typeof sortBy === 'string') {
|
||
|
valA = a[sortBy];
|
||
|
valB = b[sortBy];
|
||
|
}
|
||
|
else if (typeof sortBy === 'function') {
|
||
|
valA = sortBy(a);
|
||
|
valB = sortBy(b);
|
||
|
}
|
||
|
else {
|
||
|
var objectSorterConfig = unpackObjectSorter(sortBy);
|
||
|
return multiPropertySorter(objectSorterConfig.sortBy, sortByArr, depth, objectSorterConfig.order, objectSorterConfig.comparer || defaultComparer, a, b);
|
||
|
}
|
||
|
var equality = comparer(valA, valB, order);
|
||
|
if ((equality === 0 || (valA == null && valB == null)) &&
|
||
|
sortByArr.length > depth) {
|
||
|
return multiPropertySorter(sortByArr[depth], sortByArr, depth + 1, order, comparer, a, b);
|
||
|
}
|
||
|
return equality;
|
||
|
};
|
||
|
};
|
||
|
function getSortStrategy(sortBy, comparer, order) {
|
||
|
// Flat array sorter
|
||
|
if (sortBy === undefined || sortBy === true) {
|
||
|
return function (a, b) { return comparer(a, b, order); };
|
||
|
}
|
||
|
// Sort list of objects by single object key
|
||
|
if (typeof sortBy === 'string') {
|
||
|
throwInvalidConfigErrorIfTrue(sortBy.includes('.'), 'String syntax not allowed for nested properties.');
|
||
|
return function (a, b) { return comparer(a[sortBy], b[sortBy], order); };
|
||
|
}
|
||
|
// Sort list of objects by single function sorter
|
||
|
if (typeof sortBy === 'function') {
|
||
|
return function (a, b) { return comparer(sortBy(a), sortBy(b), order); };
|
||
|
}
|
||
|
// Sort by multiple properties
|
||
|
if (Array.isArray(sortBy)) {
|
||
|
var multiPropSorter_1 = multiPropertySorterProvider(comparer);
|
||
|
return function (a, b) { return multiPropSorter_1(sortBy[0], sortBy, 1, order, comparer, a, b); };
|
||
|
}
|
||
|
// Unpack object config to get actual sorter strategy
|
||
|
var objectSorterConfig = unpackObjectSorter(sortBy);
|
||
|
return getSortStrategy(objectSorterConfig.sortBy, objectSorterConfig.comparer || comparer, objectSorterConfig.order);
|
||
|
}
|
||
|
var sortArray = function (order, ctx, sortBy, comparer) {
|
||
|
var _a;
|
||
|
if (!Array.isArray(ctx)) {
|
||
|
return ctx;
|
||
|
}
|
||
|
// Unwrap sortBy if array with only 1 value to get faster sort strategy
|
||
|
if (Array.isArray(sortBy) && sortBy.length < 2) {
|
||
|
_a = sortBy, sortBy = _a[0];
|
||
|
}
|
||
|
return ctx.sort(getSortStrategy(sortBy, comparer, order));
|
||
|
};
|
||
|
// >>> Public <<<
|
||
|
var createNewSortInstance = function (opts) {
|
||
|
var comparer = castComparer(opts.comparer);
|
||
|
return function (_ctx) {
|
||
|
var ctx = Array.isArray(_ctx) && !opts.inPlaceSorting
|
||
|
? _ctx.slice()
|
||
|
: _ctx;
|
||
|
return {
|
||
|
/**
|
||
|
* Sort array in ascending order.
|
||
|
* @example
|
||
|
* sort([3, 1, 4]).asc();
|
||
|
* sort(users).asc(u => u.firstName);
|
||
|
* sort(users).asc([
|
||
|
* U => u.firstName
|
||
|
* u => u.lastName,
|
||
|
* ]);
|
||
|
*/
|
||
|
asc: function (sortBy) {
|
||
|
return sortArray(1, ctx, sortBy, comparer);
|
||
|
},
|
||
|
/**
|
||
|
* Sort array in descending order.
|
||
|
* @example
|
||
|
* sort([3, 1, 4]).desc();
|
||
|
* sort(users).desc(u => u.firstName);
|
||
|
* sort(users).desc([
|
||
|
* U => u.firstName
|
||
|
* u => u.lastName,
|
||
|
* ]);
|
||
|
*/
|
||
|
desc: function (sortBy) {
|
||
|
return sortArray(-1, ctx, sortBy, comparer);
|
||
|
},
|
||
|
/**
|
||
|
* Sort array in ascending or descending order. It allows sorting on multiple props
|
||
|
* in different order for each of them.
|
||
|
* @example
|
||
|
* sort(users).by([
|
||
|
* { asc: u => u.score }
|
||
|
* { desc: u => u.age }
|
||
|
* ]);
|
||
|
*/
|
||
|
by: function (sortBy) {
|
||
|
return sortArray(1, ctx, sortBy, comparer);
|
||
|
},
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
var defaultComparer = function (a, b, order) {
|
||
|
if (a == null)
|
||
|
return order;
|
||
|
if (b == null)
|
||
|
return -order;
|
||
|
if (a < b)
|
||
|
return -1;
|
||
|
if (a === b)
|
||
|
return 0;
|
||
|
return 1;
|
||
|
};
|
||
|
var sort = createNewSortInstance({
|
||
|
comparer: defaultComparer,
|
||
|
});
|
||
|
var inPlaceSort = createNewSortInstance({
|
||
|
comparer: defaultComparer,
|
||
|
inPlaceSorting: true,
|
||
|
});
|
||
|
|
||
|
exports.createNewSortInstance = createNewSortInstance;
|
||
|
exports.inPlaceSort = inPlaceSort;
|
||
|
exports.sort = sort;
|
||
|
|
||
|
Object.defineProperty(exports, '__esModule', { value: true });
|
||
|
|
||
|
})));
|