From 41a1498435cdf3d054e874a38f92953735e5002d Mon Sep 17 00:00:00 2001 From: prompt.ac/@jeffrey Date: Thu, 23 Apr 2026 20:24:48 +0000 Subject: [PATCH] kidlisp-bundler: drop query suffixes when rewriting relative imports 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(s) changed, 15 insertion(s)(+), 8 deletion(s)(-) diff --git a/system/backend/kidlisp-bundler.mjs b/system/backend/kidlisp-bundler.mjs --- a/system/backend/kidlisp-bundler.mjs +++ b/system/backend/kidlisp-bundler.mjs @@ -122,21 +122,28 @@ code = code.replace(/import\s*\((['"]aesthetic\.computer\/disks\/([^'"]+)['")])\)/g, (match, fullPath, p) => { 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; -- tangled.sh