From 63f9eed07cd1e88eecec50a6625306989d21e47c Mon Sep 17 00:00:00 2001 From: Misode Date: Thu, 27 Feb 2025 22:14:44 +0100 Subject: [PATCH] Use Spyglass API to get vanilla-mcdoc symbols --- src/app/services/DataFetcher.ts | 52 ++++++++++++++++++++++++--------- src/app/services/Spyglass.ts | 16 ++++++---- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/app/services/DataFetcher.ts b/src/app/services/DataFetcher.ts index 5b31ad16..400a81c9 100644 --- a/src/app/services/DataFetcher.ts +++ b/src/app/services/DataFetcher.ts @@ -12,7 +12,6 @@ declare var __LATEST_VERSION__: string export const latestVersion = __LATEST_VERSION__ ?? '' const mcmetaUrl = 'https://raw.githubusercontent.com/misode/mcmeta' const mcmetaTarballUrl = 'https://github.com/misode/mcmeta/tarball' -const vanillaMcdocUrl = 'https://raw.githubusercontent.com/SpyglassMC/vanilla-mcdoc' const changesUrl = 'https://raw.githubusercontent.com/misode/technical-changes' const fixesUrl = 'https://raw.githubusercontent.com/misode/mcfixes' const versionDiffUrl = 'https://mcmeta-diff.misode.workers.dev' @@ -48,19 +47,6 @@ export function getVersionChecksum(versionId: VersionId) { return version.ref } -export interface VanillaMcdocSymbols { - ref: string, - mcdoc: Record, - 'mcdoc/dispatcher': Record>, -} -export async function fetchVanillaMcdoc(): Promise { - try { - return cachedFetch(`${vanillaMcdocUrl}/generated/symbols.json`, { refresh: true }) - } catch (e) { - throw new Error(`Error occured while fetching vanilla-mcdoc: ${message(e)}`) - } -} - export async function fetchDependencyMcdoc(dependency: string) { try { return cachedFetch(`/mcdoc/${dependency}.mcdoc`, { decode: res => res.text(), refresh: true }) @@ -504,3 +490,41 @@ async function applyPatches() { localStorage.setItem(CACHE_PATCH, i.toFixed()) } } + +export async function fetchWithCache(input: RequestInfo | URL, init?: RequestInit): Promise { + const cache = await caches.open(CACHE_NAME) + const request = new Request(input, init) + const cachedResponse = await cache.match(request) + const cachedEtag = cachedResponse?.headers.get('ETag') + if (cachedEtag) { + request.headers.set('If-None-Match', cachedEtag) + } + try { + const response = await fetch(request) + if (response.status === 304 && cachedResponse) { + console.log(`[fetchWithCache] reusing cache for ${request.url}`) + return cachedResponse + } else if (!response.ok) { + let message = response.statusText + try { + message = (await response.json()).message + } catch (e) {} + throw new TypeError(`${response.status} ${message}`) + } else { + try { + await cache.put(request, response.clone()) + console.log(`[fetchWithCache] updated cache for ${request.url}`) + } catch (e) { + console.warn('[fetchWithCache] put cache', e) + } + return response + } + } catch (e) { + console.warn('[fetchWithCache] fetch', e) + if (cachedResponse) { + console.log(`[fetchWithCache] falling back to cache for ${request.url}`) + return cachedResponse + } + throw e + } +} diff --git a/src/app/services/Spyglass.ts b/src/app/services/Spyglass.ts index bc338f5e..ee378a23 100644 --- a/src/app/services/Spyglass.ts +++ b/src/app/services/Spyglass.ts @@ -12,11 +12,13 @@ import { TextDocument } from 'vscode-languageserver-textdocument' import type { ConfigGenerator } from '../Config.js' import siteConfig from '../Config.js' import { computeIfAbsent, genPath } from '../Utils.js' -import type { VanillaMcdocSymbols, VersionMeta } from './DataFetcher.js' -import { fetchBlockStates, fetchRegistries, fetchVanillaMcdoc, fetchVersions, getVersionChecksum } from './DataFetcher.js' +import type { VersionMeta } from './DataFetcher.js' +import { fetchBlockStates, fetchRegistries, fetchVersions, fetchWithCache, getVersionChecksum } from './DataFetcher.js' import { IndexedDbFileSystem } from './FileSystem.js' import type { VersionId } from './Versions.js' +const SPYGLASS_API = 'https://api.spyglassmc.com' + export const CACHE_URI = 'file:///cache/' export const ROOT_URI = 'file:///root/' export const DEPENDENCY_URI = `${ROOT_URI}dependency/` @@ -367,10 +369,10 @@ async function compressBall(files: [string, string][]): Promise { const initialize: core.ProjectInitializer = async (ctx) => { const { config, logger, meta, externals, cacheRoot } = ctx - const vanillaMcdoc = await fetchVanillaMcdoc() + const vanillaMcdocRes = await fetchWithCache(`${SPYGLASS_API}/vanilla-mcdoc/symbols`) meta.registerSymbolRegistrar('vanilla-mcdoc', { - checksum: vanillaMcdoc.ref, - registrar: vanillaMcdocRegistrar(vanillaMcdoc), + checksum: vanillaMcdocRes.headers.get('ETag') ?? '', + registrar: vanillaMcdocRegistrar(await vanillaMcdocRes.json()), }) meta.registerDependencyProvider('@misode-mcdoc', async () => { @@ -479,6 +481,10 @@ function registerAttributes(meta: core.MetaRegistry, release: ReleaseVersion, ve const VanillaMcdocUri = 'mcdoc://vanilla-mcdoc/symbols.json' +interface VanillaMcdocSymbols { + mcdoc: Record, + 'mcdoc/dispatcher': Record>, +} function vanillaMcdocRegistrar(vanillaMcdoc: VanillaMcdocSymbols): core.SymbolRegistrar { return (symbols) => { const start = performance.now()