refactoring

This commit is contained in:
2026-03-07 05:17:50 -08:00
parent 68e19d864c
commit 3c07a13547
34 changed files with 11653 additions and 9078 deletions

View File

@@ -101,9 +101,10 @@
const DECK_REGISTRY_PATH = "asset/tarot deck/decks.json";
const deckManifestSources = buildDeckManifestSources();
let deckManifestSources = buildDeckManifestSources();
const manifestCache = new Map();
const cardBackCache = new Map();
let activeDeckId = DEFAULT_DECK_ID;
function canonicalMajorName(cardName) {
@@ -132,16 +133,17 @@
}
function normalizeDeckId(deckId) {
const sources = getDeckManifestSources();
const normalized = String(deckId || "").trim().toLowerCase();
if (deckManifestSources[normalized]) {
if (sources[normalized]) {
return normalized;
}
if (deckManifestSources[DEFAULT_DECK_ID]) {
if (sources[DEFAULT_DECK_ID]) {
return DEFAULT_DECK_ID;
}
const fallbackId = Object.keys(deckManifestSources)[0];
const fallbackId = Object.keys(sources)[0];
return fallbackId || DEFAULT_DECK_ID;
}
@@ -241,6 +243,41 @@
});
}
function isRemoteAssetPath(pathValue) {
return /^(https?:)?\/\//i.test(String(pathValue || ""));
}
function toDeckAssetPath(manifest, relativeOrAbsolutePath) {
const normalizedPath = String(relativeOrAbsolutePath || "").trim();
if (!normalizedPath) {
return "";
}
if (isRemoteAssetPath(normalizedPath) || normalizedPath.startsWith("/")) {
return normalizedPath;
}
return `${manifest.basePath}/${normalizedPath.replace(/^\.\//, "")}`;
}
function resolveDeckCardBackPath(manifest) {
if (!manifest) {
return null;
}
const explicitCardBack = String(manifest.cardBack || "").trim();
if (explicitCardBack) {
return toDeckAssetPath(manifest, explicitCardBack) || null;
}
const detectedCardBack = String(manifest.cardBackPath || "").trim();
if (detectedCardBack) {
return toDeckAssetPath(manifest, detectedCardBack) || null;
}
return null;
}
function readManifestJsonSync(path) {
try {
const request = new XMLHttpRequest();
@@ -276,7 +313,8 @@
id,
label: String(entry?.label || id),
basePath,
manifestPath
manifestPath,
cardBackPath: String(entry?.cardBackPath || "").trim()
};
});
@@ -292,6 +330,14 @@
return toDeckSourceMap(registryDecks);
}
function getDeckManifestSources(forceRefresh = false) {
if (forceRefresh || !deckManifestSources || Object.keys(deckManifestSources).length === 0) {
deckManifestSources = buildDeckManifestSources();
}
return deckManifestSources || {};
}
function normalizeDeckManifest(source, rawManifest) {
if (!rawManifest || typeof rawManifest !== "object") {
return null;
@@ -337,6 +383,8 @@
id: source.id,
label: String(rawManifest.label || source.label || source.id),
basePath: String(source.basePath || "").replace(/\/$/, ""),
cardBack: String(rawManifest.cardBack || "").trim(),
cardBackPath: String(source.cardBackPath || "").trim(),
majors: rawManifest.majors || {},
minors: rawManifest.minors || {},
nameOverrides,
@@ -351,15 +399,22 @@
return manifestCache.get(normalizedDeckId);
}
const source = deckManifestSources[normalizedDeckId];
let sources = getDeckManifestSources();
let source = sources[normalizedDeckId];
if (!source) {
sources = getDeckManifestSources(true);
source = sources[normalizedDeckId];
}
if (!source) {
manifestCache.set(normalizedDeckId, null);
return null;
}
const rawManifest = readManifestJsonSync(source.manifestPath);
const normalizedManifest = normalizeDeckManifest(source, rawManifest);
manifestCache.set(normalizedDeckId, normalizedManifest);
if (normalizedManifest) {
manifestCache.set(normalizedDeckId, normalizedManifest);
}
return normalizedManifest;
}
@@ -531,11 +586,23 @@
return encodeURI(activePath);
}
if (activeDeckId !== DEFAULT_DECK_ID) {
const fallbackPath = resolveWithDeck(DEFAULT_DECK_ID, cardName);
if (fallbackPath) {
return encodeURI(fallbackPath);
}
return null;
}
function resolveTarotCardBackImage(optionsOrDeckId) {
const { resolvedDeckId } = resolveDeckOptions(optionsOrDeckId);
if (cardBackCache.has(resolvedDeckId)) {
const cachedPath = cardBackCache.get(resolvedDeckId);
return cachedPath ? encodeURI(cachedPath) : null;
}
const manifest = getDeckManifest(resolvedDeckId);
const activeBackPath = resolveDeckCardBackPath(manifest);
cardBackCache.set(resolvedDeckId, activeBackPath || null);
if (activeBackPath) {
return encodeURI(activeBackPath);
}
return null;
@@ -629,7 +696,7 @@
}
function getDeckOptions() {
return Object.values(deckManifestSources).map((source) => {
return Object.values(getDeckManifestSources()).map((source) => {
const manifest = getDeckManifest(source.id);
return {
id: source.id,
@@ -645,6 +712,7 @@
window.TarotCardImages = {
resolveTarotCardImage,
resolveTarotCardBackImage,
getTarotCardDisplayName,
getTarotCardSearchAliases,
setActiveDeck,