mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
fix cloudflare adapter warm mode and type improvements
Adds warm mode support to cloudflare adapter to enable app instance caching. Improves BkndConfig type handling and makes hybrid mode reader optional. Fixes entity hook types to properly handle Generated ID types from kysely.
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
import type { RuntimeBkndConfig } from "bknd/adapter";
|
import type { RuntimeBkndConfig } from "bknd/adapter";
|
||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { serveStatic } from "hono/cloudflare-workers";
|
import { serveStatic } from "hono/cloudflare-workers";
|
||||||
import type { MaybePromise } from "bknd";
|
import type { App, MaybePromise } from "bknd";
|
||||||
import { $console } from "bknd/utils";
|
import { $console } from "bknd/utils";
|
||||||
import { createRuntimeApp } from "bknd/adapter";
|
import { createRuntimeApp } from "bknd/adapter";
|
||||||
import { registerAsyncsExecutionContext, makeConfig, type CloudflareContext } from "./config";
|
import { registerAsyncsExecutionContext, makeConfig, type CloudflareContext } from "./config";
|
||||||
@@ -55,8 +55,12 @@ export async function createApp<Env extends CloudflareEnv = CloudflareEnv>(
|
|||||||
// compatiblity
|
// compatiblity
|
||||||
export const getFresh = createApp;
|
export const getFresh = createApp;
|
||||||
|
|
||||||
|
let app: App | undefined;
|
||||||
export function serve<Env extends CloudflareEnv = CloudflareEnv>(
|
export function serve<Env extends CloudflareEnv = CloudflareEnv>(
|
||||||
config: CloudflareBkndConfig<Env> = {},
|
config: CloudflareBkndConfig<Env> = {},
|
||||||
|
serveOptions?: (args: Env) => {
|
||||||
|
warm?: boolean;
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
|
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
|
||||||
@@ -92,8 +96,11 @@ export function serve<Env extends CloudflareEnv = CloudflareEnv>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { warm } = serveOptions?.(env) ?? {};
|
||||||
|
if (!app || warm !== true) {
|
||||||
const context = { request, env, ctx } as CloudflareContext<Env>;
|
const context = { request, env, ctx } as CloudflareContext<Env>;
|
||||||
const app = await createApp(config, context);
|
app = await createApp(config, context);
|
||||||
|
}
|
||||||
|
|
||||||
return app.fetch(request, env, ctx);
|
return app.fetch(request, env, ctx);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,14 +14,15 @@ import type { AdminControllerOptions } from "modules/server/AdminController";
|
|||||||
import type { Manifest } from "vite";
|
import type { Manifest } from "vite";
|
||||||
|
|
||||||
export type BkndConfig<Args = any, Additional = {}> = Merge<
|
export type BkndConfig<Args = any, Additional = {}> = Merge<
|
||||||
CreateAppConfig & {
|
CreateAppConfig &
|
||||||
|
Omit<Additional, "app"> & {
|
||||||
app?:
|
app?:
|
||||||
| Merge<Omit<BkndConfig, "app"> & Additional>
|
| Omit<BkndConfig<Args, Additional>, "app">
|
||||||
| ((args: Args) => MaybePromise<Merge<Omit<BkndConfig<Args>, "app"> & Additional>>);
|
| ((args: Args) => MaybePromise<Omit<BkndConfig<Args, Additional>, "app">>);
|
||||||
onBuilt?: (app: App) => MaybePromise<void>;
|
onBuilt?: (app: App) => MaybePromise<void>;
|
||||||
beforeBuild?: (app?: App, registries?: typeof $registries) => MaybePromise<void>;
|
beforeBuild?: (app?: App, registries?: typeof $registries) => MaybePromise<void>;
|
||||||
buildConfig?: Parameters<App["build"]>[0];
|
buildConfig?: Parameters<App["build"]>[0];
|
||||||
} & Additional
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type FrameworkBkndConfig<Args = any> = BkndConfig<Args>;
|
export type FrameworkBkndConfig<Args = any> = BkndConfig<Args>;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export type BkndHybridModeOptions = {
|
|||||||
* Reader function to read the configuration from the file system.
|
* Reader function to read the configuration from the file system.
|
||||||
* This is required for hybrid mode to work.
|
* This is required for hybrid mode to work.
|
||||||
*/
|
*/
|
||||||
reader: (path: string) => MaybePromise<string | object>;
|
reader?: (path: string) => MaybePromise<string | object>;
|
||||||
/**
|
/**
|
||||||
* Provided secrets to be merged into the configuration
|
* Provided secrets to be merged into the configuration
|
||||||
*/
|
*/
|
||||||
@@ -47,7 +47,7 @@ export function hybrid<
|
|||||||
"You must set a `reader` option when using hybrid mode",
|
"You must set a `reader` option when using hybrid mode",
|
||||||
);
|
);
|
||||||
|
|
||||||
const fileContent = await appConfig.reader(configFilePath);
|
const fileContent = await appConfig.reader?.(configFilePath);
|
||||||
let fileConfig = typeof fileContent === "string" ? JSON.parse(fileContent) : fileContent;
|
let fileConfig = typeof fileContent === "string" ? JSON.parse(fileContent) : fileContent;
|
||||||
if (!fileConfig) {
|
if (!fileConfig) {
|
||||||
$console.warn("No config found, using default config");
|
$console.warn("No config found, using default config");
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import type {
|
|||||||
ModuleApi,
|
ModuleApi,
|
||||||
} from "bknd";
|
} from "bknd";
|
||||||
import { objectTransform, encodeSearch } from "bknd/utils";
|
import { objectTransform, encodeSearch } from "bknd/utils";
|
||||||
import type { Insertable, Selectable, Updateable } from "kysely";
|
import type { Insertable, Selectable, Updateable, Generated } from "kysely";
|
||||||
import useSWR, { type SWRConfiguration, type SWRResponse, mutate } from "swr";
|
import useSWR, { type SWRConfiguration, type SWRResponse, mutate } from "swr";
|
||||||
import { type Api, useApi } from "ui/client";
|
import { type Api, useApi } from "ui/client";
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@ interface UseEntityReturn<
|
|||||||
Entity extends keyof DB | string,
|
Entity extends keyof DB | string,
|
||||||
Id extends PrimaryFieldType | undefined,
|
Id extends PrimaryFieldType | undefined,
|
||||||
Data = Entity extends keyof DB ? DB[Entity] : EntityData,
|
Data = Entity extends keyof DB ? DB[Entity] : EntityData,
|
||||||
|
ActualId = Data extends { id: infer I } ? (I extends Generated<infer T> ? T : I) : never,
|
||||||
Response = ResponseObject<RepositoryResult<Selectable<Data>>>,
|
Response = ResponseObject<RepositoryResult<Selectable<Data>>>,
|
||||||
> {
|
> {
|
||||||
create: (input: Insertable<Data>) => Promise<Response>;
|
create: (input: Insertable<Data>) => Promise<Response>;
|
||||||
@@ -42,9 +43,11 @@ interface UseEntityReturn<
|
|||||||
ResponseObject<RepositoryResult<Id extends undefined ? Selectable<Data>[] : Selectable<Data>>>
|
ResponseObject<RepositoryResult<Id extends undefined ? Selectable<Data>[] : Selectable<Data>>>
|
||||||
>;
|
>;
|
||||||
update: Id extends undefined
|
update: Id extends undefined
|
||||||
? (input: Updateable<Data>, id: Id) => Promise<Response>
|
? (input: Updateable<Data>, id: ActualId) => Promise<Response>
|
||||||
: (input: Updateable<Data>) => Promise<Response>;
|
: (input: Updateable<Data>) => Promise<Response>;
|
||||||
_delete: Id extends undefined ? (id: Id) => Promise<Response> : () => Promise<Response>;
|
_delete: Id extends undefined
|
||||||
|
? (id: PrimaryFieldType) => Promise<Response>
|
||||||
|
: () => Promise<Response>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useEntity = <
|
export const useEntity = <
|
||||||
|
|||||||
Reference in New Issue
Block a user