@livestore/sqlite-wasm
Version:
SQLite Wasm conveniently wrapped as an ES Module.
236 lines (185 loc) • 6.5 kB
Markdown
> NOTE This fork enables the SQLite [bytecode](byte) and
> [session](https://www.sqlite.org/sessionintro.html) extension.
# SQLite Wasm
SQLite Wasm conveniently wrapped as an ES Module.
> **Warning**
>
> This project wraps the code of
> [SQLite Wasm](https://sqlite.org/wasm/doc/trunk/index.md) with _no_ changes,
> apart from added TypeScript types. Please do _not_ file issues or feature
> requests regarding the underlying SQLite Wasm code here. Instead, please
> follow the
> [SQLite bug filing instructions](https://www.sqlite.org/src/wiki?name=Bug+Reports).
> Filing TypeScript type related issues and feature requests is fine.
## Installation
```bash
npm install @sqlite.org/sqlite-wasm
```
## Usage
There are three ways to use SQLite Wasm:
- [in the main thread with a wrapped worker](#in-a-wrapped-worker-with-opfs-if-available)
(🏆 preferred option)
- [in a worker](#in-a-worker-with-opfs-if-available)
- [in the main thread](#in-the-main-thread-without-opfs)
Only the worker versions allow you to use the origin private file system (OPFS)
storage back-end.
### In a wrapped worker (with OPFS if available):
> **Warning**
>
> For this to work, you need to set the following headers on your server:
>
> `Cross-Origin-Opener-Policy: same-origin`
>
> `Cross-Origin-Embedder-Policy: require-corp`
```js
import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm';
const log = (...args) => console.log(...args);
const error = (...args) => console.error(...args);
(async () => {
try {
log('Loading and initializing SQLite3 module...');
const promiser = await new Promise((resolve) => {
const _promiser = sqlite3Worker1Promiser({
onready: () => {
resolve(_promiser);
},
});
});
log('Done initializing. Running demo...');
let response;
response = await promiser('config-get', {});
log('Running SQLite3 version', response.result.version.libVersion);
response = await promiser('open', {
filename: 'file:mydb.sqlite3?vfs=opfs',
});
const { dbId } = response;
log(
'OPFS is available, created persisted database at',
response.result.filename.replace(/^file:(.*?)\?vfs=opfs$/, '$1'),
);
// Your SQLite code here.
} catch (err) {
if (!(err instanceof Error)) {
err = new Error(err.result.message);
}
error(err.name, err.message);
}
})();
```
The `promiser` object above implements the
[Worker1 API](https://sqlite.org/wasm/doc/trunk/api-worker1.md#worker1-methods).
### In a worker (with OPFS if available):
> **Warning**
>
> For this to work, you need to set the following headers on your server:
>
> `Cross-Origin-Opener-Policy: same-origin`
>
> `Cross-Origin-Embedder-Policy: require-corp`
```js
// In `main.js`.
const worker = new Worker('worker.js', { type: 'module' });
```
```js
// In `worker.js`.
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';
const log = (...args) => console.log(...args);
const error = (...args) => console.error(...args);
const start = function (sqlite3) {
log('Running SQLite3 version', sqlite3.version.libVersion);
let db;
if ('opfs' in sqlite3) {
db = new sqlite3.oo1.OpfsDb('/mydb.sqlite3');
log('OPFS is available, created persisted database at', db.filename);
} else {
db = new sqlite3.oo1.DB('/mydb.sqlite3', 'ct');
log('OPFS is not available, created transient database', db.filename);
}
// Your SQLite code here.
};
log('Loading and initializing SQLite3 module...');
sqlite3InitModule({
print: log,
printErr: error,
}).then((sqlite3) => {
log('Done initializing. Running demo...');
try {
start(sqlite3);
} catch (err) {
error(err.name, err.message);
}
});
```
The `db` object above implements the
[Object Oriented API #1](https://sqlite.org/wasm/doc/trunk/api-oo1.md).
### In the main thread (without OPFS):
```js
import sqlite3InitModule from '@sqlite.org/sqlite-wasm';
const log = (...args) => console.log(...args);
const error = (...args) => console.error(...args);
const start = function (sqlite3) {
log('Running SQLite3 version', sqlite3.version.libVersion);
const db = new sqlite3.oo1.DB('/mydb.sqlite3', 'ct');
// Your SQLite code here.
};
log('Loading and initializing SQLite3 module...');
sqlite3InitModule({
print: log,
printErr: error,
}).then((sqlite3) => {
try {
log('Done initializing. Running demo...');
start(sqlite3);
} catch (err) {
error(err.name, err.message);
}
});
```
The `db` object above implements the
[Object Oriented API #1](https://sqlite.org/wasm/doc/trunk/api-oo1.md).
## Usage with vite
If you are using [vite](https://vitejs.dev/), you need to add the following
config option in `vite.config.js`:
```js
import { defineConfig } from 'vite';
export default defineConfig({
server: {
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
},
optimizeDeps: {
exclude: ['@sqlite.org/sqlite-wasm'],
},
});
```
Check out a
[sample project](https://stackblitz.com/edit/vitejs-vite-ttrbwh?file=main.js)
that shows this in action.
## Demo
See the [demo](https://github.com/sqlite/sqlite-wasm/tree/main/demo) folder for
examples of how to use this in the main thread and in a worker. (Note that the
worker variant requires special HTTP headers, so it can't be hosted on GitHub
Pages.) An example that shows how to use this with vite is available on
[StackBlitz](https://stackblitz.com/edit/vitejs-vite-ttrbwh?file=main.js).
## Projects using this package
See the list of
[npm dependents](https://www.npmjs.com/browse/depended/@sqlite.org/sqlite-wasm)
for this package.
## Deploying a new version
(These steps can only be executed by maintainers.)
1. Update the version number in `package.json` reflecting the current
[SQLite version number](https://sqlite.org/download.html) and add a build
identifier suffix like `-build1`. The complete version number should read
something like `3.41.2-build1`.
1. Run `npm run build` to build the ES Module. This downloads the latest SQLite
Wasm binary and builds the ES Module.
1. Run `npm run deploy` to commit the changes, push to GitHub, and publish the
new version to npm.
## License
Apache 2.0.
## Acknowledgements
This project is based on [SQLite Wasm](https://sqlite.org/wasm), which it
conveniently wraps as an ES Module and publishes to npm as
[`@sqlite.org/sqlite-wasm`](https://www.npmjs.com/package/@sqlite.org/sqlite-wasm).