add sqlocal connection including example

This commit is contained in:
dswbx
2025-03-15 14:40:41 +01:00
parent 5697b7891a
commit 622a7b2b9a
22 changed files with 1047 additions and 56 deletions

24
examples/react/.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

1
examples/react/README.md Normal file
View File

@@ -0,0 +1 @@
# local bknd POC (WIP)

13
examples/react/index.html Normal file
View File

@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

View File

@@ -0,0 +1,28 @@
{
"name": "react",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"bknd": "file:../../app",
"@bknd/sqlocal": "file:../../packages/sqlocal",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"sqlocal": "^0.14.0"
},
"devDependencies": {
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^4.3.4",
"globals": "^15.15.0",
"typescript": "~5.7.2",
"typescript-eslint": "^8.24.1",
"vite": "^6.2.0"
}
}

View File

@@ -0,0 +1,71 @@
import { useEffect, useState } from "react";
import { App } from "bknd";
import { Admin } from "bknd/ui";
import { checksum } from "bknd/utils";
import { em, entity, text } from "bknd/data";
import { SQLocalConnection } from "@bknd/sqlocal";
import "bknd/dist/styles.css";
export default function () {
const [app, setApp] = useState<App | undefined>(undefined);
const [hash, setHash] = useState<string>("");
async function onBuilt(app: App) {
setApp(app);
setHash(await checksum(app.toJSON()));
}
useEffect(() => {
setup({
onBuilt,
})
.then((app) => console.log("setup", app?.version()))
.catch(console.error);
}, []);
if (!app) return null;
return (
// @ts-ignore
<Admin key={hash} withProvider={{ api: app.getApi() }} />
);
}
let initialized = false;
export async function setup(opts?: {
beforeBuild?: (app: App) => Promise<void>;
onBuilt?: (app: App) => Promise<void>;
}) {
if (initialized) return;
initialized = true;
const connection = new SQLocalConnection({
verbose: true,
});
const app = App.create({
connection,
initialConfig: {
data: em({
test: entity("test", {
name: text(),
}),
}).toJSON(),
},
});
if (opts?.onBuilt) {
app.emgr.onEvent(
App.Events.AppBuiltEvent,
async () => {
await opts.onBuilt?.(app);
},
"sync",
);
}
await opts?.beforeBuild?.(app);
await app.build({ sync: true });
return app;
}

View File

@@ -0,0 +1,9 @@
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>,
);

1
examples/react/src/vite-env.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference types="vite/client" />

View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noImplicitAny": false,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
}

View File

@@ -0,0 +1,23 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vite.dev/config/
// https://sqlocal.dallashoffman.com/guide/setup#vite-configuration
export default defineConfig({
optimizeDeps: {
exclude: ["sqlocal"],
},
plugins: [
react(),
{
name: "configure-response-headers",
configureServer: (server) => {
server.middlewares.use((_req, res, next) => {
res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
next();
});
},
},
],
});