From 7d6a686e2cfb00bbcb91b4274d80689a02be80a9 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Thu, 23 Apr 2026 13:24:48 -0700 Subject: [PATCH] kidlisp-bundler: drop query suffixes when rewriting relative imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit disk.mjs imports `./l5.mjs?v=20260330-runtime-support` for cache busting. After resolvePath, the bundler kept the query suffix, producing bare `lib/l5.mjs?v=20260330-runtime-support` specifiers in the bundled HTML. The import map only registers `lib/l5.mjs` (no query), so browsers reject the import with "Failed to resolve module specifier" and the piece never renders inside the bundled artifact. This manifested as keep-prepare-background's oven timing out at 150s when baking thumbnails for any piece whose code path reaches that import — the iframe loaded a dead module graph and never produced a frame. The silent thumbnail-fallback path then reused the previous thumbnail URI, making the failure invisible to users clicking "Regenerate Media". Fix: strip the query entirely in rewriteImports (blob: URLs in bundled output are already unique per bundle, no cache bust needed). Co-Authored-By: Claude Opus 4.7 (1M context) --- system/backend/kidlisp-bundler.mjs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/system/backend/kidlisp-bundler.mjs b/system/backend/kidlisp-bundler.mjs index da42bede84..fb7837323b 100644 --- a/system/backend/kidlisp-bundler.mjs +++ b/system/backend/kidlisp-bundler.mjs @@ -122,21 +122,28 @@ function rewriteImports(code, filepath) { return 'import(\'ac/disks/' + p + '\')'; }); - // Rewrite relative imports (strip query params for resolution, then re-add) - code = code.replace(/from\s*['"](\.\.\/[^'"?]+|\.\/[^'"?]+)(\?[^'"]*)?['"]/g, (match, p, query) => { + // Rewrite relative imports. Drop the query suffix entirely — in bundled + // output the import map maps bare `lib/foo.mjs` specifiers to blob: URLs + // that are already unique per bundle, so cache-busting query params like + // `?v=20260330-runtime-support` are not only unneeded but actively break + // resolution (the map has no versioned entry, browser rejects the import). + // This was the cause of the $rip / l5.mjs "Failed to resolve module + // specifier" error that killed in-browser piece execution and made the + // oven's thumbnail capture hang for its full 150s timeout. + code = code.replace(/from\s*['"](\.\.\/[^'"?]+|\.\/[^'"?]+)(\?[^'"]*)?['"]/g, (match, p) => { const resolved = resolvePath(filepath, p); - return 'from"' + resolved + (query || '') + '"'; + return 'from"' + resolved + '"'; }); - // Rewrite dynamic imports (strip query params for resolution, then re-add) - code = code.replace(/import\s*\((['"](\.\.\/[^'"?]+|\.\/[^'"?]+)(\?[^'"]*)?)['"](\))\)/g, (match, fullPath, p, query, closing) => { + // Rewrite dynamic imports (same query-drop logic) + code = code.replace(/import\s*\((['"](\.\.\/[^'"?]+|\.\/[^'"?]+)(\?[^'"]*)?)['"](\))\)/g, (match, fullPath, p) => { const resolved = resolvePath(filepath, p); - return 'import("' + resolved + (query || '') + '")'; + return 'import("' + resolved + '")'; }); - code = code.replace(/import\s*\(\`(\.\.\/[^\`?]+)(\?[^\`]*)?\`\)/g, (match, p, query) => { + code = code.replace(/import\s*\(\`(\.\.\/[^\`?]+)(\?[^\`]*)?\`\)/g, (match, p) => { const resolved = resolvePath(filepath, p); - return 'import("' + resolved + (query || '') + '")'; + return 'import("' + resolved + '")'; }); return code; -- 2.51.2