import { BreadcrumbEntry, TaxonomyLevel, TaxonomyNode, TaxonomySearchResult } from '../types'; export declare enum FailedOp { Browse = "browse", BrowseMore = "browse-more", Search = "search", SearchMore = "search-more" } export declare enum PickerActionType { /** Initial fetch for the current level started — shows the skeleton. */ FetchStart = "FETCH_START", /** Initial fetch succeeded; carries `forParentId` so stale responses can be dropped. */ FetchSuccess = "FETCH_SUCCESS", /** Initial fetch failed; sets `lastFailedOp = 'browse'` so retry knows what to re-run. */ FetchError = "FETCH_ERROR", /** User navigated deeper into a node — atomically transitions to a new level. */ DrillDown = "DRILL_DOWN", /** User navigated back to a level whose snapshot is still cached — no skeleton. */ NavigateBack = "NAVIGATE_BACK", /** User navigated back to a level whose cache was evicted — re-fetch with skeleton. */ NavigateBackRefetch = "NAVIGATE_BACK_REFETCH", /** Hard reset to `initialState` (e.g. popover closed). */ Reset = "RESET", /** "Load more" page fetch for the current browse list started. */ LoadMoreStart = "LOAD_MORE_START", /** "Load more" page appended to `items`; advances `itemsNextMarker`. */ LoadMoreSuccess = "LOAD_MORE_SUCCESS", /** * "Load more" page failed; sets `loadMoreError` so the inline error row is shown, * and `lastFailedOp = 'browse-more'` so retry knows what to re-run from the * current marker. */ LoadMoreError = "LOAD_MORE_ERROR", /** Search input changed — updates the raw `searchInputValue` on every keystroke. */ SearchInputChange = "SEARCH_INPUT_CHANGE", /** Debounced search committed — promotes `searchInputValue` to `searchQuery` and fires the request. */ SearchFetchStart = "SEARCH_FETCH_START", /** Search results arrived; carries `forQuery` so stale responses can be dropped. */ SearchFetchSuccess = "SEARCH_FETCH_SUCCESS", /** Search request failed; sets `lastFailedOp = 'search'`. */ SearchFetchError = "SEARCH_FETCH_ERROR", /** Search input cleared — wipes the search slice and returns to the browse view. */ SearchClear = "SEARCH_CLEAR", /** "Load more" page fetch for the current search results started. */ SearchLoadMoreStart = "SEARCH_LOAD_MORE_START", /** "Load more" page appended to `searchResults`; advances `searchNextMarker`. */ SearchLoadMoreSuccess = "SEARCH_LOAD_MORE_SUCCESS", /** * "Load more" page for search failed; sets `searchLoadMoreError` so the inline * error row is shown and `lastFailedOp = 'search-more'` so retry re-runs the * load-more from the current marker against the active query. */ SearchLoadMoreError = "SEARCH_LOAD_MORE_ERROR", /** User picked a level filter for the global (root-level) search. */ SetLevelFilter = "SET_LEVEL_FILTER" } export type PickerAction = { type: PickerActionType.FetchStart; } | { type: PickerActionType.FetchSuccess; entries: TaxonomyNode[]; nextMarker: string | undefined; forParentId: string | null; } | { type: PickerActionType.FetchError; error: string; forParentId: string | null; } | { type: PickerActionType.DrillDown; targetParentId: string; levelStack: BreadcrumbEntry[]; } | { type: PickerActionType.NavigateBack; targetParentId: string | null; levelStack: BreadcrumbEntry[]; cached: { items: TaxonomyNode[]; nextMarker: string | undefined; }; } | { type: PickerActionType.NavigateBackRefetch; targetParentId: string | null; levelStack: BreadcrumbEntry[]; } | { type: PickerActionType.Reset; } | { type: PickerActionType.LoadMoreStart; } | { type: PickerActionType.LoadMoreSuccess; entries: TaxonomyNode[]; nextMarker: string | undefined; } | { type: PickerActionType.LoadMoreError; error: string; } | { type: PickerActionType.SearchInputChange; value: string; availableLevels: readonly TaxonomyLevel[]; } | { type: PickerActionType.SearchFetchStart; query: string; } | { type: PickerActionType.SearchFetchSuccess; results: TaxonomySearchResult[]; nextMarker: string | undefined; forQuery: string; } | { type: PickerActionType.SearchFetchError; error: string; } | { type: PickerActionType.SearchClear; } | { type: PickerActionType.SearchLoadMoreStart; } | { type: PickerActionType.SearchLoadMoreSuccess; entries: TaxonomySearchResult[]; nextMarker: string | undefined; forQuery: string; } | { type: PickerActionType.SearchLoadMoreError; error: string; forQuery: string; } | { type: PickerActionType.SetLevelFilter; level: number | null; }; export interface PickerState { /** Breadcrumb trail of ancestors leading to `currentParentId`; empty at root. */ levelStack: BreadcrumbEntry[]; /** Parent node currently being browsed; `null` is the root level. */ currentParentId: string | null; /** Children of `currentParentId` rendered in the browse list. */ items: TaxonomyNode[]; /** Pagination cursor for the next `items` page; `undefined` when no more pages. */ itemsNextMarker: string | undefined; /** Initial fetch for the current level is in flight — drives the skeleton. */ isFetching: boolean; /** "Load more" page for the current level is in flight — drives the inline spinner. */ isFetchingMore: boolean; /** Initial fetch error for the current level; mutually exclusive with `items`. */ initialLoadError: string | null; /** * "Load more" page error for the current level. When set, an inline error row * is rendered at the bottom of the existing list (already-loaded items remain * visible). Cleared when a retry begins or the level changes. */ loadMoreError: string | null; /** Raw search input value — updated on every keystroke (pre-debounce). */ searchInputValue: string; /** Debounced/committed query the active search request was fired against; used to race-guard `SearchFetchSuccess`. */ searchQuery: string; /** Results for the active `searchQuery`. */ searchResults: TaxonomySearchResult[]; /** Pagination cursor for the next `searchResults` page. */ searchNextMarker: string | undefined; /** Initial search fetch is in flight. */ isFetchingSearch: boolean; /** "Load more" page for search results is in flight. */ isFetchingSearchMore: boolean; /** Initial search request error; mutually exclusive with `searchResults`. */ searchError: string | null; /** * "Load more" page error for the active search query. When set, an inline * error row is rendered at the bottom of the search results list. Cleared * when a retry begins or the search query changes / clears. */ searchLoadMoreError: string | null; /** Optional level filter applied to the global (root-level) search; `null` means "all levels". */ levelFilter: number | null; /** Levels available in the current taxonomy (drives the level-filter dropdown and single-level scoping). */ availableLevels: TaxonomyLevel[]; /** * Which operation failed most recently, so `retry()` knows which one to re-run * without having to infer it from other state. Cleared on success or when a * new operation begins. Covers all four failure cases: initial browse, browse * load-more, initial search, and search load-more. */ lastFailedOp: FailedOp | null; } export declare const initialState: PickerState; export declare function pickerReducer(state: PickerState, action: PickerAction): PickerState;