diff --git a/packages/playground/src/main.ts b/packages/playground/src/main.ts index 508ef6d3a3..d528aba28c 100644 --- a/packages/playground/src/main.ts +++ b/packages/playground/src/main.ts @@ -11,6 +11,10 @@ import { defineGlobals } from "./config"; import Monitor from "./Monitor.vue"; import router from "./router"; import { normalizeError } from "./utils/helpers"; +import { setupMapCache } from "./utils/mapCache"; + +setupMapCache(); + const app = createApp(Monitor); app.config.errorHandler = error => { diff --git a/packages/playground/src/utils/mapCache.ts b/packages/playground/src/utils/mapCache.ts new file mode 100644 index 0000000000..d5fbfdae30 --- /dev/null +++ b/packages/playground/src/utils/mapCache.ts @@ -0,0 +1,64 @@ +/** + * Cache configuration for map-related resources + */ +const CACHE_CONFIG = [ + { + pattern: (url: string) => url.endsWith("/all.csv") && url.includes("ISO-3166"), + contentType: "text/csv", + }, + { + pattern: (url: string) => url.includes("countries-110m.json") || url.endsWith("/110m.json"), + contentType: "application/json", + }, +] as const; + +const cache = new Map(); +const promises = new Map>(); +const originalFetch = window.fetch; + +async function getCached(url: string): Promise { + if (cache.has(url)) { + return cache.get(url)!; + } + + if (promises.has(url)) { + return promises.get(url)!; + } + + const promise = originalFetch(url) + .then(res => res.text()) + .then(text => { + cache.set(url, text); + return text; + }) + .finally(() => { + promises.delete(url); + }); + + promises.set(url, promise); + return promise; +} + +function getUrlString(input: RequestInfo | URL): string { + if (typeof input === "string") return input; + if (input instanceof URL) return input.href; + return input.url; +} + +export function setupMapCache(): void { + window.fetch = async function (input: RequestInfo | URL, init?: RequestInit): Promise { + const url = getUrlString(input); + + for (const config of CACHE_CONFIG) { + if (config.pattern(url)) { + const content = await getCached(url); + return new Response(content, { + status: 200, + headers: { "Content-Type": config.contentType }, + }); + } + } + + return originalFetch(input, init); + }; +}