mirror of
https://github.com/zadam/trilium.git
synced 2026-01-18 20:44:26 +01:00
feat(client/lightweight): integrate SQLite
This commit is contained in:
parent
d3941752f1
commit
5d474150da
@ -28,6 +28,7 @@
|
||||
"@mind-elixir/node-menu": "5.0.1",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"@preact/signals": "2.5.1",
|
||||
"@sqlite.org/sqlite-wasm": "3.51.1-build2",
|
||||
"@triliumnext/ckeditor5": "workspace:*",
|
||||
"@triliumnext/codemirror": "workspace:*",
|
||||
"@triliumnext/commons": "workspace:*",
|
||||
|
||||
@ -2,8 +2,16 @@
|
||||
// This will eventually import your core server and DB provider.
|
||||
// import { createCoreServer } from "@trilium/core"; (bundled)
|
||||
|
||||
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
// SQLite WASM instance
|
||||
let sqlite3: any = null;
|
||||
let db: any = null;
|
||||
let sqliteInitPromise: Promise<void> | null = null;
|
||||
let sqliteInitError: string | null = null;
|
||||
|
||||
function jsonResponse(obj, status = 200, extraHeaders = {}) {
|
||||
const body = encoder.encode(JSON.stringify(obj)).buffer;
|
||||
return {
|
||||
@ -22,8 +30,94 @@ function textResponse(text, status = 200, extraHeaders = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
// Initialize SQLite WASM
|
||||
async function initSQLite() {
|
||||
if (sqlite3) return; // Already initialized
|
||||
if (sqliteInitError) return; // Failed before, don't retry
|
||||
if (sqliteInitPromise) return sqliteInitPromise; // Already initializing
|
||||
|
||||
sqliteInitPromise = (async () => {
|
||||
try {
|
||||
console.log("[Worker] Initializing SQLite WASM...");
|
||||
const startTime = performance.now();
|
||||
|
||||
// Just call the init module without custom locateFile
|
||||
// The module will use import.meta.url to find sqlite3.wasm
|
||||
sqlite3 = await sqlite3InitModule({
|
||||
print: console.log,
|
||||
printErr: console.error,
|
||||
});
|
||||
|
||||
const initTime = performance.now() - startTime;
|
||||
console.log(`[Worker] SQLite WASM initialized in ${initTime.toFixed(2)}ms:`, sqlite3.version);
|
||||
|
||||
// Open a database in memory for now
|
||||
db = new sqlite3.oo1.DB(':memory:', 'c');
|
||||
console.log("[Worker] Database opened");
|
||||
|
||||
// Create a simple test table
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS options (
|
||||
name TEXT PRIMARY KEY,
|
||||
value TEXT
|
||||
);
|
||||
INSERT INTO options (name, value) VALUES
|
||||
('theme', 'dark'),
|
||||
('layoutOrientation', 'vertical'),
|
||||
('headingStyle', 'default');
|
||||
`);
|
||||
console.log("[Worker] Test table created and populated");
|
||||
} catch (error) {
|
||||
sqliteInitError = String(error);
|
||||
console.error("[Worker] SQLite initialization failed:", error);
|
||||
throw error;
|
||||
}
|
||||
})();
|
||||
|
||||
return sqliteInitPromise;
|
||||
}
|
||||
|
||||
// Example: your /bootstrap handler placeholder
|
||||
function handleBootstrap() {
|
||||
async function handleBootstrap() {
|
||||
console.log("[Worker] Bootstrap request received");
|
||||
|
||||
// Try to initialize SQLite with timeout
|
||||
let dbInfo: any = { dbStatus: 'not initialized' };
|
||||
|
||||
if (sqliteInitError) {
|
||||
dbInfo = { dbStatus: 'failed', error: sqliteInitError };
|
||||
} else {
|
||||
try {
|
||||
// Don't wait too long for SQLite initialization
|
||||
await Promise.race([
|
||||
initSQLite(),
|
||||
new Promise((_, reject) => setTimeout(() => reject(new Error("SQLite init timeout")), 5000))
|
||||
]);
|
||||
|
||||
// Query the database if initialized
|
||||
if (db) {
|
||||
const stmt = db.prepare('SELECT * FROM options');
|
||||
const options: Record<string, string> = {};
|
||||
while (stmt.step()) {
|
||||
const row = stmt.get({});
|
||||
options[row.name] = row.value;
|
||||
}
|
||||
stmt.finalize();
|
||||
|
||||
dbInfo = {
|
||||
sqliteVersion: sqlite3.version.libVersion,
|
||||
optionsFromDB: options,
|
||||
dbStatus: 'connected'
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("[Worker] Error during bootstrap:", e);
|
||||
dbInfo = { dbStatus: 'error', error: String(e) };
|
||||
}
|
||||
}
|
||||
|
||||
console.log("[Worker] Sending bootstrap response");
|
||||
|
||||
// Later: return real globals from your core state/config.
|
||||
return jsonResponse({
|
||||
assetPath: "assets",
|
||||
@ -37,7 +131,9 @@ function handleBootstrap() {
|
||||
isElectron: false,
|
||||
hasNativeTitleBar: false,
|
||||
hasBackgroundEffects: true,
|
||||
currentLocale: { id: "en", rtl: false }
|
||||
currentLocale: { id: "en", rtl: false },
|
||||
// Add SQLite info for testing
|
||||
sqlite: dbInfo
|
||||
});
|
||||
}
|
||||
|
||||
@ -45,7 +141,7 @@ function handleBootstrap() {
|
||||
async function dispatch(request) {
|
||||
const url = new URL(request.url);
|
||||
|
||||
console.log("Dispatch ", url);
|
||||
console.log("[Worker] Dispatch:", url.pathname);
|
||||
// NOTE: your core router will do this later.
|
||||
if (request.method === "GET" && url.pathname === "/bootstrap") {
|
||||
return handleBootstrap();
|
||||
@ -58,14 +154,22 @@ async function dispatch(request) {
|
||||
return textResponse("Not found", 404);
|
||||
}
|
||||
|
||||
// Start SQLite initialization as soon as the worker loads (in background)
|
||||
console.log("[Worker] Starting background SQLite initialization...");
|
||||
initSQLite().catch(err => {
|
||||
console.error("[Worker] Background SQLite init failed:", err);
|
||||
});
|
||||
|
||||
self.onmessage = async (event) => {
|
||||
const msg = event.data;
|
||||
if (!msg || msg.type !== "LOCAL_REQUEST") return;
|
||||
|
||||
const { id, request } = msg;
|
||||
console.log("[Worker] Received LOCAL_REQUEST:", id, request.method, request.url);
|
||||
|
||||
try {
|
||||
const response = await dispatch(request);
|
||||
console.log("[Worker] Dispatch completed, sending response:", id);
|
||||
|
||||
// Transfer body back (if any)
|
||||
self.postMessage({
|
||||
@ -74,6 +178,7 @@ self.onmessage = async (event) => {
|
||||
response
|
||||
}, response.body ? [response.body] : []);
|
||||
} catch (e) {
|
||||
console.error("[Worker] Dispatch error:", e);
|
||||
self.postMessage({
|
||||
type: "LOCAL_RESPONSE",
|
||||
id,
|
||||
|
||||
@ -8,12 +8,25 @@ import { viteStaticCopy } from 'vite-plugin-static-copy'
|
||||
const assets = [ "assets", "stylesheets", "fonts", "translations" ];
|
||||
|
||||
const isDev = process.env.NODE_ENV === "development";
|
||||
|
||||
// Always copy SQLite WASM files so they're available to the module
|
||||
const sqliteWasmPlugin = viteStaticCopy({
|
||||
targets: [
|
||||
{
|
||||
// Copy the entire jswasm directory to maintain the module's expected structure
|
||||
src: "../../node_modules/@sqlite.org/sqlite-wasm/sqlite-wasm/jswasm/*",
|
||||
dest: "node_modules/@sqlite.org/sqlite-wasm/sqlite-wasm/jswasm"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
let plugins: any = [
|
||||
preact({
|
||||
babel: {
|
||||
compact: !isDev
|
||||
}
|
||||
})
|
||||
}),
|
||||
sqliteWasmPlugin // Always include SQLite WASM files
|
||||
];
|
||||
|
||||
if (!isDev) {
|
||||
@ -43,6 +56,12 @@ export default defineConfig(() => ({
|
||||
cacheDir: '../../node_modules/.vite/apps/client',
|
||||
base: "",
|
||||
plugins,
|
||||
optimizeDeps: {
|
||||
exclude: ['@sqlite.org/sqlite-wasm']
|
||||
},
|
||||
worker: {
|
||||
format: 'es'
|
||||
},
|
||||
resolve: {
|
||||
alias: [
|
||||
{
|
||||
|
||||
13
pnpm-lock.yaml
generated
13
pnpm-lock.yaml
generated
@ -193,6 +193,9 @@ importers:
|
||||
'@preact/signals':
|
||||
specifier: 2.5.1
|
||||
version: 2.5.1(preact@10.28.1)
|
||||
'@sqlite.org/sqlite-wasm':
|
||||
specifier: 3.51.1-build2
|
||||
version: 3.51.1-build2
|
||||
'@triliumnext/ckeditor5':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/ckeditor5
|
||||
@ -5195,6 +5198,10 @@ packages:
|
||||
'@socket.io/component-emitter@3.1.2':
|
||||
resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==}
|
||||
|
||||
'@sqlite.org/sqlite-wasm@3.51.1-build2':
|
||||
resolution: {integrity: sha512-lVPTBlFsEijJ3wuoIbMfC9QMZKfL8huHN8D/lijNKoVxPqUDNvDtXse0wafe7USSmyfKAMb1JZ3ISSr/Vgbn5w==}
|
||||
hasBin: true
|
||||
|
||||
'@ssddanbrown/codemirror-lang-smarty@1.0.0':
|
||||
resolution: {integrity: sha512-F0ut1kmdbT3eORk3xVIKfQsGCZiQdh+6sLayBa0+FTex2gyIQlVQZRRA7bPSlchI3uZtWwNnqGNz5O/QLWRlFg==}
|
||||
|
||||
@ -15433,6 +15440,8 @@ snapshots:
|
||||
'@ckeditor/ckeditor5-utils': 47.3.0
|
||||
'@ckeditor/ckeditor5-watchdog': 47.3.0
|
||||
es-toolkit: 1.39.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ckeditor/ckeditor5-dev-build-tools@54.2.3(@swc/helpers@0.5.17)(tslib@2.8.1)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
@ -16096,8 +16105,6 @@ snapshots:
|
||||
'@ckeditor/ckeditor5-ui': 47.3.0
|
||||
'@ckeditor/ckeditor5-utils': 47.3.0
|
||||
ckeditor5: 47.3.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@ckeditor/ckeditor5-restricted-editing@47.3.0':
|
||||
dependencies:
|
||||
@ -19927,6 +19934,8 @@ snapshots:
|
||||
|
||||
'@socket.io/component-emitter@3.1.2': {}
|
||||
|
||||
'@sqlite.org/sqlite-wasm@3.51.1-build2': {}
|
||||
|
||||
'@ssddanbrown/codemirror-lang-smarty@1.0.0': {}
|
||||
|
||||
'@ssddanbrown/codemirror-lang-twig@1.0.0':
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user