refactor(build, dependencies): introduce SQLDelight WebWorker setup, update Spring Boot dependencies, and align versions

Configured `sqlite.worker.js` for OPFS-backed SQLite WASM operations in the frontend build pipeline. Added new Spring Boot dependency bundles including secure service configurations. Integrated updated database utilities with enhanced error handling. Removed outdated circuit breaker tests and replaced them with modern unit and integration test setups.
This commit is contained in:
2026-01-12 17:05:44 +01:00
parent 2f8529156a
commit 32e43b8fb0
23 changed files with 402 additions and 526 deletions
+5
View File
@@ -41,6 +41,11 @@ kotlin {
jsMain.dependencies {
implementation(libs.sqldelight.driver.web)
// NPM deps used by `sqlite.worker.js` (OPFS-backed SQLite WASM worker)
implementation(npm("@cashapp/sqldelight-sqljs-worker", "2.2.1"))
// Use a published build tag from the official package.
implementation(npm("@sqlite.org/sqlite-wasm", "3.51.1-build2"))
}
/*
@@ -3,6 +3,6 @@ package at.mocode.frontend.core.localdb
import app.cash.sqldelight.db.SqlDriver
@Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
expect class DatabaseDriverFactory {
expect class DatabaseDriverFactory() {
suspend fun createDriver(): SqlDriver
}
@@ -0,0 +1,26 @@
package at.mocode.frontend.core.localdb
import org.koin.dsl.module
/**
* Thin wrapper around SQLDelight `AppDatabase` creation.
*
* The platform-specific part is the `DatabaseDriverFactory` (expect/actual),
* which provides the appropriate SQLDelight driver (JVM sqlite driver, JS WebWorkerDriver, ...).
*/
class DatabaseProvider(
private val driverFactory: DatabaseDriverFactory
) {
suspend fun createDatabase(): AppDatabase {
val driver = driverFactory.createDriver()
return AppDatabase(driver)
}
}
/**
* Koin module to provide the SQLDelight database for all frontend targets.
*/
val localDbModule = module {
single<DatabaseDriverFactory> { DatabaseDriverFactory() }
single<DatabaseProvider> { DatabaseProvider(get()) }
}
@@ -1,6 +1,51 @@
import { runWorker } from '@cashapp/sqldelight-sqljs-worker';
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';
// Minimal worker protocol compatible with SQLDelight's `web-worker-driver`.
// Mirrors the message format used by SQLDelight's `sqljs.worker.js` implementation.
function runWorker({ driver }) {
let db = null;
const open = (name) => {
db = driver.open(name);
};
// Open once with the default database name expected by SQLDelight.
open('app.db');
self.onmessage = (event) => {
const data = event.data;
try {
switch (data && data.action) {
case 'exec': {
if (!data.sql) throw new Error('exec: Missing query string');
// sqlite-wasm oo1 DB supports `.exec(...)`.
// We intentionally return only `values` which is sufficient for SQLDelight.
const rows = [];
db.exec({
sql: data.sql,
bind: data.params ?? [],
rowMode: 'array',
callback: (row) => rows.push(row)
});
return postMessage({ id: data.id, results: { values: rows } });
}
case 'begin_transaction':
db.exec('BEGIN TRANSACTION;');
return postMessage({ id: data.id, results: [] });
case 'end_transaction':
db.exec('END TRANSACTION;');
return postMessage({ id: data.id, results: [] });
case 'rollback_transaction':
db.exec('ROLLBACK TRANSACTION;');
return postMessage({ id: data.id, results: [] });
default:
throw new Error(`Unsupported action: ${data && data.action}`);
}
} catch (err) {
return postMessage({ id: data && data.id, error: err?.message ?? String(err) });
}
};
}
sqlite3InitModule({
print: console.log,
printErr: console.error,
@@ -1,6 +1,49 @@
import { runWorker } from '@cashapp/sqldelight-sqljs-worker';
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';
// Minimal worker protocol compatible with SQLDelight's `web-worker-driver`.
// Mirrors the message format used by SQLDelight's `sqljs.worker.js` implementation.
function runWorker({ driver }) {
let db = null;
const open = (name) => {
db = driver.open(name);
};
// Open once with the default database name expected by SQLDelight.
open('app.db');
self.onmessage = (event) => {
const data = event.data;
try {
switch (data && data.action) {
case 'exec': {
if (!data.sql) throw new Error('exec: Missing query string');
const rows = [];
db.exec({
sql: data.sql,
bind: data.params ?? [],
rowMode: 'array',
callback: (row) => rows.push(row)
});
return postMessage({ id: data.id, results: { values: rows } });
}
case 'begin_transaction':
db.exec('BEGIN TRANSACTION;');
return postMessage({ id: data.id, results: [] });
case 'end_transaction':
db.exec('END TRANSACTION;');
return postMessage({ id: data.id, results: [] });
case 'rollback_transaction':
db.exec('ROLLBACK TRANSACTION;');
return postMessage({ id: data.id, results: [] });
default:
throw new Error(`Unsupported action: ${data && data.action}`);
}
} catch (err) {
return postMessage({ id: data && data.id, error: err?.message ?? String(err) });
}
};
}
sqlite3InitModule({
print: console.log,
printErr: console.error,