diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9321921 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,101 @@ +# Contributing + +## Local development + +Use Node.js 22 or later. From the repository root, install dependencies and build the package: + +```bash +npm install +npm run build +``` + +The package build uses the SQLite Wasm binaries already included in `src/bin` and writes the package +files to `dist`. + +Start an example with its `dev:*` script, for example: + +```bash +npm run dev:main-thread +``` + +For the OPFS example, use `npm run dev:opfs`. Other examples have corresponding `dev:*` scripts in +`package.json`. Rebuild the package after changing its source files. + +## Building the SQLite Wasm locally + +To rebuild the underlying SQLite Wasm binaries, use Docker: + +1. Build the Docker image: + + ```bash + docker build -t sqlite-wasm-builder:env . + ``` + +2. Run the build: + + **Unix (Linux/macOS):** + + ```bash + docker run --rm \ + -e SQLITE_REF="master" \ + -v "$(pwd)/out":/out \ + -v "$(pwd)/src/bin":/src/bin \ + sqlite-wasm-builder:env build + ``` + + **Windows (PowerShell):** + + ```powershell + docker run --rm ` + -e SQLITE_REF="master" ` + -v "${PWD}/out:/out" ` + -v "${PWD}/src/bin:/src/bin" ` + sqlite-wasm-builder:env build + ``` + + **Windows (Command Prompt):** + + ```cmd + docker run --rm ^ + -e SQLITE_REF="master" ^ + -v "%cd%/out:/out" ^ + -v "%cd%/src/bin:/src/bin" ^ + sqlite-wasm-builder:env build + ``` + +## Running tests + +The test suite consists of Node.js tests and browser-based tests (using Vitest Browser Mode). Tests +aim to sanity-check the exported scripts. We test for correct exports and **very** basic +functionality. + +1. Install dependencies: + + ```bash + npm install + ``` + +2. Install Playwright browsers (required for browser tests): + + ```bash + npx playwright install chromium --with-deps --no-shell + ``` + +3. Run all tests: + + ```bash + npm test + ``` + +## Deploying a new version + +(These steps can only be executed by maintainers.) + +1. Manually trigger the [GitHub Actions workflow](../../actions/workflows/build-wasm.yml). By + default, it uses the latest SQLite tag. This pull request will contain the latest `sqlite3.wasm` + and related bindings. + +2. Once the above pull request is validated and merged, 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`. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..58e8520 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,167 @@ +This package's wrapper code and TypeScript definitions are licensed under Apache 2.0. + +The bundled SQLite code is dedicated to the public domain. See +[SQLite's copyright statement](https://www.sqlite.org/copyright.html). Third-party notices included +in the generated WebAssembly bindings also apply. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and distribution as defined + by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is + granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other entities that control, + are controlled by, or are under common control with that entity. For the purposes of this + definition, "control" means (i) the power, direct or indirect, to cause the direction or + management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent + (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by + this License. + + "Source" form shall mean the preferred form for making modifications, including but not limited + to software source code, documentation source, and configuration files. + + "Object" form shall mean any form resulting from mechanical transformation or translation of a + Source form, including but not limited to compiled object code, generated documentation, and + conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, made available under + the License, as indicated by a copyright notice that is included in or attached to the work (an + example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or + derived from) the Work and for which the editorial revisions, annotations, elaborations, or + other modifications represent, as a whole, an original work of authorship. For the purposes of + this License, Derivative Works shall not include works that remain separable from, or merely + link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including the original version of the Work and + any modifications or additions to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or + Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this + definition, "submitted" means any form of electronic, verbal, or written communication sent to + the Licensor or its representatives, including but not limited to communication on electronic + mailing lists, source code control systems, and issue tracking systems that are managed by, or + on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding + communication that is conspicuously marked or otherwise designated in writing by the copyright + owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a + Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each + Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, + irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or + Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor + hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, use, offer to sell, sell, + import, and otherwise transfer the Work, where such license applies only to those patent claims + licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or + by combination of their Contribution(s) with the Work to which such Contribution(s) was + submitted. If You institute patent litigation against any entity (including a cross-claim or + counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work + constitutes direct or contributory patent infringement, then any patent licenses granted to You + under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof + in any medium, with or without modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a copy of this License; + and + + (b) You must cause any modified files to carry prominent notices stating that You changed the + files; and + + (c) You must retain, in the Source form of any Derivative Works that You distribute, all + copyright, patent, trademark, and attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative + Works that You distribute must include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not pertain to any part of the + Derivative Works, in at least one of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or documentation, if provided along with + the Derivative Works; or, within a display generated by the Derivative Works, if and wherever + such third-party notices normally appear. The contents of the NOTICE file are for informational + purposes only and do not modify the License. You may add Your own attribution notices within + Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the + Work, provided that such additional attribution notices cannot be construed as modifying the + License. + + You may add Your own copyright statement to Your modifications and may provide additional or + different license terms and conditions for use, reproduction, or distribution of Your + modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and + distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution + intentionally submitted for inclusion in the Work by You to the Licensor shall be under the + terms and conditions of this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate + license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service + marks, or product names of the Licensor, except as required for reasonable and customary use in + describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor + provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, + any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or + redistributing the Work and assume any risks associated with Your exercise of permissions under + this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including + negligence), contract, or otherwise, unless required by applicable law (such as deliberate and + grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for + damages, including any direct, indirect, special, incidental, or consequential damages of any + character arising as a result of this License or out of the use or inability to use the Work + (including but not limited to damages for loss of goodwill, work stoppage, computer failure or + malfunction, or any and all other commercial damages or losses), even if such Contributor has + been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works + thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, + indemnity, or other liability obligations and/or rights consistent with this License. However, + in accepting such obligations, You may act only on Your own behalf and on Your sole + responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability incurred by, or claims asserted + against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is +distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing permissions and limitations under the +License. diff --git a/README.md b/README.md index 74e703e..a5ac9af 100644 --- a/README.md +++ b/README.md @@ -28,12 +28,12 @@ npm install @sqlite.org/sqlite-wasm There are two ways to use SQLite Wasm: -- [in a worker](#in-a-worker-with-opfs-if-available) +- [in a worker](#in-a-worker-with-opfs) - [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 worker (with OPFS if available): +### In a worker (with OPFS): > [!Warning] > @@ -43,41 +43,26 @@ Only the worker versions allow you to use the origin private file system (OPFS) > > `Cross-Origin-Embedder-Policy: require-corp` -```js -// In `main.js`. -const worker = new Worker('worker.js', { type: 'module' }); +```ts +// In `main.ts`. +const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' }); ``` -```js -// In `worker.js`. +```ts +// In `worker.ts`. import sqlite3InitModule from '@sqlite.org/sqlite-wasm'; -const start = (sqlite3) => { - console.log('Running SQLite3 version', sqlite3.version.libVersion); - const db = - 'opfs' in sqlite3 - ? new sqlite3.oo1.OpfsDb('/mydb.sqlite3') - : new sqlite3.oo1.DB('/mydb.sqlite3', 'ct'); - console.log( - 'opfs' in sqlite3 - ? `OPFS is available, created persisted database at ${db.filename}` - : `OPFS is not available, created transient database ${db.filename}`, - ); +const sqlite3 = await sqlite3InitModule(); + +console.log('Running SQLite3 version', sqlite3.version.libVersion); + +const db = new sqlite3.oo1.OpfsDb('/mydb.sqlite3'); + +try { // Your SQLite code here. -}; - -const initializeSQLite = async () => { - try { - console.log('Loading and initializing SQLite3 module...'); - const sqlite3 = await sqlite3InitModule(); - console.log('Done initializing. Running demo...'); - start(sqlite3); - } catch (err) { - console.error('Initialization error:', err.name, err.message); - } -}; - -initializeSQLite(); +} finally { + db.close(); +} ``` The `db` object above implements the @@ -85,35 +70,29 @@ The `db` object above implements the ### In the main thread (without OPFS): -```js +```ts import sqlite3InitModule from '@sqlite.org/sqlite-wasm'; -const start = (sqlite3) => { - log('Running SQLite3 version', sqlite3.version.libVersion); - const db = new sqlite3.oo1.DB('/mydb.sqlite3', 'ct'); +const sqlite3 = await sqlite3InitModule(); + +console.log('Running SQLite3 version', sqlite3.version.libVersion); + +const db = new sqlite3.oo1.DB('/mydb.sqlite3', 'ct'); + +try { // Your SQLite code here. -}; -const initializeSQLite = async () => { - try { - console.log('Loading and initializing SQLite3 module...'); - const sqlite3 = await sqlite3InitModule(); - console.log('Done initializing. Running demo...'); - start(sqlite3); - } catch (err) { - console.error('Initialization error:', err.name, err.message); - } -}; - -initializeSQLite(); +} finally { + db.close(); +} ``` The `db` object above implements the [Object-Oriented API #1](https://sqlite.org/wasm/doc/trunk/api-oo1.md). -## Usage with vite +## Usage with Vite -If you are using [vite](https://vitejs.dev/), you need to add the following config option in -`vite.config.js`: +If you are using [Vite](https://vitejs.dev/), you need to add the following config option in +`vite.config.ts`: ```js import { defineConfig } from 'vite'; @@ -131,97 +110,29 @@ export default defineConfig({ }); ``` -Check out a [sample project](https://stackblitz.com/edit/vitejs-vite-ttrbwh?file=main.js) that shows -this in action. +See our [OPFS](./demos/opfs-demo) and [SAH pool](./demos/sahpool-demo) examples for working Vite +projects. -## Demo +## Examples -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). +- [Main thread](./demos/main-thread-demo) +- [Worker](./demos/in-worker-demo) +- [OPFS](./demos/opfs-demo) +- [OPFS with Web Locks](./demos/opfs-wl-demo) +- [Key-value storage (kvvfs)](./demos/kvvfs-demo) +- [SAH pool with Vite](./demos/sahpool-demo) +- [SAH pool with webpack](./demos/sahpool-webpack-demo) +- [SAH pool with Parcel](./demos/sahpool-parcel-demo) +- [SAH pool with Rsbuild](./demos/sahpool-rsbuild-demo) ## 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. Manually trigger the [GitHub Actions workflow](../../actions/workflows/build-wasm.yml). By - default, it uses the latest SQLite tag. This pull request will contain the latest `sqlite3.wasm` - and related bindings. - -2. Once the above pull request is validated and merged, 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`. - -## Building the SQLite Wasm locally - -1. Build the Docker image: - - ```bash - docker build -t sqlite-wasm-builder:env . - ``` - -2. Run the build: +## Contributing - **Unix (Linux/macOS):** - - ```bash - docker run --rm \ - -e SQLITE_REF="master" \ - -v "$(pwd)/out":/out \ - -v "$(pwd)/src/bin":/src/bin \ - sqlite-wasm-builder:env build - ``` - - **Windows (PowerShell):** - - ```powershell - docker run --rm ` - -e SQLITE_REF="master" ` - -v "${PWD}/out:/out" ` - -v "${PWD}/src/bin:/src/bin" ` - sqlite-wasm-builder:env build - ``` - - **Windows (Command Prompt):** - - ```cmd - docker run --rm ^ - -e SQLITE_REF="master" ^ - -v "%cd%/out:/out" ^ - -v "%cd%/src/bin:/src/bin" ^ - sqlite-wasm-builder:env build - ``` - -## Running tests - -The test suite consists of Node.js tests and browser-based tests (using Vitest Browser Mode). Tests -aim to sanity-check the exported scripts. We test for correct exports and **very** basic -functionality. - -1. Install dependencies: - - ```bash - npm install - ``` - -2. Install Playwright browsers (required for browser tests): - - ```bash - npx playwright install chromium --with-deps --no-shell - ``` - -3. Run all tests: - - ```bash - npm test - ``` +See [CONTRIBUTING.md](./CONTRIBUTING.md) for deployment, local build, and testing instructions. ## Deprecations @@ -230,10 +141,6 @@ they also will not be extended further. It is their author's considered opinion fragile, too imperformant, and too limited for any non-toy software, and their use is _actively discouraged_. The "correct" way to use this library is documented in [Usage](#usage) section above. -## License - -Apache 2.0. - ## Acknowledgements This project is based on [SQLite Wasm](https://sqlite.org/wasm), which it conveniently wraps as an diff --git a/package.json b/package.json index cc2345b..5d68d9d 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "test:node": "vitest --project node", "test:browser": "vitest --project browser", "publint": "npx publint", - "check-types": "tsc --noEmit", + "check-types": "tsc", "build": "tsdown", "dev:kvvfs": "npm run dev -w demos/kvvfs-demo", "dev:opfs": "npm run dev -w demos/opfs-demo", @@ -64,8 +64,6 @@ "dev:sahpool-rsbuild": "npm run dev -w demos/sahpool-rsbuild-demo", "dev:main-thread": "npm run dev -w demos/main-thread-demo", "dev:in-worker": "npm run dev -w demos/in-worker-demo", - "start": "npx http-server --coop", - "start:node": "cd demo && node node.mjs", "format": "oxfmt", "format:check": "oxfmt --check", "prepublishOnly": "npm run build && npm run format && npm run publint && npm run check-types", diff --git a/tsdown.config.ts b/tsdown.config.ts index fc8596a..8c3e8b9 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -7,7 +7,7 @@ const tsdownConfig: UserConfig[] = [ entry: { index: 'src/browser.ts', node: 'src/node.ts', - 'bin/sqlite3-worker1': 'src/bin/sqlite3-worker1.mjs', + 'sqlite3-worker1': 'src/bin/sqlite3-worker1.mjs', }, format: ['esm'], dts: false, @@ -18,8 +18,8 @@ const tsdownConfig: UserConfig[] = [ }, }, onSuccess: () => { + copyFileSync('./LICENSE.md', './dist/LICENSE.md'); copyFileSync('./src/bin/sqlite3.wasm', './dist/sqlite3.wasm'); - copyFileSync('./dist/bin/sqlite3-worker1.mjs', './dist/sqlite3-worker1.mjs'); }, }), defineConfig({ @@ -44,7 +44,6 @@ const tsdownConfig: UserConfig[] = [ onSuccess: () => { copyFileSync('./dist/sqlite3-opfs-async-proxy.iife.js', './dist/sqlite3-opfs-async-proxy.js'); rmSync('./dist/sqlite3-opfs-async-proxy.iife.js'); - rmSync('./dist/bin', { recursive: true, force: true }); }, }), ];