/** * Monitors and requests the summary of recently changed history items and commits the * results to the history items and other attached stores. The initial update time threshold * corresponds to the module import time. Once the watcher is called, continuous requests are * submitted, delayed only by the throttle period and the request response time. */ import { storeToRefs } from "pinia"; import { useCollectionElementsStore } from "@/stores/collectionElementsStore"; import { useDatasetStore } from "@/stores/datasetStore"; import { useHistoryItemsStore } from "@/stores/historyItemsStore"; import { useHistoryStore } from "@/stores/historyStore"; import { loadSet } from "@/utils/setCache"; import { urlData } from "@/utils/url"; const limit = 1000; export const ACTIVE_POLLING_INTERVAL = 3000; export const INACTIVE_POLLING_INTERVAL = 60000; // last time the history has changed let lastUpdateTime = null; // last time changed history items have been requested let lastRequestDate = new Date(); export async function watchHistory(app) { // GalaxyApp const { isWatching } = storeToRefs(useHistoryItemsStore()); try { isWatching.value = true; await watchHistoryOnce(app); } catch (error) { // error alerting the user that watch history failed console.warn(error); isWatching.value = false; } } export async function watchHistoryOnce(app) { const historyStore = useHistoryStore(); const historyItemsStore = useHistoryItemsStore(); const datasetStore = useDatasetStore(); const collectionElementsStore = useCollectionElementsStore(); // get current history const checkForUpdate = new Date(); const history = await historyStore.loadCurrentHistory(lastUpdateTime); const { lastCheckedTime } = storeToRefs(historyItemsStore); lastCheckedTime.value = checkForUpdate; if (!history || !history.id) { return; } // continue if the history update time has changed if (!lastUpdateTime || lastUpdateTime < history.update_time) { const historyId = history.id; lastUpdateTime = history.update_time; historyItemsStore.setLastUpdateTime(); // execute request to obtain recently changed items const params = { v: "dev", limit: limit, q: "update_time-ge", qv: lastRequestDate.toISOString(), }; // request detailed info only for the expanded datasets const detailedIds = getCurrentlyExpandedHistoryContentIds(); if (detailedIds.length) { params["details"] = detailedIds.join(","); } const url = `/api/histories/${historyId}/contents`; lastRequestDate = new Date(); const payload = await urlData({ url, params }); // show warning that not all changes have been obtained if (payload && payload.length == limit) { console.debug(`Reached limit of monitored changes (limit=${limit}).`); } // pass changed items to attached stores historyStore.setHistory(history); datasetStore.saveDatasets(payload); historyItemsStore.saveHistoryItems(historyId, payload); collectionElementsStore.saveCollections(payload); // trigger changes in legacy handler if (app) { app.user.loadFromApi(app.user.id || "current"); } } } /** * Returns the set of history item IDs that are currently expanded in the history panel from the cache. * These content items need to retrieve detailed information when updated. * @returns {Array} List of history item IDs that are currently expanded. */ function getCurrentlyExpandedHistoryContentIds() { const expandedItemIds = []; const cacheKey = "expanded-history-items"; const expandedItems = loadSet(cacheKey); expandedItems.forEach((key) => { // Items have the format: - const itemId = key.split("-")[1]; if (itemId?.trim()) { expandedItemIds.push(itemId); } }); return expandedItemIds; }