Skip to content

Commit c165098

Browse files
committed
Add wrapped worker
1 parent 23808d1 commit c165098

13 files changed

+286
-148
lines changed

README.md

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,70 @@ npm install @sqlite.org/sqlite-wasm
2020

2121
## Usage
2222

23-
There are two ways to use SQLite Wasm:
24-
[in the main thread](#in-the-main-thread-without-opfs) and
25-
[in a worker](#in-a-worker-with-opfs-if-available). Only the worker version
26-
allows you to use the origin private file system (OPFS) storage back-end.
23+
There are three ways to use SQLite Wasm:
2724

28-
### In the main thread (without OPFS):
25+
- [in the main thread with a wrapped worker](#in-a-wrapped-worker-with-opfs)
26+
(preferred option 💡) and
27+
- [in a worker](#in-a-worker-with-opfs-if-available)
28+
- [in the main thread](#in-the-main-thread-without-opfs)
29+
30+
Only the worker versions allow you to use the origin private file system (OPFS)
31+
storage back-end.
32+
33+
### In a wrapped worker (with OPFS if available):
34+
35+
> **Warning**
36+
>
37+
> For this to work, you need to set the following headers on your server:
38+
>
39+
> `Cross-Origin-Opener-Policy: same-origin`
40+
>
41+
> `Cross-Origin-Embedder-Policy: require-corp`
2942
3043
```js
31-
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';
44+
import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm';
3245

3346
const log = (...args) => console.log(...args);
3447
const error = (...args) => console.error(...args);
3548

36-
const start = function (sqlite3) {
37-
log('Running SQLite3 version', sqlite3.version.libVersion);
38-
const db = new sqlite3.oo1.DB('/mydb.sqlite3', 'ct');
39-
// Your SQLite code here.
40-
};
41-
42-
log('Loading and initializing SQLite3 module...');
43-
sqlite3InitModule({
44-
print: log,
45-
printErr: error,
46-
}).then((sqlite3) => {
49+
(async () => {
4750
try {
51+
log('Loading and initializing SQLite3 module...');
52+
53+
const promiser = await new Promise((resolve) => {
54+
const _promiser = sqlite3Worker1Promiser({
55+
onready: () => {
56+
resolve(_promiser);
57+
},
58+
});
59+
});
60+
4861
log('Done initializing. Running demo...');
49-
start(sqlite3);
62+
63+
let response;
64+
65+
response = await promiser('config-get', {});
66+
log('Running SQLite3 version', response.result.version.libVersion);
67+
68+
response = await promiser('open', {
69+
filename: 'file:mydb.sqlite3?vfs=opfs',
70+
});
71+
const { dbId } = response;
72+
logHtml(
73+
'',
74+
'OPFS is available, created persisted database at',
75+
response.result.filename.replace(/^file:(.*?)\?vfs=opfs/, '$1'),
76+
);
77+
// Your SQLite code here.
5078
} catch (err) {
79+
if (!(err instanceof Error)) {
80+
err = new Error(err.result.message);
81+
}
5182
error(err.name, err.message);
5283
}
53-
});
84+
})();
5485
```
5586

56-
The `db` object above implements the
57-
[Object Oriented API #1](https://sqlite.org/wasm/doc/trunk/api-oo1.md).
58-
5987
### In a worker (with OPFS if available):
6088

6189
> **Warning**
@@ -105,6 +133,37 @@ sqlite3InitModule({
105133
});
106134
```
107135

136+
### In the main thread (without OPFS):
137+
138+
```js
139+
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';
140+
141+
const log = (...args) => console.log(...args);
142+
const error = (...args) => console.error(...args);
143+
144+
const start = function (sqlite3) {
145+
log('Running SQLite3 version', sqlite3.version.libVersion);
146+
const db = new sqlite3.oo1.DB('/mydb.sqlite3', 'ct');
147+
// Your SQLite code here.
148+
};
149+
150+
log('Loading and initializing SQLite3 module...');
151+
sqlite3InitModule({
152+
print: log,
153+
printErr: error,
154+
}).then((sqlite3) => {
155+
try {
156+
log('Done initializing. Running demo...');
157+
start(sqlite3);
158+
} catch (err) {
159+
error(err.name, err.message);
160+
}
161+
});
162+
```
163+
164+
The `db` object above implements the
165+
[Object Oriented API #1](https://sqlite.org/wasm/doc/trunk/api-oo1.md).
166+
108167
## Usage with vite
109168

110169
If you are using [vite](https://vitejs.dev/), you need to add the following

demo/index.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
<meta charset="utf-8" />
55
<title>SQLite Wasm Demo</title>
66
<script type="module" src="script.js"></script>
7+
<script type="module" src="wrapped-worker.js"></script>
78
<script type="module" src="main-thread.js"></script>
89
</head>
910
<body>
1011
<h1>SQLite Wasm Demo</h1>
11-
<h2>Main thread</h2>
12-
<div class="main-thread"></div>
12+
<h2>Wrapped Worker</h2>
13+
<div class="worker-promiser"></div>
1314
<h2>Worker</h2>
1415
<div class="worker"></div>
16+
<h2>Main thread</h2>
17+
<div class="main-thread"></div>
1518
</body>
1619
</html>

demo/wrapped-worker.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { sqlite3Worker1Promiser } from '../index.mjs';
2+
3+
(async () => {
4+
const container = document.querySelector('.worker-promiser');
5+
6+
const logHtml = function (cssClass, ...args) {
7+
const div = document.createElement('div');
8+
if (cssClass) div.classList.add(cssClass);
9+
div.append(document.createTextNode(args.join(' ')));
10+
container.append(div);
11+
};
12+
13+
try {
14+
logHtml('', 'Loading and initializing SQLite3 module...');
15+
16+
const promiser = await new Promise((resolve) => {
17+
const _promiser = sqlite3Worker1Promiser({
18+
onready: () => {
19+
resolve(_promiser);
20+
},
21+
});
22+
});
23+
24+
logHtml('', 'Done initializing. Running demo...');
25+
26+
let response;
27+
28+
response = await promiser('config-get', {});
29+
logHtml('', 'Running SQLite3 version', response.result.version.libVersion);
30+
31+
response = await promiser('open', {
32+
filename: 'file:worker-promiser.sqlite3?vfs=opfs',
33+
});
34+
const { dbId } = response;
35+
logHtml(
36+
'',
37+
'OPFS is available, created persisted database at',
38+
response.result.filename.replace(/^file:(.*?)\?vfs=opfs/, '$1'),
39+
);
40+
41+
await promiser('exec', { dbId, sql: 'CREATE TABLE IF NOT EXISTS t(a,b)' });
42+
logHtml('', 'Creating a table...');
43+
44+
logHtml('', 'Insert some data using exec()...');
45+
for (let i = 20; i <= 25; ++i) {
46+
await promiser('exec', {
47+
dbId,
48+
sql: 'INSERT INTO t(a,b) VALUES (?,?)',
49+
bind: [i, i * 2],
50+
});
51+
}
52+
53+
logHtml('', 'Query data with exec()');
54+
await promiser('exec', {
55+
dbId,
56+
sql: 'SELECT a FROM t ORDER BY a LIMIT 3',
57+
callback: (result) => {
58+
if (!result.row) {
59+
return;
60+
}
61+
logHtml('', result.row);
62+
},
63+
});
64+
65+
await promiser('close', { dbId });
66+
} catch (err) {
67+
if (!(err instanceof Error)) {
68+
err = new Error(err.result.message);
69+
}
70+
console.error(err.name, err.message);
71+
}
72+
})();

index.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
import { default as sqlite3InitModule } from './sqlite-wasm/jswasm/sqlite3-bundler-friendly.mjs';
2+
import './sqlite-wasm/jswasm/sqlite3-worker1-promiser-bundler-friendly.js';
3+
4+
const sqlite3Worker1Promiser = self.sqlite3Worker1Promiser;
25

36
export default sqlite3InitModule;
7+
export { sqlite3Worker1Promiser };

package-lock.json

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

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sqlite.org/sqlite-wasm",
3-
"version": "3.44.0-build2",
3+
"version": "3.44.0-build3",
44
"description": "SQLite Wasm conveniently wrapped as an ES Module.",
55
"keywords": [
66
"sqlite",
@@ -58,7 +58,7 @@
5858
"http-server": "github:vapier/http-server",
5959
"module-workers-polyfill": "^0.3.2",
6060
"node-fetch": "^3.3.2",
61-
"prettier": "^3.0.3",
61+
"prettier": "^3.1.0",
6262
"publint": "^0.2.5",
6363
"prettier-plugin-jsdoc": "^1.1.1",
6464
"shx": "^0.3.4"

sqlite-wasm/jswasm/sqlite3-bundler-friendly.mjs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3871,10 +3871,10 @@ var sqlite3InitModule = (() => {
38713871
var type = stream.tty
38723872
? 2
38733873
: FS.isDir(stream.mode)
3874-
? 3
3875-
: FS.isLink(stream.mode)
3876-
? 7
3877-
: 4;
3874+
? 3
3875+
: FS.isLink(stream.mode)
3876+
? 7
3877+
: 4;
38783878
HEAP8[pbuf >> 0] = type;
38793879

38803880
return 0;
@@ -6812,8 +6812,8 @@ var sqlite3InitModule = (() => {
68126812
'i32' === ptrIR
68136813
? 4
68146814
: 'i64' === ptrIR
6815-
? 8
6816-
: toss('Unhandled ptrSizeof:', ptrIR));
6815+
? 8
6816+
: toss('Unhandled ptrSizeof:', ptrIR));
68176817

68186818
const cache = Object.create(null);
68196819

@@ -7259,8 +7259,8 @@ var sqlite3InitModule = (() => {
72597259
return n
72607260
? __utf8Decode(heapWrappers().HEAP8U, ptr, ptr + n)
72617261
: null === n
7262-
? n
7263-
: '';
7262+
? n
7263+
: '';
72647264
};
72657265

72667266
target.jstrlen = function (str) {
@@ -10524,11 +10524,11 @@ var sqlite3InitModule = (() => {
1052410524

1052510525
globalThis.sqlite3ApiBootstrap.initializers.push(function (sqlite3) {
1052610526
sqlite3.version = {
10527-
libVersion: '3.44.0',
10528-
libVersionNumber: 3044000,
10527+
libVersion: '3.44.1',
10528+
libVersionNumber: 3044001,
1052910529
sourceId:
10530-
'2023-11-01 11:23:50 17129ba1ff7f0daf37100ee82d507aef7827cf38de1866e2633096ae6ad81301',
10531-
downloadVersion: 3440000,
10530+
'2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4',
10531+
downloadVersion: 3440100,
1053210532
};
1053310533
});
1053410534

@@ -11130,8 +11130,8 @@ var sqlite3InitModule = (() => {
1113011130
'number' === typeof arity
1113111131
? arity
1113211132
: xArity.length
11133-
? xArity.length - 1
11134-
: 0;
11133+
? xArity.length - 1
11134+
: 0;
1113511135
let rc;
1113611136
if (isWindow) {
1113711137
rc = capi.sqlite3_create_window_function(

0 commit comments

Comments
 (0)