password_manager/src/lib/stores/search.svelte.js

46 lines
1.2 KiB
JavaScript

/**
* Search and filter state.
* Shared between Sidebar and EntryList for coordinated filtering.
*/
const DEBOUNCE_MS = 300
export class SearchStore {
query = $state('') // raw input value — bound to the search input
debouncedQuery = $state('') // debounced value — used for actual search
activeGroupId = $state('all') // 'all' or a group id
refreshTrigger = $state(0) // incremented to force a re-fetch
#debounceTimer = null
/**
* Update the search query with debouncing.
* Call this from the input handler instead of setting `query` directly.
*/
setSearchQuery(value) {
this.query = value
if (this.#debounceTimer) clearTimeout(this.#debounceTimer)
if (value === '') {
this.debouncedQuery = ''
this.#debounceTimer = null
} else {
this.#debounceTimer = setTimeout(() => {
this.debouncedQuery = value
this.#debounceTimer = null
}, DEBOUNCE_MS)
}
}
clear() {
this.query = ''
this.debouncedQuery = ''
this.activeGroupId = 'all'
}
/** Force subscribed components to re-fetch data. */
refresh() {
this.refreshTrigger++
}
}
export const search = new SearchStore()