mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 11:07:10 +00:00
feat(folio-webApp): OPFS-backed sqlite worker + webpack config
sqlite.worker.js implements the SQLDelight web-worker protocol
(exec/begin_transaction/end_transaction/rollback_transaction) on top
of @sqlite.org/sqlite-wasm. Prefers the OPFS SAH pool VFS for
persistent storage and falls back to in-memory when OPFS is
unavailable.
webpack.config.d/coopcoep.js sends COOP/COEP headers on the dev
server so cross-origin isolation is available, even though the SAH
pool itself does not require it. webpack.config.d/sqlite-wasm.js
enables asyncWebAssembly so webpack can bundle sqlite3.wasm via the
'new URL("sqlite3.wasm", import.meta.url)' reference inside the
sqlite-wasm package.
This commit is contained in:
1 parent
80b02fd19f
commit
db2801d16c
3 files changed
+89
No files matched your search
@@ -0,0 +1,71 @@
|
||||
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';
|
||||
|
||||
let db = null;
|
||||
let isPersistent = false;
|
||||
|
||||
async function init() {
|
||||
const sqlite3 = await sqlite3InitModule({
|
||||
print: (msg) => console.log('[sqlite]', msg),
|
||||
printErr: (msg) => console.error('[sqlite]', msg),
|
||||
});
|
||||
|
||||
try {
|
||||
const pool = await sqlite3.installOpfsSAHPoolVfs({
|
||||
directory: '/folio-sqlite-pool',
|
||||
clearOnInit: false,
|
||||
initialCapacity: 6,
|
||||
});
|
||||
db = new pool.OpfsSAHPoolDb('/folio.sqlite3');
|
||||
isPersistent = true;
|
||||
console.log('[sqlite] using OPFS SAH pool');
|
||||
} catch (sahErr) {
|
||||
console.warn('[sqlite] OPFS SAH pool unavailable, falling back to in-memory:', sahErr?.message ?? sahErr);
|
||||
db = new sqlite3.oo1.DB(':memory:', 'ct');
|
||||
isPersistent = false;
|
||||
}
|
||||
}
|
||||
|
||||
function execQuery(sql, params) {
|
||||
const rows = db.exec({
|
||||
sql,
|
||||
bind: params,
|
||||
returnValue: 'resultRows',
|
||||
});
|
||||
return { values: rows };
|
||||
}
|
||||
|
||||
function dispatch(data) {
|
||||
switch (data && data.action) {
|
||||
case 'exec':
|
||||
if (!data.sql) throw new Error('exec: missing sql');
|
||||
return execQuery(data.sql, data.params);
|
||||
case 'begin_transaction':
|
||||
db.exec('BEGIN TRANSACTION;');
|
||||
return { values: [] };
|
||||
case 'end_transaction':
|
||||
db.exec('COMMIT;');
|
||||
return { values: [] };
|
||||
case 'rollback_transaction':
|
||||
db.exec('ROLLBACK;');
|
||||
return { values: [] };
|
||||
default:
|
||||
throw new Error('Unsupported action: ' + (data && data.action));
|
||||
}
|
||||
}
|
||||
|
||||
const ready = init();
|
||||
|
||||
self.onmessage = (event) => {
|
||||
const data = event.data;
|
||||
ready
|
||||
.then(() => {
|
||||
const results = dispatch(data);
|
||||
self.postMessage({ id: data.id, results });
|
||||
})
|
||||
.catch((err) => {
|
||||
const message = err && err.message ? String(err.message) : String(err);
|
||||
self.postMessage({ id: data && data.id, error: { message, name: err && err.name } });
|
||||
});
|
||||
};
|
||||
|
||||
self.postMessage({ ready: true, persistent: isPersistent });
|
||||
@@ -0,0 +1,9 @@
|
||||
config.devServer = {
|
||||
...(config.devServer || {}),
|
||||
headers: {
|
||||
...((config.devServer && config.devServer.headers) || {}),
|
||||
'Cross-Origin-Opener-Policy': 'same-origin',
|
||||
'Cross-Origin-Embedder-Policy': 'require-corp',
|
||||
'Cross-Origin-Resource-Policy': 'cross-origin',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
// Webpack picks up `new Worker(new URL("./sqlite.worker.js", import.meta.url),
|
||||
// { type: "module" })` from the compiled Kotlin/wasm output and bundles the
|
||||
// worker. The bundled worker imports `@sqlite.org/sqlite-wasm`, which in turn
|
||||
// loads sqlite3.wasm via `new URL("sqlite3.wasm", import.meta.url)`. Enabling
|
||||
// asyncWebAssembly lets webpack process that .wasm reference correctly.
|
||||
config.experiments = {
|
||||
...(config.experiments || {}),
|
||||
asyncWebAssembly: true,
|
||||
};
|
||||
Reference in new issue
Block a user