feat: adding env aware endpoint to obtain sqlite connection, remove libsql hard dependency

This commit is contained in:
dswbx
2025-06-13 11:09:47 +02:00
parent 046c1d21b1
commit bbb7bfb7a1
28 changed files with 288 additions and 159 deletions

View File

@@ -1,11 +1,18 @@
/// <reference types="bun-types" />
import path from "node:path";
import { type RuntimeBkndConfig, createRuntimeApp, type RuntimeOptions } from "bknd/adapter";
import { registerLocalMediaAdapter } from "bknd/adapter/node";
import {
type RuntimeBkndConfig,
createRuntimeApp,
type RuntimeOptions,
Connection,
} from "bknd/adapter";
import { registerLocalMediaAdapter } from ".";
import { config } from "bknd/core";
import type { ServeOptions } from "bun";
import { serveStatic } from "hono/bun";
import { sqlite } from "bknd/adapter/sqlite";
import type { App } from "App";
type BunEnv = Bun.Env;
export type BunBkndConfig<Env = BunEnv> = RuntimeBkndConfig<Env> & Omit<ServeOptions, "fetch">;
@@ -18,9 +25,17 @@ export async function createApp<Env = BunEnv>(
const root = path.resolve(distPath ?? "./node_modules/bknd/dist", "static");
registerLocalMediaAdapter();
let connection: Connection | undefined;
if (Connection.isConnection(config.connection)) {
connection = config.connection;
} else {
connection = sqlite(config.connection ?? { url: ":memory:" });
}
return await createRuntimeApp(
{
...config,
connection,
serveStatic: serveStatic({ root }),
},
args ?? (process.env as Env),
@@ -33,8 +48,11 @@ export function createHandler<Env = BunEnv>(
args: Env = {} as Env,
opts?: RuntimeOptions,
) {
let app: App | undefined;
return async (req: Request) => {
const app = await createApp(config, args ?? (process.env as Env), opts);
if (!app) {
app = await createApp(config, args ?? (process.env as Env), opts);
}
return app.fetch(req);
};
}
@@ -72,5 +90,5 @@ export function serve<Env = BunEnv>(
),
});
console.log(`Server is running on http://localhost:${port}`);
console.info(`Server is running on http://localhost:${port}`);
}

View File

