mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-15 20:17:22 +00:00
init opfs and sqlocal as another browser adapter
This commit is contained in:
@@ -16,12 +16,12 @@
|
||||
"prepublishOnly": "bun run typecheck && bun run test && bun run build"
|
||||
},
|
||||
"dependencies": {
|
||||
"sqlocal": "^0.14.0"
|
||||
"sqlocal": "^0.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitest/browser": "^3.0.8",
|
||||
"@vitest/ui": "^3.0.8",
|
||||
"@types/node": "^22.13.10",
|
||||
"@types/node": "^24.10.1",
|
||||
"bknd": "workspace:*",
|
||||
"kysely": "^0.27.6",
|
||||
"tsup": "^8.4.0",
|
||||
|
||||
@@ -1,51 +1,44 @@
|
||||
import { Kysely, ParseJSONResultsPlugin } from "kysely";
|
||||
import { SqliteConnection, SqliteIntrospector } from "bknd/data";
|
||||
import { SQLocalKysely } from "sqlocal/kysely";
|
||||
import type { ClientConfig } from "sqlocal";
|
||||
import { SqliteConnection, SqliteIntrospector, type DB } from "bknd";
|
||||
import type { SQLocalKysely } from "sqlocal/kysely";
|
||||
|
||||
const plugins = [new ParseJSONResultsPlugin()];
|
||||
|
||||
export type SQLocalConnectionConfig = Omit<ClientConfig, "databasePath"> & {
|
||||
// make it optional
|
||||
databasePath?: ClientConfig["databasePath"];
|
||||
};
|
||||
export class SQLocalConnection extends SqliteConnection<SQLocalKysely> {
|
||||
private connected: boolean = false;
|
||||
|
||||
export class SQLocalConnection extends SqliteConnection {
|
||||
private _client: SQLocalKysely | undefined;
|
||||
|
||||
constructor(private config: SQLocalConnectionConfig) {
|
||||
super(null as any, {}, plugins);
|
||||
constructor(client: SQLocalKysely) {
|
||||
// @ts-expect-error - config is protected
|
||||
client.config.onConnect = () => {
|
||||
// we need to listen for the connection, it will be awaited in init()
|
||||
this.connected = true;
|
||||
};
|
||||
super({
|
||||
kysely: new Kysely<any>({
|
||||
dialect: {
|
||||
...client.dialect,
|
||||
createIntrospector: (db: Kysely<DB>) => {
|
||||
return new SqliteIntrospector(db as any, {
|
||||
plugins,
|
||||
});
|
||||
},
|
||||
},
|
||||
plugins,
|
||||
}) as any,
|
||||
});
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
override async init() {
|
||||
if (this.initialized) return;
|
||||
|
||||
await new Promise((resolve) => {
|
||||
this._client = new SQLocalKysely({
|
||||
...this.config,
|
||||
databasePath: this.config.databasePath ?? "session",
|
||||
onConnect: (r) => {
|
||||
this.kysely = new Kysely<any>({
|
||||
dialect: {
|
||||
...this._client!.dialect,
|
||||
createIntrospector: (db: Kysely<any>) => {
|
||||
return new SqliteIntrospector(db, {
|
||||
plugins,
|
||||
});
|
||||
},
|
||||
},
|
||||
plugins,
|
||||
});
|
||||
this.config.onConnect?.(r);
|
||||
resolve(1);
|
||||
},
|
||||
});
|
||||
});
|
||||
super.init();
|
||||
}
|
||||
|
||||
get client(): SQLocalKysely {
|
||||
if (!this._client) throw new Error("Client not initialized");
|
||||
return this._client!;
|
||||
let tries = 0;
|
||||
while (!this.connected && tries < 100) {
|
||||
tries++;
|
||||
await new Promise((resolve) => setTimeout(resolve, 5));
|
||||
}
|
||||
if (!this.connected) {
|
||||
throw new Error("Failed to connect to SQLite database");
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { SQLocalConnection, type SQLocalConnectionConfig } from "./SQLocalConnection";
|
||||
export { SQLocalConnection } from "./SQLocalConnection";
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { SQLocalConnection, type SQLocalConnectionConfig } from "../src";
|
||||
import { SQLocalConnection } from "../src";
|
||||
import type { ClientConfig } from "sqlocal";
|
||||
import { SQLocalKysely } from "sqlocal/kysely";
|
||||
|
||||
describe(SQLocalConnection, () => {
|
||||
function create(config: SQLocalConnectionConfig = {}) {
|
||||
return new SQLocalConnection(config);
|
||||
function create(config: ClientConfig = { databasePath: ":memory:" }) {
|
||||
return new SQLocalConnection(new SQLocalKysely(config));
|
||||
}
|
||||
|
||||
it("constructs", async () => {
|
||||
const connection = create();
|
||||
expect(() => connection.client).toThrow();
|
||||
await connection.init();
|
||||
expect(connection.client).toBeDefined();
|
||||
expect(await connection.client.sql`SELECT 1`).toEqual([{ "1": 1 }]);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { SQLocalConnection, type SQLocalConnectionConfig } from "../src";
|
||||
import { createApp } from "bknd";
|
||||
import * as proto from "bknd/data";
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { SQLocalConnection } from "../src";
|
||||
import { createApp, em, entity, text } from "bknd";
|
||||
import type { ClientConfig } from "sqlocal";
|
||||
import { SQLocalKysely } from "sqlocal/kysely";
|
||||
|
||||
describe("integration", () => {
|
||||
function create(config: SQLocalConnectionConfig = { databasePath: ":memory:" }) {
|
||||
return new SQLocalConnection(config);
|
||||
function create(config: ClientConfig = { databasePath: ":memory:" }) {
|
||||
return new SQLocalConnection(new SQLocalKysely(config));
|
||||
}
|
||||
|
||||
it("should create app and ping", async () => {
|
||||
@@ -19,14 +20,14 @@ describe("integration", () => {
|
||||
});
|
||||
|
||||
it("should create a basic schema", async () => {
|
||||
const schema = proto.em(
|
||||
const schema = em(
|
||||
{
|
||||
posts: proto.entity("posts", {
|
||||
title: proto.text().required(),
|
||||
content: proto.text(),
|
||||
posts: entity("posts", {
|
||||
title: text().required(),
|
||||
content: text(),
|
||||
}),
|
||||
comments: proto.entity("comments", {
|
||||
content: proto.text(),
|
||||
comments: entity("comments", {
|
||||
content: text(),
|
||||
}),
|
||||
},
|
||||
(fns, s) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// <reference types="vitest" />
|
||||
/// <reference types="@vitest/browser/providers/webdriverio" />
|
||||
import { defineConfig } from "vite";
|
||||
import { defineConfig } from "vitest/config";
|
||||
|
||||
// https://github.com/DallasHoff/sqlocal/blob/main/vite.config.ts
|
||||
export default defineConfig({
|
||||
|
||||
Reference in New Issue
Block a user