diff --git a/.changeset/sixty-buses-type.md b/.changeset/sixty-buses-type.md new file mode 100644 index 000000000..713855e6e --- /dev/null +++ b/.changeset/sixty-buses-type.md @@ -0,0 +1,6 @@ +--- +'@electric-sql/pglite-utils': patch +'@electric-sql/pglite': patch +--- + +Fix caching of artifacts such that they are not downloaded multiple times diff --git a/docs/repl/ReplPlayground.vue b/docs/repl/ReplPlayground.vue index 195b3f58b..f0971cd92 100644 --- a/docs/repl/ReplPlayground.vue +++ b/docs/repl/ReplPlayground.vue @@ -35,7 +35,9 @@ const showReloadMsg = computed(() => { }) async function doLoadPg() { - pg.value = await loadPg() + if (!pg.value) { + pg.value = await loadPg() + } } async function loadPg() { @@ -162,6 +164,7 @@ watch( async function clearDb() { if (pg.value) { await pg.value.close() + pg.value = null } while (true) { const closed = await new Promise((resolve, reject) => { diff --git a/packages/pglite-utils/src/utils.ts b/packages/pglite-utils/src/utils.ts index cdbb0b5e1..10fd36915 100644 --- a/packages/pglite-utils/src/utils.ts +++ b/packages/pglite-utils/src/utils.ts @@ -3,18 +3,18 @@ export const IN_NODE = typeof process.versions === 'object' && typeof process.versions.node === 'string' -const wasmDownloadPromises = new Map>() +const artifactDownloadPromises = new Map>() -export async function startWasmDownload(url: URL) { - if (IN_NODE || wasmDownloadPromises.has(url)) { +export async function startArtifactDownload(url: URL) { + if (IN_NODE || artifactDownloadPromises.has(url.toString())) { return } - wasmDownloadPromises.set(url, fetch(url)) + artifactDownloadPromises.set(url.toString(), fetch(url)) } // This is a global cache of the Wasm modules to avoid having to re-download or // compile them on subsequent calls. -const cachedWasmModules = new Map() +const cachedWasmModules = new Map() export async function instantiateWasm( imports: WebAssembly.Imports, @@ -24,8 +24,8 @@ export async function instantiateWasm( instance: WebAssembly.Instance module: WebAssembly.Module }> { - if (module || cachedWasmModules.has(moduleUrl)) { - const mod = module || cachedWasmModules.get(moduleUrl)! + if (module || cachedWasmModules.has(moduleUrl.toString())) { + const mod = module || cachedWasmModules.get(moduleUrl.toString())! return { instance: await WebAssembly.instantiate(mod, imports), module: mod, @@ -38,19 +38,20 @@ export async function instantiateWasm( buffer, imports, ) - cachedWasmModules.set(moduleUrl, newModule) + cachedWasmModules.set(moduleUrl.toString(), newModule) return { instance, module: newModule, } } else { - if (!wasmDownloadPromises.has(moduleUrl)) { - wasmDownloadPromises.set(moduleUrl, fetch(moduleUrl)) + if (!artifactDownloadPromises.has(moduleUrl.toString())) { + startArtifactDownload(moduleUrl) + // wasmDownloadPromises.set(moduleUrl, fetch(moduleUrl)) } - const response = await wasmDownloadPromises.get(moduleUrl) + const response = await artifactDownloadPromises.get(moduleUrl.toString()) const { module: newModule, instance } = - await WebAssembly.instantiateStreaming(response!, imports) - cachedWasmModules.set(moduleUrl, newModule) + await WebAssembly.instantiateStreaming(response!.clone(), imports) + cachedWasmModules.set(moduleUrl.toString(), newModule) return { instance, module: newModule, @@ -64,8 +65,9 @@ export async function getFsBundle(fsBundleUrl: URL): Promise { const fileData = await fs.readFile(fsBundleUrl) return fileData.buffer } else { - const response = await fetch(fsBundleUrl) - return response.arrayBuffer() + startArtifactDownload(fsBundleUrl) + const response = await artifactDownloadPromises.get(fsBundleUrl.toString()) + return response!.clone().arrayBuffer() } } diff --git a/packages/pglite/src/pglite.ts b/packages/pglite/src/pglite.ts index 1814b9224..297efd2b8 100644 --- a/packages/pglite/src/pglite.ts +++ b/packages/pglite/src/pglite.ts @@ -273,14 +273,14 @@ export class PGlite if (!options.pgliteWasmModule) { // Start the wasm download in the background so it's ready when we need it - pglUtils.startWasmDownload( + pglUtils.startArtifactDownload( new URL('../release/pglite.wasm', import.meta.url), ) } if (!options.initdbWasmModule) { // Start the wasm download in the background so it's ready when we need it - pglUtils.startWasmDownload( + pglUtils.startArtifactDownload( new URL('../release/initdb.wasm', import.meta.url), ) }