diff --git a/app/src/adapter/index.ts b/app/src/adapter/index.ts index 949aaba..79f4c97 100644 --- a/app/src/adapter/index.ts +++ b/app/src/adapter/index.ts @@ -154,23 +154,32 @@ export async function createRuntimeApp( * }); * ``` */ -export function serveStaticViaImport(opts?: { manifest?: Manifest }) { +export function serveStaticViaImport(opts?: { + manifest?: Manifest; + appendRaw?: boolean; + package?: string; +}) { let files: string[] | undefined; + const pkg = opts?.package ?? "bknd"; // @ts-ignore return async (c: Context, next: Next) => { if (!files) { const manifest = opts?.manifest || - ((await import("bknd/dist/manifest.json", { with: { type: "json" } })) - .default as Manifest); + (( + await import(/* @vite-ignore */ `${pkg}/dist/manifest.json`, { + with: { type: "json" }, + }) + ).default as Manifest); files = Object.values(manifest).flatMap((asset) => [asset.file, ...(asset.css || [])]); } const path = c.req.path.substring(1); if (files.includes(path)) { try { - const content = await import(/* @vite-ignore */ `bknd/static/${path}?raw`, { + const url = `${pkg}/static/${path}${opts?.appendRaw ? "?raw" : ""}`; + const content = await import(/* @vite-ignore */ url, { with: { type: "text" }, }).then((m) => m.default); @@ -183,7 +192,7 @@ export function serveStaticViaImport(opts?: { manifest?: Manifest }) { }); } } catch (e) { - console.error("Error serving static file:", e); + console.error(`Error serving static file "${path}":`, String(e)); return c.text("File not found", 404); } } diff --git a/docs/content/docs/(documentation)/integration/(runtimes)/deno.mdx b/docs/content/docs/(documentation)/integration/(runtimes)/deno.mdx new file mode 100644 index 0000000..a26ada2 --- /dev/null +++ b/docs/content/docs/(documentation)/integration/(runtimes)/deno.mdx @@ -0,0 +1,105 @@ +--- +title: "Deno" +description: "Run bknd inside Deno" +tags: ["documentation"] +--- + +Deno is fully supported as a runtime for bknd. If you plan to solely use the API, the setup is pretty straightforward. + +```ts title="main.ts" +import { createAdapterApp } from "npm:bknd/adapter"; + +const app = await createAdapterApp({ + connection: { + url: "file:data.db", + }, +}); + +export default { + fetch: app.fetch, +}; +``` + +## Serve the Admin UI + +In order to also serve the static assets of the admin UI, you have 3 choices: + +1. Use the `serveStaticViaImport` function to serve the static assets from the `bknd` package directly (requires unstable `raw-imports`). +2. Copy the static assets to your local project and use Hono's `serveStatic` middleware. +3. Use the `adminOptions.assetsPath` property to point to a remote address with the static assets. + +### `serveStaticViaImport` + +The `serveStaticViaImport` function is a middleware that serves the static assets from the `bknd` package directly using dynamic raw imports. It requires the unstable `raw-imports` feature to be enabled. You can enable it by adding the following to your `deno.json`: + +```json title="deno.json" +{ + "unstable": ["raw-imports"] +} +``` + +Or by using the `--unstable-raw-imports` flag when running your script. Now create a `main.ts` file to serve the API and static assets: + +```ts title="main.ts" +import { createRuntimeApp, serveStaticViaImport } from "bknd/adapter"; + +const app = await createRuntimeApp({ + connection: { + url: "file:data.db", + }, + serveStatic: serveStaticViaImport() +}); + +export default { + fetch: app.fetch, +}; +``` + +### `serveStatic` from local files + +You can also serve the static assets from your local project by using Hono's `serveStatic` middleware. You can do so by copying the static assets to your local project and using the `serveStatic` middleware. First, you have to copy the static assets, by running the following command: + +```bash +deno run npm:bknd copy-assets --out public +``` + +This will copy the static assets to the `public` directory and then serve them from there: + +```ts title="main.ts" +import { createRuntimeApp, serveStatic } from "bknd/adapter"; +import { serveStatic } from "npm:hono/deno"; + +const app = await createRuntimeApp({ + connection: { + url: "file:data.db", + }, + serveStatic: serveStatic({ + root: "./public", + }), +}); + +export default { + fetch: app.fetch, +}; +``` + +### `adminOptions.assetsPath` + +You can also use the `adminOptions.assetsPath` property to point to a remote address with the static assets. This is useful in case none of the other methods work for you. + +```ts title="main.ts" +import { createRuntimeApp } from "bknd/adapter"; + +const app = await createRuntimeApp({ + connection: { + url: "file:data.db", + }, + adminOptions: { + assetsPath: "https://...", + }, +}); + +export default { + fetch: app.fetch, +}; +``` \ No newline at end of file diff --git a/docs/content/docs/(documentation)/integration/(runtimes)/meta.json b/docs/content/docs/(documentation)/integration/(runtimes)/meta.json index 9083adc..33c50b3 100644 --- a/docs/content/docs/(documentation)/integration/(runtimes)/meta.json +++ b/docs/content/docs/(documentation)/integration/(runtimes)/meta.json @@ -1,3 +1,3 @@ { - "pages": ["node", "bun", "cloudflare", "aws", "docker"] + "pages": ["node", "bun", "cloudflare", "deno", "aws", "docker"] } diff --git a/docs/content/docs/(documentation)/integration/introduction.mdx b/docs/content/docs/(documentation)/integration/introduction.mdx index 6d67d94..6330208 100644 --- a/docs/content/docs/(documentation)/integration/introduction.mdx +++ b/docs/content/docs/(documentation)/integration/introduction.mdx @@ -61,6 +61,12 @@ If you prefer to use a runtime instead of a framework, you can choose from the f href="/integration/cloudflare" /> +} + title="Deno" + href="/integration/deno" +/> + } title="AWS Lambda" diff --git a/docs/content/docs/(documentation)/start.mdx b/docs/content/docs/(documentation)/start.mdx index 8e664c6..91bfdd7 100644 --- a/docs/content/docs/(documentation)/start.mdx +++ b/docs/content/docs/(documentation)/start.mdx @@ -97,6 +97,12 @@ Start by using the integration guide for these popular frameworks/runtimes. Ther href="/integration/bun" /> +} + title="Deno" + href="/integration/deno" +/> + } title="AWS Lambda"