import { onCleanup } from "solid-js" export type ShellOption = { path: string name: string acceptable: boolean } export type ShellSelectOption = { id: string value: string name: string terminalOnly: boolean } export function createShellOptions(input: { shells: ShellOption[]; current: string | undefined }) { const counts = input.shells.reduce((result, shell) => { result.set(shell.name, (result.get(shell.name) ?? 0) + 1) return result }, new Map()) const options: ShellSelectOption[] = [ { id: "auto", value: "", name: "", terminalOnly: false }, ...input.shells.map((shell) => { const ambiguous = (counts.get(shell.name) ?? 0) > 1 const name = ambiguous ? shell.path : shell.name return { id: shell.path, value: ambiguous ? shell.path : shell.name, name, terminalOnly: !shell.acceptable, } }), ] if (input.current && !options.some((option) => option.value === input.current)) { options.push({ id: input.current, value: input.current, name: input.current, terminalOnly: false }) } return options } export function createSoundPreviewController(player: (id: string | undefined) => Promise<(() => void) | undefined>) { let cleanup: (() => void) | undefined let timeout: ReturnType | undefined let run = 0 const stop = () => { run += 1 cleanup?.() clearTimeout(timeout) cleanup = undefined timeout = undefined } const play = (id: string | undefined) => { stop() if (!id) return const current = ++run timeout = setTimeout(() => { timeout = undefined void player(id).then((next) => { if (run === current) { cleanup = next return } next?.() }) }, 100) } onCleanup(stop) return { play, stop } }