Skip to content

Commit d713ca1

Browse files
authored
Merge pull request #15 from etiennenoel/added-comlink-and-better-main-thread-support
Added comlink and a sqlite client that encapsulates the communication…
2 parents fba7d4f + b0d6397 commit d713ca1

File tree

6 files changed

+150
-0
lines changed

6 files changed

+150
-0
lines changed

demo/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
<title>SQLite Wasm Demo</title>
66
<script type="module" src="script.js"></script>
77
<script type="module" src="main-thread.js"></script>
8+
<script type="module" src="sqlite-client.js"></script>
89
</head>
910
<body>
1011
<h1>SQLite Wasm Demo</h1>
1112
<h2>Main thread</h2>
1213
<div class="main-thread"></div>
1314
<h2>Worker</h2>
1415
<div class="worker"></div>
16+
<h2>Built-in SQLite Client</h2>
17+
<div id="sqlite-client"></div>
1518
</body>
1619
</html>

demo/sqlite-client.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import SqliteClient from '/src/sqlite.client.mjs';
2+
3+
const sqliteClient = new SqliteClient('/db.sqlite3', '/src/sqlite.worker.mjs');
4+
5+
await sqliteClient.init();
6+
7+
await sqliteClient.executeSql('CREATE TABLE IF NOT EXISTS t(a,b)');
8+
9+
for (let i = 20; i <= 25; ++i) {
10+
await sqliteClient.executeSql('INSERT INTO t(a,b) VALUES (?,?)', [i, i * 2]);
11+
}
12+
13+
const rows = await sqliteClient.executeSql(
14+
'SELECT a FROM t ORDER BY a LIMIT 3',
15+
);
16+
17+
console.log(rows);
18+
19+
document.getElementById('sqlite-client').innerHTML =
20+
'<table>' +
21+
'<thead>' +
22+
'<tr>' +
23+
'<th>a</th>' +
24+
'</tr>' +
25+
'</thead>' +
26+
'<tbody>' +
27+
rows.map((row) => '<tr><td> ' + row[0] + '</td></tr>').concat();
28+
'</tbody>' + '</table>';

package-lock.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,8 @@
5858
"prettier": "^2.8.8",
5959
"publint": "^0.1.12",
6060
"shx": "^0.3.4"
61+
},
62+
"dependencies": {
63+
"comlink": "^4.4.1"
6164
}
6265
}

src/sqlite-client.mjs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
const log = (...args) => console.log(...args);
2+
const error = (...args) => console.error(...args);
3+
4+
export default class SqliteClient {
5+
sqliteWorker;
6+
7+
dbFile = '';
8+
sqliteWorkerPath = '';
9+
10+
constructor(dbFile, sqliteWorkerPath) {
11+
if (typeof dbFile !== 'string') {
12+
return error(
13+
"The 'dbFile' parameter passed to the SqliteClient constructor must be of type 'string'. Instead, you passed: '" +
14+
typeof dbFile +
15+
"'",
16+
);
17+
}
18+
19+
if (typeof sqliteWorkerPath !== 'string') {
20+
return error(
21+
"The 'sqliteWorkerPath' parameter passed to the SqliteClient constructor must be of type 'string'. Instead, you passed: '" +
22+
typeof sqliteWorkerPath +
23+
"'",
24+
);
25+
}
26+
27+
this.dbFile = dbFile;
28+
this.sqliteWorkerPath = sqliteWorkerPath;
29+
}
30+
31+
async init() {
32+
const SqliteWorker = Comlink.wrap(
33+
new Worker(this.sqliteWorkerPath, {
34+
type: 'module',
35+
}),
36+
);
37+
38+
this.sqliteWorker = await new SqliteWorker();
39+
40+
await this.sqliteWorker.init(this.dbFile);
41+
}
42+
43+
async executeSql(sqlStatement, bindParameters = []) {
44+
if (typeof sqlStatement !== 'string') {
45+
return error(
46+
"The 'sqlStatement' parameter passed to the 'executeSql' method of the SqliteClient must be of type 'string'. Instead, you passed: '" +
47+
typeof sqlStatement +
48+
"'",
49+
);
50+
}
51+
52+
if (!Array.isArray(bindParameters)) {
53+
return error(
54+
"The 'bindParameters' parameter passed to the 'executeSql' method of the SqliteClient must be of type 'array'. Instead, you passed: '" +
55+
typeof bindParameters +
56+
"'",
57+
);
58+
}
59+
60+
return new Promise(async (resolve) => {
61+
await this.sqliteWorker.executeSql(
62+
sqlStatement,
63+
bindParameters,
64+
Comlink.proxy((rows) => {
65+
return resolve(rows);
66+
}),
67+
);
68+
});
69+
}
70+
}

src/sqlite-worker.mjs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import * as Comlink from 'https://unpkg.com/comlink/dist/esm/comlink.mjs';
2+
import { default as sqlite3InitModule } from '../index.mjs';
3+
4+
const log = (...args) => console.log(...args);
5+
const error = (...args) => console.error(...args);
6+
7+
class SqliteWorker {
8+
db;
9+
init(dbFile) {
10+
return new Promise((resolve) => {
11+
sqlite3InitModule({
12+
print: log,
13+
printErr: error,
14+
}).then((sqlite3) => {
15+
try {
16+
this.db = new sqlite3.oo1.OpfsDb(dbFile);
17+
} catch (err) {
18+
error(err.name, err.message);
19+
}
20+
21+
return resolve();
22+
});
23+
});
24+
}
25+
26+
executeSql(sqlStatement, bindParameters, callback) {
27+
return callback(
28+
this.db.exec({
29+
sql: sqlStatement,
30+
bind: bindParameters,
31+
returnValue: 'resultRows',
32+
rowMode: 'array',
33+
}),
34+
);
35+
}
36+
}
37+
38+
Comlink.expose(SqliteWorker);

0 commit comments

Comments
 (0)