From b720c6ee2565575b45d17aae6625cfeb9cdb3e7a Mon Sep 17 00:00:00 2001 From: seb Date: Wed, 5 Aug 2026 07:07:18 +0200 Subject: [PATCH] u --- src/api/storageManager.jsx | 74 ++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/src/api/storageManager.jsx b/src/api/storageManager.jsx index 77195ce..9a2b00a 100644 --- a/src/api/storageManager.jsx +++ b/src/api/storageManager.jsx @@ -2,32 +2,49 @@ import { createContext, useContext, useRef } from 'react'; export const StorageManagerContext = createContext(null); -function createStorageManager() { - /** Fetch /articleIndex on construction and convert to the row shape the search page renders. */ - const articleIndexPromise = fetch('/api/articleIndex') - .then(async (res) => { - const data = await res.json(); - const articles = Array.isArray(data) ? data : (data?.articles ?? []); - console.log('[storageMgr] GET /articleIndex', { - status: res.status, - count: articles.length, - sampleKeys: - 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 []; +function loadArticleIndex() { + /** Fetch /articleIndex and convert to the row shape the search page renders. */ + return fetch('/api/articleIndex').then(async (res) => { + const data = await res.json(); + const articles = Array.isArray(data) ? data : (data?.articles ?? []); + console.log('[storageMgr] GET /articleIndex', { + status: res.status, + count: articles.length, + sampleKeys: + 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, + })); + }); +} + +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 }) { const articles = await articleIndexPromise; @@ -48,8 +65,11 @@ function createStorageManager() { return { doSearch, - // Expose so callers can await if they want the loaded index. - articleIndexPromise, + update, + // Always the current cache promise (including after update()). + get articleIndexPromise() { + return articleIndexPromise; + }, }; }