serve a static website from your pds

Add fallback

Changed files
+38 -9
src
routes
~
sites
[name]
+19 -7
proxy.js
··· 54 54 process.stdout.write(`${req.method} ${req.url} `); 55 55 const start = performance.now(); 56 56 57 + let err; 57 58 try { 58 59 if (req.method !== "GET") return error(res, 405, "Method not supported"); 59 60 queueMicrotask(updateRecord); 60 61 61 62 let asset = record.value.assets[req.url.slice(1)]; 63 + let status = 200; 64 + 65 + // if there's no matching file, try to treat it as a folder and use an index.html inside it 62 66 if (!asset) { 63 - const path = req.url.slice(1).split("/"), 64 - filename = path.pop(); 65 - if (!/^.+\..+$/.test(filename)) { 66 - asset = record.value.assets[path.concat("index.html").join("/")]; 67 - } 67 + const path = req.url.slice(1).split("/").concat("index.html").join("/"); 68 + asset = record.value.assets[path]; 68 69 } 69 70 71 + // if there's still no matching file and a fallback is defined, try to use it 72 + if (!asset && record.value.fallback) { 73 + asset = record.value.assets[record.value.fallback.path]; 74 + if (record.value.fallback.status) status = record.value.fallback.status; 75 + } 76 + 77 + // if there's *still* no matching file, return a generic 404 70 78 if (!asset) return error(res, 404, "Not found"); 71 79 80 + // fetch the file's blob 72 81 try { 73 82 const blob = await getBlob(pds, did, asset.ref.$link); 74 83 ··· 77 86 78 87 const contentType = blob.headers.get("content-type") || asset.file.mimeType; 79 88 res.setHeader("content-type", contentType); 89 + res.statusCode = status; 80 90 81 91 const reader = blob.body.getReader(); 82 92 while (true) { ··· 84 94 if (done) break; 85 95 res.write(value); 86 96 } 97 + 87 98 res.end(); 88 - } catch (error) { 89 - console.error(error); 99 + } catch (e) { 100 + err = e; 90 101 return error(res, 502, "Bad gateway"); 91 102 } 92 103 } finally { 93 104 const ms = performance.now() - start; 94 105 process.stdout.write(`${res.statusCode} - ${Math.round(ms)}ms\n`); 106 + if (err) console.error(err); 95 107 } 96 108 }); 97 109
+19 -2
src/routes/~/sites/[name]/+page.svelte
··· 45 45 const form = e.currentTarget; 46 46 const formdata = new FormData(form); 47 47 48 - // todo: implement me 48 + let fallback: { path: string; status?: number } | undefined; 49 + 50 + const fallbackPath = formdata.get("fallback_path"); 51 + if (fallbackPath && typeof fallbackPath === "string") { 52 + fallback = { path: fallbackPath }; 53 + 54 + const fallbackStatus = formdata.get("fallback_status"); 55 + if (fallbackStatus && typeof fallbackStatus === "string") { 56 + const status = Number.parseInt(fallbackStatus); 57 + if (!Number.isNaN(status) && status !== 404) fallback.status = status; 58 + } 59 + } 60 + 61 + await atp.updateBundle(rkey, { ...(data.record.value as any), fallback }); 62 + invalidate(`rkey:${rkey}`); 63 + form.reset(); 49 64 } 65 + 66 + $inspect(data.record.value.fallback?.status); 50 67 </script> 51 68 52 69 <div class="detail"> ··· 106 123 <legend>Fallback</legend> 107 124 <label> 108 125 <span>path</span> 109 - <input name="fallback_path" group={data.record.value.fallback?.path} /> 126 + <input name="fallback_path" value={data.record.value.fallback?.path} /> 110 127 </label> 111 128 <label> 112 129 <span>200</span>