@@ -1,4 +1,4 @@
import type { Database } from "bun:sqlite";
import { Database } from "bun:sqlite";
import {
buildQueryFn,
GenericSqliteConnection,
@@ -30,12 +30,19 @@ function bunSqliteExecutor(db: Database, cache: boolean): IGenericSqlite<Databas
};
}
export function bunSqlite(config: BunSqliteConnectionConfig) {
return new GenericSqliteConnection(
config.database,
() => bunSqliteExecutor(config.database, false),
{
name: "bun-sqlite",
},
);
export function bunSqlite(config?: BunSqliteConnectionConfig | { url: string }) {
let database: Database;
if (config) {
if ("database" in config) {
database = config.database;
} else {
database = new Database(config.url);
}
} else {
database = new Database(":memory:");
}
return new GenericSqliteConnection(database, () => bunSqliteExecutor(database, false), {
name: "bun-sqlite",
});
}

View File

@@ -1 +1,3 @@
export * from "./bun.adapter";
export * from "../node/storage";
export * from "./connection/BunSqliteConnection";

View File

@@ -64,7 +64,7 @@ export class DurableBkndApp extends DurableObject {
"type" in config.connection &&
config.connection.type === "libsql"
) {
config.connection.config.protocol = "wss";
//config.connection.config.protocol = "wss";
}
this.app = await createRuntimeApp({

View File

@@ -3,6 +3,8 @@ import { config as $config } from "bknd/core";
import type { MiddlewareHandler } from "hono";
import type { AdminControllerOptions } from "modules/server/AdminController";
export { Connection } from "bknd/data";
export type BkndConfig<Args = any> = CreateAppConfig & {
app?: CreateAppConfig | ((args: Args) => CreateAppConfig);
onBuilt?: (app: App) => Promise<void>;

View File

@@ -4,7 +4,7 @@ import {
parseBigInt,
type IGenericSqlite,
} from "../../../data/connection/sqlite/GenericSqliteConnection";
import type { DatabaseSync } from "node:sqlite";
import { DatabaseSync } from "node:sqlite";
export type NodeSqliteConnectionConfig = {
database: DatabaseSync;
@@ -39,8 +39,19 @@ function nodeSqliteExecutor(db: DatabaseSync): IGenericSqlite<DatabaseSync> {
};
}
export function nodeSqlite(config: NodeSqliteConnectionConfig) {
return new GenericSqliteConnection(config.database, () => nodeSqliteExecutor(config.database), {
export function nodeSqlite(config?: NodeSqliteConnectionConfig | { url: string }) {
let database: DatabaseSync;
if (config) {
if ("database" in config) {
database = config.database;
} else {
database = new DatabaseSync(config.url);
}
} else {
database = new DatabaseSync(":memory:");
}
return new GenericSqliteConnection(database, () => nodeSqliteExecutor(database), {
name: "node-sqlite",
});
}

View File

@@ -1,18 +1,3 @@
import { registries } from "bknd";
import { type LocalAdapterConfig, StorageLocalAdapter } from "./storage/StorageLocalAdapter";
export * from "./node.adapter";
export { StorageLocalAdapter, type LocalAdapterConfig };
let registered = false;
export function registerLocalMediaAdapter() {
if (!registered) {
registries.media.register("local", StorageLocalAdapter);
registered = true;
}
return (config: Partial<LocalAdapterConfig> = {}) => {
const adapter = new StorageLocalAdapter(config);
return adapter.toJSON(true);
};
}
export * from "./storage";
export * from "./connection/NodeSqliteConnection";

View File

@@ -2,9 +2,16 @@ import path from "node:path";
import { serve as honoServe } from "@hono/node-server";
import { serveStatic } from "@hono/node-server/serve-static";
import { registerLocalMediaAdapter } from "adapter/node/index";
import { type RuntimeBkndConfig, createRuntimeApp, type RuntimeOptions } from "bknd/adapter";
import {
type RuntimeBkndConfig,
createRuntimeApp,
type RuntimeOptions,
Connection,
} from "bknd/adapter";
import { config as $config } from "bknd/core";
import { $console } from "core";
import { sqlite } from "bknd/adapter/sqlite";
import type { App } from "App";
type NodeEnv = NodeJS.ProcessEnv;
export type NodeBkndConfig<Env = NodeEnv> = RuntimeBkndConfig<Env> & {
@@ -28,10 +35,18 @@ export async function createApp<Env = NodeEnv>(
console.warn("relativeDistPath is deprecated, please use distPath instead");
}
let connection: Connection | undefined;
if (Connection.isConnection(config.connection)) {
connection = config.connection;
} else {
connection = sqlite(config.connection ?? { url: ":memory:" });
}
registerLocalMediaAdapter();
return await createRuntimeApp(
{
...config,
connection,
serveStatic: serveStatic({ root }),
},
// @ts-ignore
@@ -45,8 +60,11 @@ export function createHandler<Env = NodeEnv>(
args: Env = {} as Env,
opts?: RuntimeOptions,
) {
let app: App | undefined;
return async (req: Request) => {
const app = await createApp(config, args ?? (process.env as Env), opts);
if (!app) {
app = await createApp(config, args ?? (process.env as Env), opts);
}
return app.fetch(req);
};
}

View File

@@ -0,0 +1,17 @@
import { registries } from "bknd";
import { type LocalAdapterConfig, StorageLocalAdapter } from "./StorageLocalAdapter";
export * from "./StorageLocalAdapter";
let registered = false;
export function registerLocalMediaAdapter() {
if (!registered) {
registries.media.register("local", StorageLocalAdapter);
registered = true;
}
return (config: Partial<LocalAdapterConfig> = {}) => {
const adapter = new StorageLocalAdapter(config);
return adapter.toJSON(true);
};
}

View File

@@ -0,0 +1,8 @@
import type { Connection } from "bknd/data";
import { $console } from "bknd/core";
import { bunSqlite } from "../bun/connection/BunSqliteConnection";
export function sqlite(config: { url: string }): Connection {
$console.info("Using bun-sqlite", config);
return bunSqlite(config);
}

View File

@@ -0,0 +1,8 @@
import { $console } from "bknd/core";
import type { Connection } from "bknd/data";
import { libsql } from "../../data/connection/sqlite/LibsqlConnection";
export function sqlite(config: { url: string }): Connection {
$console.info("Using libsql", config);
return libsql(config);
}

View File

@@ -0,0 +1,8 @@
import { $console } from "bknd/core";
import type { Connection } from "bknd/data";
import { nodeSqlite } from "../node/connection/NodeSqliteConnection";
export function sqlite(config: { url: string }): Connection {
$console.info("Using node-sqlite", config);
return nodeSqlite(config);
}

View File

@@ -0,0 +1,3 @@
import type { Connection } from "bknd/data";
export type SqliteConnection = (config: { url: string }) => Connection;