use useMemoize to simplify cache

This commit is contained in:
Gauthier Roebroeck 2025-10-22 10:50:59 +08:00
parent 5af990c7cf
commit e0019b3432
4 changed files with 28 additions and 25 deletions

View file

@ -32,7 +32,7 @@ declare module 'vue' {
HistoryExpandDuplicatePageDeleted: typeof import('./components/history/expand/DuplicatePageDeleted.vue')['default']
HistoryExpandSeriesDirectoryDeleted: typeof import('./components/history/expand/SeriesDirectoryDeleted.vue')['default']
HistoryExpandTable: typeof import('./components/history/expand/Table.vue')['default']
HistoryTable: typeof import('./components/history/Table.vue')['default']
HistoryTable: typeof import('./components/history/HistoryTable.vue')['default']
ImportBooksDirectorySelection: typeof import('./components/import/books/DirectorySelection.vue')['default']
ImportBooksTransientBooksTable: typeof import('./components/import/books/TransientBooksTable.vue')['default']
ImportReadlistTable: typeof import('./components/import/readlist/Table.vue')['default']

View file

@ -101,6 +101,7 @@ import { historicalEventMessages } from '@/utils/i18n/enum/historical-event'
import type { MessageDescriptor } from '@formatjs/intl/src/types'
import { seriesDetailQuery } from '@/colada/series'
import { bookDetailQuery } from '@/colada/books'
import { useMemoize } from '@vueuse/core'
const intl = useIntl()
@ -200,31 +201,33 @@ function getExpandedComponent(eventType: string): Component | null {
}
}
const seriesCache = reactive<Record<string, string>>({})
const seriesCacheNotFound = reactive<string[]>([])
const booksCache = reactive<Record<string, string>>({})
const booksCacheNotFound = reactive<string[]>([])
const seriesCache = reactive<Record<string, string | undefined>>({})
const booksCache = reactive<Record<string, string | undefined>>({})
const getSeriesTitle = useMemoize(async (seriesId: string) =>
useQuery(seriesDetailQuery, () => ({ seriesId: seriesId }))
.refresh(true)
.then(({ data }) => data?.metadata.title)
.catch(() => undefined),
)
const getBookTitle = useMemoize(async (bookId: string) =>
useQuery(bookDetailQuery, () => ({ bookId: bookId }))
.refresh(true)
.then(({ data }) => data?.metadata.title)
.catch(() => undefined),
)
watch(data, (data) => {
for (const seriesId of new Set(data?.content?.map((s) => s.seriesId))) {
if (seriesId && !seriesCacheNotFound.includes(seriesId) && !(seriesId in seriesCache)) {
const { refresh } = useQuery(seriesDetailQuery, () => ({ seriesId: seriesId }))
refresh(true)
.then(({ data }) => {
if (data) seriesCache[seriesId] = data.metadata.title
})
.catch(() => seriesCacheNotFound.push(seriesId))
if (seriesId) {
void getSeriesTitle(seriesId).then((title) => (seriesCache[seriesId] = title))
}
}
for (const bookId of new Set(data?.content?.map((s) => s.bookId))) {
if (bookId && !booksCacheNotFound.includes(bookId) && !(bookId in booksCache)) {
const { refresh } = useQuery(bookDetailQuery, () => ({ bookId: bookId }))
refresh(true)
.then(({ data }) => {
if (data) booksCache[bookId] = data.metadata.title
})
.catch(() => booksCacheNotFound.push(bookId))
if (bookId) {
void getBookTitle(bookId).then((title) => (booksCache[bookId] = title))
}
}
})

View file

@ -1,6 +1,6 @@
import type { Meta, StoryObj } from '@storybook/vue3-vite'
import Table from './Table.vue'
import HistoryTable from './HistoryTable.vue'
import { delay, http } from 'msw'
import { response401Unauthorized } from '@/mocks/api/handlers'
import { httpTyped } from '@/mocks/api/httpTyped'
@ -8,19 +8,19 @@ import { mockPage } from '@/mocks/api/pageable'
import { PageRequest } from '@/types/PageRequest'
const meta = {
component: Table,
component: HistoryTable,
render: (args: object) => ({
components: { Table },
components: { HistoryTable },
setup() {
return { args }
},
template: '<Table v-bind="args" />',
template: '<HistoryTable v-bind="args" />',
}),
parameters: {
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
},
args: {},
} satisfies Meta<typeof Table>
} satisfies Meta<typeof HistoryTable>
export default meta
type Story = StoryObj<typeof meta>
@ -32,7 +32,7 @@ export const Default: Story = {
export const Loading: Story = {
parameters: {
msw: {
handlers: [http.all('*/api/v1/history', async () => await delay(5_000))],
handlers: [http.all('*/api/*', async () => await delay(5_000))],
},
},
}