fix: folk-wrapper crash, service worker API exclusion, fal.ai endpoint

- folk-wrapper: createRenderRoot crashed because innerHTML="" removed the
  slot from DOM, making parentElement null on the next line. Save parent
  ref before clearing.

- sw.ts: module API paths (/space/module/api/...) weren't excluded from
  caching. Changed startsWith("/api/") to includes("/api/"). Also fixed
  catch handler returning undefined instead of a Response.

- image-gen: changed queue.fal.run to fal.run for synchronous responses.
  The queue endpoint returns request_id, not the actual image data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-02 23:36:15 -08:00
parent 4f9b036cc0
commit fef419f572
3 changed files with 11 additions and 10 deletions

View File

@ -292,11 +292,12 @@ export class FolkWrapper extends FolkShape {
<div class="tags"></div>
`;
// Replace existing content structure
// Replace existing content structure — save parent ref before clearing
const existingSlot = root.querySelector("slot");
if (existingSlot?.parentElement) {
existingSlot.parentElement.innerHTML = "";
existingSlot.parentElement.appendChild(wrapper);
const slotParent = existingSlot?.parentElement;
if (slotParent) {
slotParent.innerHTML = "";
slotParent.appendChild(wrapper);
}
// Get references

View File

@ -533,7 +533,7 @@ app.post("/api/image-gen", async (c) => {
};
const styledPrompt = (stylePrompts[style] || "") + prompt;
const res = await fetch("https://queue.fal.run/fal-ai/flux-pro/v1.1", {
const res = await fetch("https://fal.run/fal-ai/flux-pro/v1.1", {
method: "POST",
headers: {
Authorization: `Key ${FAL_KEY}`,
@ -567,7 +567,7 @@ app.post("/api/video-gen/t2v", async (c) => {
const { prompt, duration } = await c.req.json();
if (!prompt) return c.json({ error: "prompt required" }, 400);
const res = await fetch("https://queue.fal.run/fal-ai/wan/v2.1", {
const res = await fetch("https://fal.run/fal-ai/wan/v2.1", {
method: "POST",
headers: {
Authorization: `Key ${FAL_KEY}`,
@ -600,7 +600,7 @@ app.post("/api/video-gen/i2v", async (c) => {
const { image, prompt, duration } = await c.req.json();
if (!image) return c.json({ error: "image required" }, 400);
const res = await fetch("https://queue.fal.run/fal-ai/kling-video/v1/standard/image-to-video", {
const res = await fetch("https://fal.run/fal-ai/kling-video/v1/standard/image-to-video", {
method: "POST",
headers: {
Authorization: `Key ${FAL_KEY}`,

View File

@ -40,12 +40,12 @@ self.addEventListener("fetch", (event) => {
// Skip non-http(s) schemes (chrome-extension://, etc.) — they can't be cached
if (!url.protocol.startsWith("http")) return;
// Skip WebSocket and API requests entirely
// Skip WebSocket and API requests entirely (including module APIs like /space/module/api/...)
if (
event.request.url.startsWith("ws://") ||
event.request.url.startsWith("wss://") ||
url.pathname.startsWith("/ws/") ||
url.pathname.startsWith("/api/")
url.pathname.includes("/api/")
) {
return;
}
@ -101,7 +101,7 @@ self.addEventListener("fetch", (event) => {
}
return response;
})
.catch(() => cached as Response);
.catch(() => cached || new Response("Offline", { status: 503 }));
return cached || fetchPromise;
})
);