web-sqlite-js 0.0.1 → 0.0.2-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 wuchuheng
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,250 @@
1
+ # web-sqlite-js
2
+
3
+ Enables direct use of SQLite in the web browser with reliable local data persistence via OPFS (Origin Private File System).
4
+
5
+ It runs SQLite in a Web Worker to avoid blocking the main thread and handles all synchronization automatically, providing a simple, Promise-based API.
6
+
7
+ ## Features
8
+
9
+ - **Persistent Storage**: Uses OPFS for high-performance, persistent file storage.
10
+ - **Non-Blocking**: Runs in a Web Worker, keeping your UI responsive.
11
+ - **Concurrency Safe**: Built-in mutex ensures safe, sequential execution of commands.
12
+ - **Type-Safe**: Written in TypeScript with full type definitions.
13
+ - **Transactions**: Supports atomic transactions with automatic rollback on error.
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install web-sqlite-js
19
+ ```
20
+
21
+ ## ⚠️ Critical Configuration: COOP & COEP
22
+
23
+ To use `SharedArrayBuffer` (required by the SQLite WASM build), your server **must** serve the application with the following HTTP headers:
24
+
25
+ ```http
26
+ Cross-Origin-Opener-Policy: same-origin
27
+ Cross-Origin-Embedder-Policy: require-corp
28
+ ```
29
+
30
+ If these headers are missing, the database **will not start**.
31
+
32
+ ### Configuration Guides
33
+
34
+ <details>
35
+ <summary><strong>Vite</strong></summary>
36
+
37
+ Update your `vite.config.ts`:
38
+
39
+ ```typescript
40
+ import { defineConfig } from "vite";
41
+
42
+ export default defineConfig({
43
+ server: {
44
+ headers: {
45
+ "Cross-Origin-Opener-Policy": "same-origin",
46
+ "Cross-Origin-Embedder-Policy": "require-corp",
47
+ },
48
+ },
49
+ preview: {
50
+ headers: {
51
+ "Cross-Origin-Opener-Policy": "same-origin",
52
+ "Cross-Origin-Embedder-Policy": "require-corp",
53
+ },
54
+ },
55
+ });
56
+ ```
57
+
58
+ </details>
59
+
60
+ <details>
61
+ <summary><strong>Next.js</strong></summary>
62
+
63
+ Update your `next.config.js`:
64
+
65
+ ```javascript
66
+ /** @type {import('next').NextConfig} */
67
+ const nextConfig = {
68
+ async headers() {
69
+ return [
70
+ {
71
+ source: "/(.*)",
72
+ headers: [
73
+ {
74
+ key: "Cross-Origin-Opener-Policy",
75
+ value: "same-origin",
76
+ },
77
+ {
78
+ key: "Cross-Origin-Embedder-Policy",
79
+ value: "require-corp",
80
+ },
81
+ ],
82
+ },
83
+ ];
84
+ },
85
+ };
86
+
87
+ module.exports = nextConfig;
88
+ ```
89
+
90
+ </details>
91
+
92
+ <details>
93
+ <summary><strong>Webpack (Dev Server)</strong></summary>
94
+
95
+ Update your `webpack.config.js`:
96
+
97
+ ```javascript
98
+ module.exports = {
99
+ // ...
100
+ devServer: {
101
+ headers: {
102
+ "Cross-Origin-Opener-Policy": "same-origin",
103
+ "Cross-Origin-Embedder-Policy": "require-corp",
104
+ },
105
+ },
106
+ };
107
+ ```
108
+
109
+ </details>
110
+
111
+ <details>
112
+ <summary><strong>Nginx</strong></summary>
113
+
114
+ Add the headers to your server block:
115
+
116
+ ```nginx
117
+ server {
118
+ # ...
119
+ add_header Cross-Origin-Opener-Policy "same-origin";
120
+ add_header Cross-Origin-Embedder-Policy "require-corp";
121
+ # ...
122
+ }
123
+ ```
124
+
125
+ </details>
126
+
127
+ <details>
128
+ <summary><strong>Express.js</strong></summary>
129
+
130
+ Use a middleware:
131
+
132
+ ```javascript
133
+ const express = require("express");
134
+ const app = express();
135
+
136
+ app.use((req, res, next) => {
137
+ res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
138
+ res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
139
+ next();
140
+ });
141
+
142
+ // ...
143
+ ```
144
+
145
+ </details>
146
+
147
+ <details>
148
+ <summary><strong>React / Vue (Create React App / Vue CLI)</strong></summary>
149
+
150
+ Most modern React/Vue setups use **Vite**. Please refer to the **Vite** section above.
151
+
152
+ If you are using an older webpack-based setup (like CRA `react-scripts`), you technically need to configure the underlying `webpack-dev-server`, but CRA doesn't expose this easily without ejecting or using tools like `craco` or `react-app-rewired` to modify the dev server configuration as shown in the **Webpack** section.
153
+
154
+ </details>
155
+
156
+ ## Usage
157
+
158
+ ### Basic Query
159
+
160
+ ```typescript
161
+ import openDB from "web-sqlite-js";
162
+
163
+ // 1. Open the database (creates 'my-database.sqlite3' in OPFS)
164
+ const db = await openDB("my-database");
165
+
166
+ // 2. Initialize schema
167
+ await db.exec(`
168
+ CREATE TABLE IF NOT EXISTS users (
169
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
170
+ name TEXT,
171
+ email TEXT
172
+ );
173
+ `);
174
+
175
+ // 3. Insert data (Parameterized)
176
+ await db.exec("INSERT INTO users (name, email) VALUES (?, ?)", [
177
+ "Alice",
178
+ "alice@example.com",
179
+ ]);
180
+ await db.exec("INSERT INTO users (name, email) VALUES ($name, $email)", {
181
+ $name: "Bob",
182
+ $email: "bob@example.com",
183
+ });
184
+
185
+ // 4. Query data
186
+ interface User {
187
+ id: number;
188
+ name: string;
189
+ email: string;
190
+ }
191
+
192
+ const users = await db.query<User>("SELECT * FROM users");
193
+ console.log(users);
194
+ // Output: [{ id: 1, name: 'Alice', ... }, { id: 2, name: 'Bob', ... }]
195
+
196
+ // 5. Close when done
197
+ await db.close();
198
+ ```
199
+
200
+ ### Transactions
201
+
202
+ Transactions are atomic. If any command inside the callback fails, the entire transaction is rolled back.
203
+
204
+ ```typescript
205
+ await db.transaction(async (tx) => {
206
+ await tx.exec("INSERT INTO users (name) VALUES (?)", ["Charlie"]);
207
+
208
+ // You can perform multiple operations safely
209
+ await tx.exec("INSERT INTO logs (action) VALUES (?)", ["User Created"]);
210
+
211
+ // If you throw an error here, both INSERTs will be rolled back!
212
+ // throw new Error('Something went wrong');
213
+ });
214
+ ```
215
+
216
+ ### Multiple Connections
217
+
218
+ You can open multiple connections to the same file. They will automatically synchronize access.
219
+
220
+ ```typescript
221
+ const db1 = await openDB("shared-db");
222
+ const db2 = await openDB("shared-db");
223
+
224
+ await db1.exec("INSERT INTO items (name) VALUES (?)", ["Item 1"]);
225
+
226
+ // db2 sees the change immediately after db1 finishes
227
+ const items = await db2.query("SELECT * FROM items");
228
+ ```
229
+
230
+ ## API
231
+
232
+ ### `openDB(filename: string, options?: { debug?: boolean })`
233
+
234
+ Opens a database connection. Returns a `DBInterface`.
235
+
236
+ ### `db.exec(sql: string, params?: any[] | Record<string, any>)`
237
+
238
+ Executes a SQL statement (INSERT, UPDATE, DELETE, CREATE). Returns `{ changes, lastInsertRowid }`.
239
+
240
+ ### `db.query<T>(sql: string, params?: any[] | Record<string, any>)`
241
+
242
+ Executes a SELECT statement. Returns an array of rows `T[]`.
243
+
244
+ ### `db.transaction<T>(callback: (tx: DBInterface) => Promise<T>)`
245
+
246
+ Runs the callback inside a transaction (`BEGIN` ... `COMMIT`/`ROLLBACK`). The `tx` object provided to the callback has the same `exec` and `query` methods.
247
+
248
+ ### `db.close()`
249
+
250
+ Closes the connection and terminates the worker.
package/dist/index.js CHANGED
@@ -12743,7 +12743,6 @@ if(!globalThis.SharedArrayBuffer){
12743
12743
  return sIM;
12744
12744
  })();
12745
12745
  sqlite3InitModule = toExportForESM;
12746
- var sqlite3InitModule$1 = sqlite3InitModule;
12747
12746
  var SqliteEvent = /* @__PURE__ */ ((SqliteEvent2) => {
12748
12747
  SqliteEvent2["OPEN"] = "open";
12749
12748
  SqliteEvent2["CLOSE"] = "close";
@@ -12865,7 +12864,7 @@ if(!globalThis.SharedArrayBuffer){
12865
12864
  if (typeof payload.filename !== "string") {
12866
12865
  throw new Error("Invalid payload for OPEN event: expected filename string");
12867
12866
  }
12868
- sqlite3 = await sqlite3InitModule$1();
12867
+ sqlite3 = await sqlite3InitModule();
12869
12868
  console.debug(\`Initialized sqlite3 module in worker.\`);
12870
12869
  let { filename } = payload;
12871
12870
  if (!filename.endsWith(".sqlite3")) {
package/package.json CHANGED
@@ -1,10 +1,21 @@
1
1
  {
2
2
  "name": "web-sqlite-js",
3
- "version": "0.0.1",
4
- "description": "",
3
+ "version": "0.0.2-beta",
4
+ "description": "Enables direct use of SQLite in the web browser with reliable local data persistence via OPFS.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
+ "author": "wuchuheng <root@wuchuheng.com>",
9
+ "keywords": [
10
+ "sqlite",
11
+ "wasm",
12
+ "opfs",
13
+ "web-worker",
14
+ "database",
15
+ "typescript",
16
+ "web-sqlite"
17
+ ],
18
+ "sideEffects": false,
8
19
  "exports": {
9
20
  ".": {
10
21
  "types": "./dist/index.d.ts",
@@ -27,7 +38,9 @@
27
38
  "package:publish": "npm run test && npm run build && npm publish --access public"
28
39
  },
29
40
  "files": [
30
- "dist"
41
+ "dist",
42
+ "LICENSE",
43
+ "README.md"
31
44
  ],
32
45
  "devDependencies": {
33
46
  "@eslint/css": "^0.14.1",
@@ -53,12 +66,11 @@
53
66
  },
54
67
  "repository": {
55
68
  "type": "git",
56
- "url": "git+https://github.com/wuchuheng/web-sqlite-v2.git"
69
+ "url": "git+https://github.com/wuchuheng/web-sqlite-js.git"
57
70
  },
58
- "author": "",
59
- "license": "ISC",
71
+ "license": "MIT",
60
72
  "bugs": {
61
- "url": "https://github.com/wuchuheng/web-sqlite-v2/issues"
73
+ "url": "https://github.com/wuchuheng/web-sqlite-js/issues"
62
74
  },
63
- "homepage": "https://github.com/wuchuheng/web-sqlite-v2#readme"
75
+ "homepage": "https://github.com/wuchuheng/web-sqlite-js#readme"
64
76
  }