This commit is contained in:
seb
2026-08-05 07:07:18 +02:00
parent 406684f4a2
commit b720c6ee25

View File

@@ -2,32 +2,49 @@ import { createContext, useContext, useRef } from 'react';
export const StorageManagerContext = createContext(null); export const StorageManagerContext = createContext(null);
function createStorageManager() { function loadArticleIndex() {
/** Fetch /articleIndex on construction and convert to the row shape the search page renders. */ /** Fetch /articleIndex and convert to the row shape the search page renders. */
const articleIndexPromise = fetch('/api/articleIndex') return fetch('/api/articleIndex').then(async (res) => {
.then(async (res) => { const data = await res.json();
const data = await res.json(); const articles = Array.isArray(data) ? data : (data?.articles ?? []);
const articles = Array.isArray(data) ? data : (data?.articles ?? []); console.log('[storageMgr] GET /articleIndex', {
console.log('[storageMgr] GET /articleIndex', { status: res.status,
status: res.status, count: articles.length,
count: articles.length, sampleKeys:
sampleKeys: articles.slice(0, 3).map((a) => (a && typeof a === 'object' ? Object.keys(a) : null)),
articles.slice(0, 3).map((a) => (a && typeof a === 'object' ? Object.keys(a) : null)),
});
// Map backend article rows to the recordset shape used by the result list.
// `categories` is a comma-joined string (formatCategoryList splits on ',').
return articles.map((a) => ({
id: a.id,
sku: a.sku,
name: a.name,
eans: a.eans ?? [],
categories: Array.isArray(a.categoryIds) ? a.categoryIds.join(',') : null,
}));
})
.catch((err) => {
console.error('[storageMgr] GET /articleIndex failed', err);
return [];
}); });
// Map backend article rows to the recordset shape used by the result list.
// `categories` is a comma-joined string (formatCategoryList splits on ',').
return articles.map((a) => ({
id: a.id,
sku: a.sku,
name: a.name,
eans: a.eans ?? [],
categories: Array.isArray(a.categoryIds) ? a.categoryIds.join(',') : null,
}));
});
}
function createStorageManager() {
let articleIndexPromise = loadArticleIndex().catch((err) => {
console.error('[storageMgr] GET /articleIndex failed', err);
return [];
});
/**
* Re-fetch /articleIndex. Searches keep using the old cache until the new
* load resolves; only then is the cache replaced. On failure the old cache stays.
*/
async function update() {
try {
const articles = await loadArticleIndex();
articleIndexPromise = Promise.resolve(articles);
return articles;
} catch (err) {
console.error('[storageMgr] update /articleIndex failed', err);
throw err;
}
}
async function doSearch({ target, filter, offset, maxCount, onUpdate }) { async function doSearch({ target, filter, offset, maxCount, onUpdate }) {
const articles = await articleIndexPromise; const articles = await articleIndexPromise;
@@ -48,8 +65,11 @@ function createStorageManager() {
return { return {
doSearch, doSearch,
// Expose so callers can await if they want the loaded index. update,
articleIndexPromise, // Always the current cache promise (including after update()).
get articleIndexPromise() {
return articleIndexPromise;
},
}; };
} }