diff --git a/packages/core/src/build/targets/web.js b/packages/core/src/build/targets/web.js index cdb04478..70a1686b 100644 --- a/packages/core/src/build/targets/web.js +++ b/packages/core/src/build/targets/web.js @@ -29,6 +29,8 @@ export default async app => { import join from "@rcompat/fs/join"; import stringify from "@rcompat/object/stringify"; import crypto from "@rcompat/crypto"; + import { OK } from "@rcompat/http/status"; + import { resolve } from "@rcompat/http/mime"; const encoder = new TextEncoder(); const hash = async (data, algorithm = "sha-384") => { @@ -63,13 +65,28 @@ export default async app => { const pages = { ${pages_str} }; + const buildroot = file(import.meta.url).join(".."); + + const serve_asset = asset => new Response(asset.stream(), { + status: OK, + headers: { + "Content-Type": resolve(asset.name), + }, + }); const loader = { page(name) { return pages[name] ?? pages["${app.get("pages.app")}"]; }, - asset(pathname) { - return assets.find(asset => asset.src === pathname); + async asset(pathname) { + const root_asset = buildroot.join(\`client/\${pathname}\`); + if (await await root_asset.isFile) { + return serve_asset(asset); + } + const static_asset = buildroot.join(\`client/static/\${pathname}\`); + if (await static_asset.isFile) { + return serve_asset(static_asset); + } }, }; const target = "web"; diff --git a/packages/core/src/serve/hook/handle.js b/packages/core/src/serve/hook/handle.js index 169392b4..5d7b369b 100644 --- a/packages/core/src/serve/hook/handle.js +++ b/packages/core/src/serve/hook/handle.js @@ -1,4 +1,3 @@ -import log from "#log"; import client_error from "@primate/core/handler/error"; import cascade from "@rcompat/async/cascade"; import tryreturn from "@rcompat/async/tryreturn"; @@ -71,21 +70,8 @@ export default app => { }); }; - const as_asset = async (pathname, code) => new Response(code, { - status: OK, - headers: { - "Content-Type": resolve(pathname), -// Etag: await path.modified(), - }, - }); - - const handle = async request => { - const { pathname } = request.url; - - const asset = app.loader.asset(pathname)?.code; - - return asset === undefined ? as_route(request) : as_asset(pathname, asset); - }; + const handle = async request => + (await app.loader.asset(request.url.pathname)) ?? as_route(request); // first hook const pass = (request, next) => next({ ...request, diff --git a/packages/native/src/desktop.js b/packages/native/src/desktop.js index 46aa0134..9a234f36 100644 --- a/packages/native/src/desktop.js +++ b/packages/native/src/desktop.js @@ -6,6 +6,12 @@ export default async app => { const http = app.get("http"); const client = app.runpath(location.client); const re = /app..*(?:js|css)$/u; + + const import_statics = (await client.collect()).map((path, i) => ` + import static${i} from "./client${path.debase(client)}" with { type: "file" }; + statics["${path.debase(client)}"] = await file(static${i});`) + .join("\n"); + const $imports = (await Promise.all((await client.collect(re, { recursive: false })) .map(async (file, i) => { const type = file.extension === ".css" ? "style" : "js"; @@ -30,6 +36,8 @@ export default async app => { import file from "@rcompat/fs/file"; import stringify from "@rcompat/object/stringify"; import crypto from "@rcompat/crypto"; + import { OK } from "@rcompat/http/status"; + import { resolve } from "@rcompat/http/mime"; const encoder = new TextEncoder(); const hash = async (data, algorithm = "sha-384") => { @@ -38,6 +46,9 @@ export default async app => { return \`\${prefix}-\${btoa(String.fromCharCode(...new Uint8Array(bytes)))}\`; }; + const statics = {}; + ${import_statics} + ${$imports.map(({ path }, i) => `import asset${i} from "${path}" with { type: "file" }; const file${i} = await file(asset${i}).text();`).join("\n ")} @@ -69,13 +80,26 @@ export default async app => { const pages = { ${pages.map((page, i) => `"${page}": page${i},`).join("\n ")} }; + const serve_asset = asset => new Response(asset.stream(), { + status: OK, + headers: { + "Content-Type": resolve(asset.name), + }, + }); const loader = { page(name) { return pages[name] ?? pages["${app.get("pages.app")}"]; }, asset(pathname) { - return assets.find(asset => asset.src === pathname); + const root_asset = statics[pathname]; + if (root_asset !== undefined) { + return serve_asset(root_asset); + } + const static_asset = statics[\`/static\${pathname}\`]; + if (static_asset !== undefined) { + return serve_asset(static_asset); + } }, webview() { return Webview;