import type { ProviderInstanceId } from "@t3tools/contracts"; import * as Arr from "effect/Array"; import * as Order from "effect/Order"; export interface ModelSlugItem { readonly slug: string; } export interface ProviderModelItem extends ModelSlugItem { readonly instanceId: ProviderInstanceId; } export function providerModelKey(instanceId: ProviderInstanceId, slug: string): string { return `${instanceId}:${slug}`; } function rankByValue(values: ReadonlyArray): ReadonlyMap { return new Map(Arr.map(values, (value, index) => [value, index] as const)); } function toSet( values: ReadonlySet | ReadonlyArray | undefined, ): ReadonlySet { return values instanceof Set ? values : new Set(values ?? []); } function byOptionalRank(rank: (item: T) => number | undefined): Order.Order { return Order.mapInput(Order.Number, (item: T) => rank(item) ?? Number.POSITIVE_INFINITY); } function byTrueFirst(predicate: (item: T) => boolean): Order.Order { return Order.mapInput(Order.flip(Order.Boolean), predicate); } export function sortModelsForProviderInstance( models: ReadonlyArray, options?: { readonly modelOrder?: ReadonlyArray; readonly favoriteModels?: ReadonlySet | ReadonlyArray; readonly groupFavorites?: boolean; }, ): T[] { const modelOrder = options?.modelOrder ?? []; const favoriteModels = toSet(options?.favoriteModels); const orderBySlug = rankByValue(modelOrder); const originalOrder = rankByValue(Arr.map(models, (model) => model.slug)); const orders: Array> = [ ...(options?.groupFavorites === true ? [byTrueFirst((model) => favoriteModels.has(model.slug))] : []), byOptionalRank((model) => orderBySlug.get(model.slug)), byOptionalRank((model) => originalOrder.get(model.slug)), ]; return Arr.sort(models, Order.combineAll(orders)); } export function sortProviderModelItems( items: ReadonlyArray, options?: { readonly favoriteModelKeys?: ReadonlySet | ReadonlyArray; readonly groupFavorites?: boolean; readonly instanceOrder?: ReadonlyArray; }, ): T[] { const favoriteModelKeys = toSet(options?.favoriteModelKeys); const instanceOrder = new Map( Arr.map(options?.instanceOrder ?? [], (instanceId, index) => [instanceId, index] as const), ); const originalOrder = rankByValue( Arr.map(items, (item) => providerModelKey(item.instanceId, item.slug)), ); const orders: Array> = [ ...(options?.groupFavorites === true ? [ byTrueFirst((item) => favoriteModelKeys.has(providerModelKey(item.instanceId, item.slug)), ), ] : []), byOptionalRank((item) => instanceOrder.get(item.instanceId)), byOptionalRank((item) => originalOrder.get(providerModelKey(item.instanceId, item.slug))), ]; return Arr.sort(items, Order.combineAll(orders)); }