No releases published yet. Try a snapshot!`;
return { latestRelease: null };
}
let html = '';
[...releases].reverse().forEach((ver, i) => {
const dlUrl = `${GITHUB_RELEASES}/download/${encodeURIComponent(ver)}/${ARTIFACT_ID}-${ver}.jar`;
html += renderVersionCard(ver, dlUrl, 'Download JAR', 'release', i === 0);
});
container.innerHTML = html;
const latest = relData.latestRelease || releases[releases.length - 1];
return { latestRelease: latest };
} catch (e) {
console.warn('Failed to fetch releases:', e);
showError('release-list');
return { latestRelease: null };
}
}
async function loadSnapshots() {
const container = document.getElementById('snapshot-list');
try {
const snapData = await fetchMavenMetadata('snapshots');
const snapshots = snapData?.versions || [];
if (snapshots.length === 0) {
container.innerHTML = `
No snapshots found.`;
return { latestSnapshot: null };
}
const reversed = [...snapshots].reverse();
const MAX_EXACT_FETCHES = 3;
const groupPath = GROUP_ID.replace(/\./g, '/');
// Fetch exact JARs for the latest few in parallel
const exactJarUrls = await Promise.all(
reversed.slice(0, MAX_EXACT_FETCHES).map(ver => fetchExactSnapshotJar(ver))
);
let html = '';
reversed.forEach((ver, i) => {
let finalUrl, btnText;
if (i < MAX_EXACT_FETCHES && exactJarUrls[i]) {
finalUrl = exactJarUrls[i];
btnText = 'Download JAR';
} else {
finalUrl = `${MAVEN_BASE}/#/snapshots/${groupPath}/${ARTIFACT_ID}/${ver}`;
btnText = 'View Folder';
}
html += renderVersionCard(ver, finalUrl, btnText, 'snapshot', i === 0);
});
container.innerHTML = html;
return { latestSnapshot: snapshots[snapshots.length - 1], latestSnapshotJar: exactJarUrls[0] };
} catch (e) {
console.warn('Failed to fetch snapshots:', e);
showError('snapshot-list');
return { latestSnapshot: null };
}
}
async function initVersions() {
// Fire both columns independently so each shows its own skeletons -> content
const [relResult, snapResult] = await Promise.all([
loadReleases(),
loadSnapshots()
]);
// Update hero/nav download buttons with the best available version
const latestRelease = relResult.latestRelease;
const latestSnapshot = snapResult.latestSnapshot;
let isSnapshotFallback = false;
let best;
if (latestRelease) {
best = latestRelease;
} else if (latestSnapshot) {
best = latestSnapshot;
isSnapshotFallback = true;
} else {
// Both failed - fallback hero to GitHub
document.querySelectorAll('.dynamic-mod-title').forEach(el => el.textContent = 'Check GitHub for latest');
document.querySelectorAll('.dynamic-dl-btn').forEach(el => el.href = GITHUB_RELEASES);
document.querySelectorAll('.dynamic-mod-ver').forEach(el => el.textContent = '');
return;
}
const mcVer = getMcVersion(best);
const modVer = getModVersion(best);
let primaryDlUrl;
if (isSnapshotFallback) {
primaryDlUrl = snapResult.latestSnapshotJar || GITHUB_RELEASES;
} else {
primaryDlUrl = `${GITHUB_RELEASES}/download/${encodeURIComponent(best)}/${ARTIFACT_ID}-${best}.jar`;
}
document.querySelectorAll('.dynamic-dl-btn').forEach(el => el.href = primaryDlUrl);
document.querySelectorAll('.dynamic-mc-ver').forEach(el => el.textContent = mcVer);
document.querySelectorAll('.dynamic-mod-ver').forEach(el => el.textContent = isSnapshotFallback ? `v${modVer} (Snap)` : `v${modVer}`);
document.querySelectorAll('.dynamic-mod-title').forEach(el => el.textContent = isSnapshotFallback ? `Latest Snapshot: ${modVer}` : `Release ${modVer}`);
}
initVersions();
});