export type DropPlacement = "before" | "after"; /** Devuelve un orden nuevo o ausencia de cambio; nunca modifica la colección recibida. */ export function reorderItems( items: readonly T[], sourceIndex: number, targetIndex: number, placement: DropPlacement ): T[] | undefined { if ( !(Number.isInteger(sourceIndex) && Number.isInteger(targetIndex)) || sourceIndex < 0 || targetIndex < 0 || sourceIndex >= items.length || targetIndex >= items.length ) { return undefined; } const insertionIndex = targetIndex + (placement === "after" ? 1 : 0); const destination = insertionIndex - (sourceIndex < insertionIndex ? 1 : 0); if (sourceIndex === destination) { return undefined; } const next = [...items]; const removed = next.splice(sourceIndex, 1); next.splice(destination, 0, ...removed); return next; }