diff --git a/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts b/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts index cfcba5d..e666cf6 100644 --- a/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts +++ b/app/src/adapter/cloudflare/cloudflare-workers.adapter.ts @@ -11,6 +11,7 @@ export type CloudflareBkndConfig = FrameworkBkndConfig> kv?: KVNamespace; dobj?: DurableObjectNamespace; }; + static?: "kv" | "assets"; key?: string; keepAliveSeconds?: number; forceHttps?: boolean; @@ -29,18 +30,23 @@ export function serve(config: CloudflareBkndConfig) { return { async fetch(request: Request, env: Env, ctx: ExecutionContext) { const url = new URL(request.url); - const manifest = config.manifest; - if (manifest) { + if (config.manifest && config.static === "assets") { + console.warn("manifest is not useful with static 'assets'"); + } else if (!config.manifest && config.static === "kv") { + throw new Error("manifest is required with static 'kv'"); + } + + if (config.manifest && config.static !== "assets") { const pathname = url.pathname.slice(1); - const assetManifest = JSON.parse(manifest); + const assetManifest = JSON.parse(config.manifest); if (pathname && pathname in assetManifest) { const hono = new Hono(); hono.all("*", async (c, next) => { const res = await serveStatic({ path: `./${pathname}`, - manifest + manifest: config.manifest! })(c as any, next); if (res instanceof Response) { const ttl = 60 * 60 * 24 * 365; diff --git a/app/src/core/utils/typebox/index.ts b/app/src/core/utils/typebox/index.ts index a793e33..9e6f2d6 100644 --- a/app/src/core/utils/typebox/index.ts +++ b/app/src/core/utils/typebox/index.ts @@ -21,7 +21,6 @@ import { type ValueErrorIterator } from "@sinclair/typebox/errors"; import { Check, Default, Value, type ValueError } from "@sinclair/typebox/value"; -import { cloneDeep } from "lodash-es"; export type RecursivePartial = { [P in keyof T]?: T[P] extends (infer U)[] @@ -73,7 +72,7 @@ export class TypeInvalidError extends Error { } export function stripMark(obj: O) { - const newObj = cloneDeep(obj); + const newObj = structuredClone(obj); mark(newObj, false); return newObj as O; } diff --git a/docs/integration/cloudflare.mdx b/docs/integration/cloudflare.mdx index 6cf92ee..04926be 100644 --- a/docs/integration/cloudflare.mdx +++ b/docs/integration/cloudflare.mdx @@ -16,7 +16,7 @@ and then install bknd as a dependency: If you don't choose anything specific, the following code will use the `warm` mode. See the chapter [Using a different mode](#using-a-different-mode) for available modes. -```ts +```ts src/index.ts import { serve } from "bknd/adapter/cloudflare"; export default serve({ @@ -42,32 +42,37 @@ And confirm it works by opening [http://localhost:8787](http://localhost:8787) i your browser. ## Serve the Admin UI -Now in order to also server the static admin files, you have to modify the `wrangler.toml` to -include the static assets: -```toml -[site] -bucket = "node_modules/bknd/dist/static" -``` +Now in order to also server the static admin files, you have to modify the `wrangler.toml` to include the static assets. You can do so by either serving the static using the new [Assets feature](https://developers.cloudflare.com/workers/static-assets/), or the deprecated [Workers Site](https://developers.cloudflare.com/workers/configuration/sites/configuration/). -And then modify the worker entry as follows: -```ts {2, 14, 15} -import { serve } from "bknd/adapter/cloudflare"; -import manifest from "__STATIC_CONTENT_MANIFEST"; + + + Make sure your assets point to the static assets included in the bknd package: -export default serve({ - app: ({ env }) => ({ - connection: { - type: "libsql", - config: { - url: env.DB_URL, - authToken: env.DB_TOKEN - } - } - }), - manifest, - setAdminHtml: true -}); -``` + ```toml wrangler.toml + assets = { directory = "node_modules/bknd/dist/static" } + ``` + + + + Make sure your site points to the static assets included in the bknd package: + + ```toml wrangler.toml + [site] + bucket = "node_modules/bknd/dist/static" + ``` + + And then modify the worker entry as follows: + ```ts {2, 6} src/index.ts + import { serve } from "bknd/adapter/cloudflare"; + import manifest from "__STATIC_CONTENT_MANIFEST"; + + export default serve({ + app: () => ({/* ... */}), + manifest + }); + ``` + + ## Adding custom routes You can also add custom routes by defining them after the app has been built, like so: diff --git a/examples/cloudflare-worker/src/index.ts b/examples/cloudflare-worker/src/index.ts index dbb2e9b..628c490 100644 --- a/examples/cloudflare-worker/src/index.ts +++ b/examples/cloudflare-worker/src/index.ts @@ -1,7 +1,5 @@ import { serve } from "bknd/adapter/cloudflare"; -import manifest from "__STATIC_CONTENT_MANIFEST"; - export default serve({ app: (args) => ({ connection: { @@ -13,6 +11,5 @@ export default serve({ }), onBuilt: async (app) => { app.modules.server.get("/custom", (c) => c.json({ hello: "world" })); - }, - manifest + } }); diff --git a/examples/cloudflare-worker/wrangler.toml b/examples/cloudflare-worker/wrangler.toml index 86fe17d..27157d0 100644 --- a/examples/cloudflare-worker/wrangler.toml +++ b/examples/cloudflare-worker/wrangler.toml @@ -5,9 +5,10 @@ compatibility_date = "2024-11-06" compatibility_flags = ["nodejs_compat"] workers_dev = true minify = true +assets = { directory = "../../app/dist/static" } [observability] enabled = true -[site] -bucket = "../../app/dist/static" \ No newline at end of file +#[site] +#bucket = "../../app/dist/static" \ No newline at end of file