This commit is contained in:
seb
2026-08-06 00:32:22 +02:00
parent 855710a198
commit d8b48d96e1
7 changed files with 151 additions and 58 deletions

View File

@@ -176,19 +176,36 @@ export class StorageManager extends ApiClient {
/**
* Fetch article history, then refetch whenever SSE emits `article-<sku>`.
* Paginates in the store (full list from HTTP; slice via setSkipAndOffset).
* @param {string} sku
* @param {(history: unknown[]) => void} onHistory
* @returns {() => void} unwatch
* @param {(history: unknown[], total: number) => void} onHistory
* @returns {{ unwatch: () => void, setSkipAndOffset: (skip: number, offset: number) => void }}
*/
watchArticleHistory(sku, onHistory) {
const key = String(sku);
let active = true;
let loaded = false;
/** @type {unknown[]} */
let all = [];
let skip = 0;
/** Page size (how many rows to emit). */
let offset = Number.POSITIVE_INFINITY;
const emit = () => {
if (!active || !loaded) return;
const total = all.length;
const end =
offset === Number.POSITIVE_INFINITY ? total : skip + offset;
onHistory(all.slice(skip, end), total);
};
const refresh = () =>
this.article.history(key).then((res) => {
if (!active) return;
requireObject(res, 'GET /api/article/{sku}/history');
onHistory(requireArray(res.history, 'history'));
all = requireArray(res.history, 'history');
loaded = true;
emit();
});
const run = () =>
@@ -211,17 +228,24 @@ export class StorageManager extends ApiClient {
run();
return () => {
active = false;
const set = this.#historyWatchers.get(key);
if (!set) return;
set.delete(run);
if (set.size === 0) {
this.#historyWatchers.delete(key);
if (!this.#articleWatchers.has(key)) {
this.#events?.removeEventListener(`article-${key}`, this.#onArticleSignal);
return {
unwatch: () => {
active = false;
const set = this.#historyWatchers.get(key);
if (!set) return;
set.delete(run);
if (set.size === 0) {
this.#historyWatchers.delete(key);
if (!this.#articleWatchers.has(key)) {
this.#events?.removeEventListener(`article-${key}`, this.#onArticleSignal);
}
}
}
},
setSkipAndOffset: (nextSkip, nextOffset) => {
skip = nextSkip;
offset = nextOffset;
emit();
},
};
}