UNPKG

@difizen/mana-common

Version:

80 lines (73 loc) 2.38 kB
import type { MaybeArray } from './types'; import type { MaybePromise } from '.'; export enum Priority { PRIOR = 1000, DEFAULT = 100, IDLE = -1, } export namespace Priority { export type PriorityObject<T> = { readonly priority: number; readonly value: T; }; export type GetPriority<T> = (value: T) => MaybePromise<number>; export type GetPrioritySync<T> = (value: T) => number; export function isValid<T>(p: PriorityObject<T>): boolean { return p.priority > 0; } export function compare<T>(p: PriorityObject<T>, p2: PriorityObject<T>): number { return p2.priority - p.priority; } export async function toPriorityObject<T>( rawValue: T, getPriority: GetPriority<T>, ): Promise<PriorityObject<T>>; export async function toPriorityObject<T>( rawValue: T[], getPriority: GetPriority<T>, ): Promise<PriorityObject<T>[]>; export async function toPriorityObject<T>( rawValue: MaybeArray<T>, getPriority: GetPriority<T>, ): Promise<MaybeArray<PriorityObject<T>>> { if (rawValue instanceof Array) { return Promise.all(rawValue.map((v) => toPriorityObject(v, getPriority))); } const value = rawValue; const priority = await getPriority(value); return { priority, value }; } export async function sort<T>( values: T[], getPriority: GetPriority<T>, ): Promise<PriorityObject<T>[]> { const prioritizeable = await toPriorityObject(values, getPriority); return prioritizeable.filter(isValid).sort(compare); } export function toPriorityObjectSync<T>( rawValue: T, getPriority: GetPrioritySync<T>, ): PriorityObject<T>; export function toPriorityObjectSync<T>( rawValue: T[], getPriority: GetPrioritySync<T>, ): PriorityObject<T>[]; export function toPriorityObjectSync<T>( rawValue: MaybeArray<T>, getPriority: GetPrioritySync<T>, ): MaybeArray<PriorityObject<T>> { if (rawValue instanceof Array) { return rawValue.map((v) => toPriorityObjectSync(v, getPriority)); } const value = rawValue; const priority = getPriority(value); return { priority, value }; } export function sortSync<T>( values: T[], getPriority: GetPrioritySync<T>, ): PriorityObject<T>[] { const prioritizeable = toPriorityObjectSync(values, getPriority); return prioritizeable.filter(isValid).sort(compare); } }