update app and index.html
This commit is contained in:
+84
-2
@@ -11,6 +11,14 @@
|
||||
const textLexiconCache = new Map();
|
||||
const textLexiconOccurrencesCache = new Map();
|
||||
const textSearchCache = new Map();
|
||||
const NOW_SNAPSHOT_MIN_INTERVAL_MS = 5 * 60 * 1000;
|
||||
let nowSnapshotCache = {
|
||||
geoKey: "",
|
||||
fetchedAtMs: 0,
|
||||
value: null,
|
||||
pendingGeoKey: "",
|
||||
pendingPromise: null
|
||||
};
|
||||
|
||||
const DATA_ROOT = "data";
|
||||
const MAGICK_ROOT = DATA_ROOT;
|
||||
@@ -215,6 +223,26 @@
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
function normalizeGeoKey(geo) {
|
||||
const latitude = Number(geo?.latitude);
|
||||
const longitude = Number(geo?.longitude);
|
||||
|
||||
if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return `${latitude.toFixed(6)},${longitude.toFixed(6)}`;
|
||||
}
|
||||
|
||||
function isNowSnapshotPollingEnabled() {
|
||||
if (typeof document !== "undefined" && document.hidden === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const activeSection = String(window.TarotSectionStateUi?.getActiveSection?.() || "home").trim();
|
||||
return activeSection === "home";
|
||||
}
|
||||
|
||||
function toApiAssetUrl(assetPath) {
|
||||
const { apiBaseUrl, apiKey } = resolveConnectionSettings();
|
||||
const normalizedAssetPath = String(assetPath || "")
|
||||
@@ -247,6 +275,13 @@
|
||||
textLexiconCache.clear();
|
||||
textLexiconOccurrencesCache.clear();
|
||||
textSearchCache.clear();
|
||||
nowSnapshotCache = {
|
||||
geoKey: "",
|
||||
fetchedAtMs: 0,
|
||||
value: null,
|
||||
pendingGeoKey: "",
|
||||
pendingPromise: null
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeTarotName(value) {
|
||||
@@ -370,11 +405,58 @@
|
||||
}
|
||||
|
||||
async function fetchNowSnapshot(geo, timestamp = new Date()) {
|
||||
return fetchJson(buildApiUrl("/api/v1/now", {
|
||||
const geoKey = normalizeGeoKey(geo);
|
||||
const nowMs = Date.now();
|
||||
|
||||
if (!isNowSnapshotPollingEnabled()) {
|
||||
if (geoKey && nowSnapshotCache.pendingPromise && nowSnapshotCache.pendingGeoKey === geoKey) {
|
||||
return nowSnapshotCache.pendingPromise;
|
||||
}
|
||||
|
||||
if (geoKey && geoKey === nowSnapshotCache.geoKey && nowSnapshotCache.value) {
|
||||
return nowSnapshotCache.value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
geoKey
|
||||
&& geoKey === nowSnapshotCache.geoKey
|
||||
&& nowSnapshotCache.value
|
||||
&& Number.isFinite(nowSnapshotCache.fetchedAtMs)
|
||||
&& (nowMs - nowSnapshotCache.fetchedAtMs) < NOW_SNAPSHOT_MIN_INTERVAL_MS
|
||||
) {
|
||||
return nowSnapshotCache.value;
|
||||
}
|
||||
|
||||
if (geoKey && nowSnapshotCache.pendingPromise && nowSnapshotCache.pendingGeoKey === geoKey) {
|
||||
return nowSnapshotCache.pendingPromise;
|
||||
}
|
||||
|
||||
const requestPromise = fetchJson(buildApiUrl("/api/v1/now", {
|
||||
latitude: geo?.latitude,
|
||||
longitude: geo?.longitude,
|
||||
date: timestamp instanceof Date ? timestamp.toISOString() : timestamp
|
||||
}));
|
||||
}))
|
||||
.then((snapshot) => {
|
||||
if (geoKey) {
|
||||
nowSnapshotCache.geoKey = geoKey;
|
||||
nowSnapshotCache.fetchedAtMs = Date.now();
|
||||
nowSnapshotCache.value = snapshot;
|
||||
}
|
||||
return snapshot;
|
||||
})
|
||||
.finally(() => {
|
||||
if (nowSnapshotCache.pendingPromise === requestPromise) {
|
||||
nowSnapshotCache.pendingPromise = null;
|
||||
nowSnapshotCache.pendingGeoKey = "";
|
||||
}
|
||||
});
|
||||
|
||||
nowSnapshotCache.pendingPromise = requestPromise;
|
||||
nowSnapshotCache.pendingGeoKey = geoKey;
|
||||
return requestPromise;
|
||||
}
|
||||
|
||||
async function loadTarotCards(filters = {}) {
|
||||
|
||||
Reference in New Issue
Block a user