(minCount: number, modeFilter?: HistoryMode)
| 20 | let pendingLoadModeFilter: HistoryMode | undefined; |
| 21 | |
| 22 | async function loadHistoryEntries(minCount: number, modeFilter?: HistoryMode): Promise<HistoryEntry[]> { |
| 23 | // Round up to next chunk to avoid repeated small reads |
| 24 | const target = Math.ceil(minCount / HISTORY_CHUNK_SIZE) * HISTORY_CHUNK_SIZE; |
| 25 | |
| 26 | // If a load is already pending with the same mode filter and will satisfy our needs, wait for it |
| 27 | if (pendingLoad && pendingLoadTarget >= target && pendingLoadModeFilter === modeFilter) { |
| 28 | return pendingLoad; |
| 29 | } |
| 30 | |
| 31 | // If a load is pending but won't satisfy our needs or has different filter, we need to wait for it |
| 32 | // to complete first, then start a new one (can't interrupt an ongoing read) |
| 33 | if (pendingLoad) { |
| 34 | await pendingLoad; |
| 35 | } |
| 36 | |
| 37 | // Start a new load |
| 38 | pendingLoadTarget = target; |
| 39 | pendingLoadModeFilter = modeFilter; |
| 40 | pendingLoad = (async () => { |
| 41 | const entries: HistoryEntry[] = []; |
| 42 | let loaded = 0; |
| 43 | for await (const entry of getHistory()) { |
| 44 | // If mode filter is specified, only include entries that match the mode |
| 45 | if (modeFilter) { |
| 46 | const entryMode = getModeFromInput(entry.display); |
| 47 | if (entryMode !== modeFilter) { |
| 48 | continue; |
| 49 | } |
| 50 | } |
| 51 | entries.push(entry); |
| 52 | loaded++; |
| 53 | if (loaded >= pendingLoadTarget) break; |
| 54 | } |
| 55 | return entries; |
| 56 | })(); |
| 57 | |
| 58 | try { |
| 59 | return await pendingLoad; |
| 60 | } finally { |
| 61 | pendingLoad = null; |
| 62 | pendingLoadTarget = 0; |
| 63 | pendingLoadModeFilter = undefined; |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | export function useArrowKeyHistory( |
| 68 | onSetInput: (value: string, mode: HistoryMode, pastedContents: Record<number, PastedContent>) => void, |
no test coverage detected