refactored adapters to run test suites (#126)

* refactored adapters to run test suites

* fix bun version for tests

* added missing adapter tests and refactored examples to use `bknd.config.ts` where applicable
This commit is contained in:
dswbx
2025-04-01 11:43:11 +02:00
committed by GitHub
parent 36e4224b33
commit 3f26c45dd9
55 changed files with 1130 additions and 647 deletions
+8 -13
View File
@@ -1,8 +1,12 @@
import { App } from "bknd";
import { createRuntimeApp } from "bknd/adapter";
import { type CloudflareBkndConfig, constants, type Context, makeCfConfig } from "../index";
import type { CloudflareBkndConfig, Context, CloudflareEnv } from "../index";
import { makeConfig, registerAsyncsExecutionContext, constants } from "../config";
export async function getCached(config: CloudflareBkndConfig, { env, ctx, ...args }: Context) {
export async function getCached<Env extends CloudflareEnv = CloudflareEnv>(
config: CloudflareBkndConfig<Env>,
{ env, ctx, ...args }: Context<Env>,
) {
const { kv } = config.bindings?.(env)!;
if (!kv) throw new Error("kv namespace is not defined in cloudflare.bindings");
const key = config.key ?? "app";
@@ -16,9 +20,10 @@ export async function getCached(config: CloudflareBkndConfig, { env, ctx, ...arg
const app = await createRuntimeApp(
{
...makeCfConfig(config, { env, ctx, ...args }),
...makeConfig(config, env),
initialConfig,
onBuilt: async (app) => {
registerAsyncsExecutionContext(app, ctx);
app.module.server.client.get(constants.cache_endpoint, async (c) => {
await kv.delete(key);
return c.json({ message: "Cache cleared" });
@@ -26,16 +31,6 @@ export async function getCached(config: CloudflareBkndConfig, { env, ctx, ...arg
await config.onBuilt?.(app);
},
beforeBuild: async (app) => {
app.emgr.onEvent(
App.Events.AppBeforeResponse,
async (event) => {
ctx.waitUntil(event.params.app.emgr.executeAsyncs());
},
{
mode: "sync",
id: constants.exec_async_event_id,
},
);
app.emgr.onEvent(
App.Events.AppConfigUpdatedEvent,
async ({ params: { app } }) => {
+9 -14
View File
@@ -1,9 +1,13 @@
import { DurableObject } from "cloudflare:workers";
import { App, type CreateAppConfig } from "bknd";
import type { App, CreateAppConfig } from "bknd";
import { createRuntimeApp, makeConfig } from "bknd/adapter";
import { type CloudflareBkndConfig, type Context, constants } from "../index";
import type { CloudflareBkndConfig, Context, CloudflareEnv } from "../index";
import { constants, registerAsyncsExecutionContext } from "../config";
export async function getDurable(config: CloudflareBkndConfig, ctx: Context) {
export async function getDurable<Env extends CloudflareEnv = CloudflareEnv>(
config: CloudflareBkndConfig<Env>,
ctx: Context<Env>,
) {
const { dobj } = config.bindings?.(ctx.env)!;
if (!dobj) throw new Error("durable object is not defined in cloudflare.bindings");
const key = config.key ?? "app";
@@ -17,7 +21,7 @@ export async function getDurable(config: CloudflareBkndConfig, ctx: Context) {
const id = dobj.idFromName(key);
const stub = dobj.get(id) as unknown as DurableBkndApp;
const create_config = makeConfig(config, ctx);
const create_config = makeConfig(config, ctx.env);
const res = await stub.fire(ctx.request, {
config: create_config,
@@ -67,16 +71,7 @@ export class DurableBkndApp extends DurableObject {
this.app = await createRuntimeApp({
...config,
onBuilt: async (app) => {
app.emgr.onEvent(
App.Events.AppBeforeResponse,
async (event) => {
this.ctx.waitUntil(event.params.app.emgr.executeAsyncs());
},
{
mode: "sync",
id: constants.exec_async_event_id,
},
);
registerAsyncsExecutionContext(app, this.ctx);
app.modules.server.get(constants.do_endpoint, async (c) => {
// @ts-ignore
const context: any = c.req.raw.cf ? c.req.raw.cf : c.env.cf;
+37 -29
View File
@@ -1,40 +1,48 @@
import { App } from "bknd";
import { createRuntimeApp } from "bknd/adapter";
import { type CloudflareBkndConfig, type Context, makeCfConfig, constants } from "../index";
import { createRuntimeApp, type RuntimeOptions } from "bknd/adapter";
import type { CloudflareBkndConfig, Context, CloudflareEnv } from "../index";
import { makeConfig, registerAsyncsExecutionContext } from "../config";
export async function makeApp(config: CloudflareBkndConfig, ctx: Context) {
return await createRuntimeApp(
export async function makeApp<Env extends CloudflareEnv = CloudflareEnv>(
config: CloudflareBkndConfig<Env>,
args: Env = {} as Env,
opts?: RuntimeOptions,
) {
return await createRuntimeApp<Env>(
{
...makeCfConfig(config, ctx),
...makeConfig(config, args),
adminOptions: config.html ? { html: config.html } : undefined,
onBuilt: async (app) => {
app.emgr.onEvent(
App.Events.AppBeforeResponse,
async (event) => {
ctx.ctx.waitUntil(event.params.app.emgr.executeAsyncs());
},
{
mode: "sync",
id: constants.exec_async_event_id,
},
);
await config.onBuilt?.(app);
},
},
ctx,
args,
opts,
);
}
export async function getFresh(config: CloudflareBkndConfig, ctx: Context) {
const app = await makeApp(config, ctx);
export async function getWarm<Env extends CloudflareEnv = CloudflareEnv>(
config: CloudflareBkndConfig<Env>,
ctx: Context<Env>,
opts: RuntimeOptions = {},
) {
const app = await makeApp(
{
...config,
onBuilt: async (app) => {
registerAsyncsExecutionContext(app, ctx.ctx);
config.onBuilt?.(app);
},
},
ctx.env,
opts,
);
return app.fetch(ctx.request);
}
let warm_app: App;
export async function getWarm(config: CloudflareBkndConfig, ctx: Context) {
if (!warm_app) {
warm_app = await makeApp(config, ctx);
}
return warm_app.fetch(ctx.request);
export async function getFresh<Env extends CloudflareEnv = CloudflareEnv>(
config: CloudflareBkndConfig<Env>,
ctx: Context<Env>,
opts: RuntimeOptions = {},
) {
return await getWarm(config, ctx, {
...opts,
force: true,
});
}