feat: remove flexsearch dependency and replace with simple string filtering (#2542)

This commit is contained in:
kolaente 2026-04-04 21:41:25 +02:00 committed by GitHub
parent f5752b97e9
commit 0834d19f9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 21 additions and 101 deletions

View File

@ -84,7 +84,6 @@
"dompurify": "3.3.2",
"fast-deep-equal": "3.1.3",
"flatpickr": "4.6.13",
"flexsearch": "0.8.212",
"floating-vue": "5.2.2",
"is-touch-device": "1.0.1",
"klona": "2.0.6",

View File

@ -114,9 +114,6 @@ importers:
flatpickr:
specifier: 4.6.13
version: 4.6.13
flexsearch:
specifier: 0.8.212
version: 0.8.212
floating-vue:
specifier: 5.2.2
version: 5.2.2(vue@3.5.27(typescript@5.9.3))
@ -4140,9 +4137,6 @@ packages:
flatted@3.4.2:
resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==}
flexsearch@0.8.212:
resolution: {integrity: sha512-wSyJr1GUWoOOIISRu+X2IXiOcVfg9qqBRyCPRUdLMIGJqPzMo+jMRlvE83t14v1j0dRMEaBbER/adQjp6Du2pw==}
floating-vue@5.2.2:
resolution: {integrity: sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg==}
peerDependencies:
@ -11047,8 +11041,6 @@ snapshots:
flatted@3.4.2: {}
flexsearch@0.8.212: {}
floating-vue@5.2.2(vue@3.5.27(typescript@5.9.3)):
dependencies:
'@floating-ui/dom': 1.1.1

View File

@ -1,51 +0,0 @@
import {Document} from 'flexsearch'
export interface withId {
id: number,
}
const indexes: { [k: string]: Document<withId> } = {}
export const createNewIndexer = (name: string, fieldsToIndex: string[]) => {
if (typeof indexes[name] === 'undefined') {
indexes[name] = new Document<withId>({
tokenize: 'full',
document: {
id: 'id',
index: fieldsToIndex,
},
})
}
const index = indexes[name]
function add(item: withId) {
return index.add(item.id, item)
}
function remove(item: withId) {
return index.remove(item.id)
}
function update(item: withId) {
return index.update(item.id, item)
}
function search(query: string | null) {
if (query === '' || query === null) {
return null
}
return index.search(query)
?.flatMap(r => r.result)
.filter((value, index, self) => self.indexOf(value) === index) as number[]
|| null
}
return {
add,
remove,
update,
search,
}
}

View File

@ -4,12 +4,9 @@ import {acceptHMRUpdate, defineStore} from 'pinia'
import LabelService from '@/services/label'
import {success} from '@/message'
import {i18n} from '@/i18n'
import {createNewIndexer} from '@/indexes'
import {setModuleLoading} from '@/stores/helper'
import type {ILabel} from '@/modelTypes/ILabel'
const {add, remove, update, search} = createNewIndexer('labels', ['title', 'description'])
async function getAllLabels(page = 1): Promise<ILabel[]> {
const labelService = new LabelService()
const labels = await labelService.getAll({}, {}, page) as ILabel[]
@ -48,12 +45,12 @@ export const useLabelStore = defineStore('label', () => {
// **
const filterLabelsByQuery = computed(() => {
return (labelsToHide: ILabel[], query: string) => {
if (query === '') return []
const labelIdsToHide: number[] = labelsToHide.map(({id}) => id)
return search(query)
?.filter(value => !labelIdsToHide.includes(value))
.map(id => labels.value[id])
|| []
const q = query.toLowerCase()
return labelsArray.value
.filter(l => !labelIdsToHide.includes(l.id))
.filter(l => l.title.toLowerCase().includes(q) || (l.description ?? '').toLowerCase().includes(q))
}
})
@ -75,17 +72,14 @@ export const useLabelStore = defineStore('label', () => {
function setLabels(newLabels: ILabel[]) {
newLabels.forEach(l => {
labels.value[l.id] = l
add(l)
})
}
function setLabel(label: ILabel) {
labels.value[label.id] = {...label}
update(label)
}
function removeLabelById(label: ILabel) {
remove(label)
delete labels.value[label.id]
}

View File

@ -30,15 +30,6 @@ vi.mock('@/stores/base', () => ({
}),
}))
vi.mock('@/indexes', () => ({
createNewIndexer: () => ({
add: vi.fn(),
remove: vi.fn(),
search: vi.fn(),
update: vi.fn(),
}),
}))
function createMockProject(overrides: Partial<IProject>): IProject {
return {
id: 1,

View File

@ -8,7 +8,6 @@ import ProjectDuplicateService from '@/services/projectDuplicateService'
import ProjectDuplicateModel from '@/models/projectDuplicateModel'
import {setModuleLoading} from '@/stores/helper'
import {removeProjectFromHistory} from '@/modules/projectHistory'
import {createNewIndexer} from '@/indexes'
import type {IProject} from '@/modelTypes/IProject'
@ -21,8 +20,6 @@ import SavedFilterModel from '@/models/savedFilter'
import type {IProjectView} from '@/modelTypes/IProjectView'
import {PERMISSIONS} from '@/constants/permissions.ts'
const {add, remove, search, update} = createNewIndexer('projects', ['title', 'description'])
export const useProjectStore = defineStore('project', () => {
const baseStore = useBaseStore()
const router = useRouter()
@ -99,32 +96,33 @@ export const useProjectStore = defineStore('project', () => {
}
})
function searchByQuery(query: string): IProject[] {
if (query === '') return []
const q = query.toLowerCase()
return projectsArray.value.filter(p =>
p.title.toLowerCase().includes(q) || (p.description ?? '').toLowerCase().includes(q),
)
}
const searchProjectAndFilter = computed(() => {
return (query: string, includeArchived = false) => {
return search(query)
?.map(id => projects.value[id])
.filter(project => project?.isArchived === includeArchived)
|| []
return searchByQuery(query).filter(project => project.isArchived === includeArchived)
}
})
const searchProject = computed(() => {
return (query: string, includeArchived = false) => {
return search(query)
?.filter(value => value > 0)
.map(id => projects.value[id])
.filter(project => project?.isArchived === includeArchived)
|| []
return searchByQuery(query)
.filter(p => p.id > 0)
.filter(project => project.isArchived === includeArchived)
}
})
const searchSavedFilter = computed(() => {
return (query: string, includeArchived = false) => {
return search(query)
?.filter(value => getSavedFilterIdFromProjectId(value) > 0)
.map(id => projects.value[id])
.filter(project => project?.isArchived === includeArchived)
|| []
return searchByQuery(query)
.filter(p => getSavedFilterIdFromProjectId(p.id) > 0)
.filter(project => project.isArchived === includeArchived)
}
})
@ -134,7 +132,6 @@ export const useProjectStore = defineStore('project', () => {
function setProject(project: IProject) {
projects.value[project.id] = project
update(project)
// FIXME: This should be a watcher, but using a watcher instead will sometimes crash browser processes.
// Reverted from 31b7c1f217532bf388ba95a03f469508bee46f6a
@ -154,7 +151,6 @@ export const useProjectStore = defineStore('project', () => {
.filter(p => p.parentProjectId === project.id)
.forEach(p => removeProjectById(p))
remove(project)
delete projects.value[project.id]
}
@ -276,7 +272,6 @@ export const useProjectStore = defineStore('project', () => {
projects.value = {}
setProjects(loadedProjects)
loadedProjects.forEach(p => add(p))
return loadedProjects
}