web-sqlite-js 1.1.1 → 2.1.0
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/README.md +193 -48
- package/dist/index.d.ts +28 -0
- package/dist/index.js +2 -2
- package/package.json +83 -83
package/README.md
CHANGED
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
<a href="https://www.npmjs.com/package/web-sqlite-js" target="_blank">
|
|
14
14
|
<img src="https://img.shields.io/npm/v/web-sqlite-js.svg" alt="NPM Version" />
|
|
15
15
|
</a>
|
|
16
|
+
<a href="https://github.com/wuchuheng/web-sqlite-js/discussions" target="_blank">
|
|
17
|
+
<img src="https://img.shields.io/badge/v2.0.0-new%20features-blue" alt="v2.0.0" />
|
|
18
|
+
</a>
|
|
16
19
|
<a href="https://github.com/wuchuheng/web-sqlite-js/blob/main/LICENSE" target="_blank">
|
|
17
20
|
<img src="https://img.shields.io/github/license/wuchuheng/web-sqlite-js.svg" alt="License" />
|
|
18
21
|
</a>
|
|
@@ -35,6 +38,9 @@ Designed to be truly effortless, it allows you to get a high-performance relatio
|
|
|
35
38
|
- [Usage](#usage)
|
|
36
39
|
- [Debug mode](#debug-mode)
|
|
37
40
|
- [Transactions](#transactions)
|
|
41
|
+
- [Structured Logging (v2.0.0)](#structured-logging-v200)
|
|
42
|
+
- [Global Database Access (v2.0.0)](#global-database-access-v200)
|
|
43
|
+
- [Database Events (v2.0.0)](#database-events-v200)
|
|
38
44
|
|
|
39
45
|
## Features
|
|
40
46
|
|
|
@@ -43,6 +49,10 @@ Designed to be truly effortless, it allows you to get a high-performance relatio
|
|
|
43
49
|
- **Concurrency Safe**: Built-in mutex ensures safe, sequential execution of commands.
|
|
44
50
|
- **Type-Safe**: Written in TypeScript with full type definitions.
|
|
45
51
|
- **Transactions**: Supports atomic transactions with automatic rollback on error.
|
|
52
|
+
- **Structured Logging** (v2.0.0): Subscribe to SQL execution logs via `onLog()`.
|
|
53
|
+
- **Global Namespace** (v2.0.0): Access databases from anywhere via `window.__web_sqlite`.
|
|
54
|
+
- **Database Events** (v2.0.0): Listen to database open/close events for UI synchronization.
|
|
55
|
+
- **Database Registry** (v2.0.0): Prevents duplicate database opens with automatic tracking.
|
|
46
56
|
|
|
47
57
|
## Quick start
|
|
48
58
|
|
|
@@ -66,8 +76,8 @@ For quick demos or plain HTML pages you can load the prebuilt module directly:
|
|
|
66
76
|
|
|
67
77
|
```html
|
|
68
78
|
<script type="module">
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
import openDB from "https://cdn.jsdelivr.net/npm/web-sqlite-js@1.0.9/dist/index.js";
|
|
80
|
+
// ...
|
|
71
81
|
</script>
|
|
72
82
|
```
|
|
73
83
|
|
|
@@ -95,18 +105,18 @@ Update your `vite.config.ts`:
|
|
|
95
105
|
import { defineConfig } from "vite";
|
|
96
106
|
|
|
97
107
|
export default defineConfig({
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
},
|
|
108
|
+
server: {
|
|
109
|
+
headers: {
|
|
110
|
+
"Cross-Origin-Opener-Policy": "same-origin",
|
|
111
|
+
"Cross-Origin-Embedder-Policy": "require-corp",
|
|
103
112
|
},
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
},
|
|
114
|
+
preview: {
|
|
115
|
+
headers: {
|
|
116
|
+
"Cross-Origin-Opener-Policy": "same-origin",
|
|
117
|
+
"Cross-Origin-Embedder-Policy": "require-corp",
|
|
109
118
|
},
|
|
119
|
+
},
|
|
110
120
|
});
|
|
111
121
|
```
|
|
112
122
|
|
|
@@ -120,23 +130,23 @@ Update your `next.config.js`:
|
|
|
120
130
|
```javascript
|
|
121
131
|
/** @type {import('next').NextConfig} */
|
|
122
132
|
const nextConfig = {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
133
|
+
async headers() {
|
|
134
|
+
return [
|
|
135
|
+
{
|
|
136
|
+
source: "/(.*)",
|
|
137
|
+
headers: [
|
|
138
|
+
{
|
|
139
|
+
key: "Cross-Origin-Opener-Policy",
|
|
140
|
+
value: "same-origin",
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
key: "Cross-Origin-Embedder-Policy",
|
|
144
|
+
value: "require-corp",
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
];
|
|
149
|
+
},
|
|
140
150
|
};
|
|
141
151
|
|
|
142
152
|
module.exports = nextConfig;
|
|
@@ -151,13 +161,13 @@ Update your `webpack.config.js`:
|
|
|
151
161
|
|
|
152
162
|
```javascript
|
|
153
163
|
module.exports = {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
},
|
|
164
|
+
// ...
|
|
165
|
+
devServer: {
|
|
166
|
+
headers: {
|
|
167
|
+
"Cross-Origin-Opener-Policy": "same-origin",
|
|
168
|
+
"Cross-Origin-Embedder-Policy": "require-corp",
|
|
160
169
|
},
|
|
170
|
+
},
|
|
161
171
|
};
|
|
162
172
|
```
|
|
163
173
|
|
|
@@ -189,9 +199,9 @@ const express = require("express");
|
|
|
189
199
|
const app = express();
|
|
190
200
|
|
|
191
201
|
app.use((req, res, next) => {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
202
|
+
res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
|
|
203
|
+
res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
|
|
204
|
+
next();
|
|
195
205
|
});
|
|
196
206
|
|
|
197
207
|
// ...
|
|
@@ -227,12 +237,12 @@ await db.exec(`
|
|
|
227
237
|
|
|
228
238
|
// 3. Insert data (Parameterized)
|
|
229
239
|
await db.exec("INSERT INTO users (name, email) VALUES (?, ?)", [
|
|
230
|
-
|
|
231
|
-
|
|
240
|
+
"Alice",
|
|
241
|
+
"alice@example.com",
|
|
232
242
|
]);
|
|
233
243
|
await db.exec("INSERT INTO users (name, email) VALUES ($name, $email)", {
|
|
234
|
-
|
|
235
|
-
|
|
244
|
+
$name: "Bob",
|
|
245
|
+
$email: "bob@example.com",
|
|
236
246
|
});
|
|
237
247
|
|
|
238
248
|
// 4. Query data
|
|
@@ -258,7 +268,7 @@ await db.query("SELECT * FROM notes WHERE id = ?", [1]);
|
|
|
258
268
|
|
|
259
269
|
The console output highlights SQL keywords and shows how long each statement took (click to preview):
|
|
260
270
|
|
|
261
|
-
[](docs/assets/debug.png)
|
|
271
|
+
[](docs/assets/debug.png)
|
|
262
272
|
|
|
263
273
|
#### Transactions
|
|
264
274
|
|
|
@@ -266,16 +276,151 @@ Transactions are atomic. If any command inside the callback fails, the entire tr
|
|
|
266
276
|
|
|
267
277
|
```typescript
|
|
268
278
|
await db.transaction(async (tx) => {
|
|
269
|
-
|
|
279
|
+
await tx.exec("INSERT INTO users (name) VALUES (?)", ["Charlie"]);
|
|
280
|
+
|
|
281
|
+
// You can perform multiple operations safely
|
|
282
|
+
await tx.exec("INSERT INTO logs (action) VALUES (?)", ["User Created"]);
|
|
283
|
+
|
|
284
|
+
// If you throw an error here, both INSERTs will be rolled back!
|
|
285
|
+
// throw new Error('Something went wrong');
|
|
286
|
+
});
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Structured Logging (v2.0.0)
|
|
290
|
+
|
|
291
|
+
Subscribe to structured log events for monitoring, debugging, and analytics. The `onLog()` API allows you to capture SQL execution details, errors, and application events.
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
const db = await openDB("myapp");
|
|
295
|
+
|
|
296
|
+
// Register log listener
|
|
297
|
+
const cancelLog = db.onLog((log) => {
|
|
298
|
+
if (log.level === "error") {
|
|
299
|
+
// Send errors to tracking service
|
|
300
|
+
errorTracking.capture(log.data);
|
|
301
|
+
} else if (log.level === "debug") {
|
|
302
|
+
// Log SQL execution details
|
|
303
|
+
console.log(`SQL: ${log.data.sql}, Duration: ${log.data.duration}ms`);
|
|
304
|
+
} else if (log.level === "info") {
|
|
305
|
+
// Track application events (open, close, transactions)
|
|
306
|
+
console.log(`Event: ${log.data.action}`);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Execute some SQL to generate logs
|
|
311
|
+
await db.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
|
|
312
|
+
await db.exec("INSERT INTO users (name) VALUES (?)", ["Alice"]);
|
|
313
|
+
|
|
314
|
+
// Later: stop listening
|
|
315
|
+
cancelLog();
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Log Levels**:
|
|
270
319
|
|
|
271
|
-
|
|
272
|
-
|
|
320
|
+
- `"debug"` - SQL execution details (sql, duration, bind parameters)
|
|
321
|
+
- `"info"` - Application events (open, close, commit, rollback)
|
|
322
|
+
- `"error"` - SQL errors and exceptions
|
|
273
323
|
|
|
274
|
-
|
|
275
|
-
|
|
324
|
+
**Multiple Callbacks**: You can register multiple log listeners simultaneously:
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
const cancel1 = db.onLog((log) => console.log("Logger 1:", log));
|
|
328
|
+
const cancel2 = db.onLog((log) => {
|
|
329
|
+
if (log.level === "error") sendToAlerting(log.data);
|
|
276
330
|
});
|
|
277
331
|
```
|
|
278
332
|
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## Global Database Access (v2.0.0)
|
|
336
|
+
|
|
337
|
+
Access opened databases from anywhere in your application without imports. The `window.__web_sqlite` global namespace provides direct references to all opened database instances.
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
// Open database in module A
|
|
341
|
+
const db = await openDB("app");
|
|
342
|
+
|
|
343
|
+
// In module B (no import needed):
|
|
344
|
+
const db = window.__web_sqlite.databases["app.sqlite3"];
|
|
345
|
+
const users = await db.query("SELECT * FROM users");
|
|
346
|
+
|
|
347
|
+
// List all opened databases
|
|
348
|
+
console.log(Object.keys(window.__web_sqlite.databases));
|
|
349
|
+
// Output: ["app.sqlite3", "users.sqlite3"]
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
**Use Cases**:
|
|
353
|
+
|
|
354
|
+
- **DevTools Integration**: Access databases from browser console for debugging
|
|
355
|
+
- **Cross-Module Communication**: Share database state without prop drilling
|
|
356
|
+
- **Debugging**: Inspect and query databases directly from DevTools console
|
|
357
|
+
|
|
358
|
+
**Browser Console Example**:
|
|
359
|
+
|
|
360
|
+
```javascript
|
|
361
|
+
// From browser DevTools console:
|
|
362
|
+
window.__web_sqlite.databases["app.sqlite3"]
|
|
363
|
+
.query("SELECT * FROM users")
|
|
364
|
+
.then((users) => console.table(users));
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Database Events (v2.0.0)
|
|
370
|
+
|
|
371
|
+
Subscribe to database open/close events for UI synchronization and monitoring. The `onDatabaseChange()` API notifies you when databases are opened or closed.
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
// Subscribe to database changes
|
|
375
|
+
const unsubscribe = window.__web_sqlite.onDatabaseChange((event) => {
|
|
376
|
+
if (event.action === "opened") {
|
|
377
|
+
console.log(`Database opened: ${event.dbName}`);
|
|
378
|
+
updateDatabaseList(event.databases);
|
|
379
|
+
} else if (event.action === "closed") {
|
|
380
|
+
console.log(`Database closed: ${event.dbName}`);
|
|
381
|
+
updateDatabaseList(event.databases);
|
|
382
|
+
}
|
|
383
|
+
console.log("Current databases:", event.databases);
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// Open a database
|
|
387
|
+
await openDB("app");
|
|
388
|
+
// Output: Database opened: app.sqlite3
|
|
389
|
+
// Output: Current databases: ["app.sqlite3"]
|
|
390
|
+
|
|
391
|
+
// Open another database
|
|
392
|
+
await openDB("users");
|
|
393
|
+
// Output: Database opened: users.sqlite3
|
|
394
|
+
// Output: Current databases: ["app.sqlite3", "users.sqlite3"]
|
|
395
|
+
|
|
396
|
+
// Close first database
|
|
397
|
+
await window.__web_sqlite.databases["app.sqlite3"].close();
|
|
398
|
+
// Output: Database closed: app.sqlite3
|
|
399
|
+
// Output: Current databases: ["users.sqlite3"]
|
|
400
|
+
|
|
401
|
+
// Unsubscribe when done
|
|
402
|
+
// unsubscribe();
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
**Event Structure**:
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
interface DatabaseChangeEvent {
|
|
409
|
+
action: "opened" | "closed"; // What happened
|
|
410
|
+
dbName: string; // Which database (normalized name)
|
|
411
|
+
databases: string[]; // All currently opened database names
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**Use Cases**:
|
|
416
|
+
|
|
417
|
+
- **DevTools Panels**: Show active databases in browser DevTools
|
|
418
|
+
- **UI Updates**: Refresh database list when databases open/close
|
|
419
|
+
- **Monitoring**: Track database lifecycle for debugging
|
|
420
|
+
- **Multi-Window Sync**: Coordinate database access across browser windows
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
279
424
|
## Star History
|
|
280
425
|
|
|
281
426
|
<p align="left">
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,20 @@ declare interface DBInterface {
|
|
|
21
21
|
transaction<T>(fn: transactionCallback<T>): Promise<T>;
|
|
22
22
|
/** Close the database and release resources. */
|
|
23
23
|
close(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Subscribe to log events
|
|
26
|
+
* Logs include SQL execution, timing, errors, and application events
|
|
27
|
+
*
|
|
28
|
+
* @param callback - Called for each log entry
|
|
29
|
+
* @returns Unsubscribe function
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* const unsubscribe = db.onLog((log) => {
|
|
33
|
+
* console.log(`[${log.level}]`, log.data);
|
|
34
|
+
* });
|
|
35
|
+
* // Later: unsubscribe();
|
|
36
|
+
*/
|
|
37
|
+
onLog(callback: (log: LogEntry) => void): () => void;
|
|
24
38
|
/** Dev tooling APIs for release testing. */
|
|
25
39
|
devTool: DevTool;
|
|
26
40
|
}
|
|
@@ -46,6 +60,20 @@ declare type ExecResult = {
|
|
|
46
60
|
lastInsertRowid?: number | bigint;
|
|
47
61
|
};
|
|
48
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Log entry with level and structured data
|
|
65
|
+
*/
|
|
66
|
+
declare type LogEntry = {
|
|
67
|
+
/**
|
|
68
|
+
* Log level: 'info' | 'debug' | 'error'
|
|
69
|
+
*/
|
|
70
|
+
level: "info" | "debug" | "error";
|
|
71
|
+
/**
|
|
72
|
+
* Log data (SQL, timing, errors, events, etc.)
|
|
73
|
+
*/
|
|
74
|
+
data: unknown;
|
|
75
|
+
};
|
|
76
|
+
|
|
49
77
|
/**
|
|
50
78
|
* Opens a SQLite database connection with release-versioning support.
|
|
51
79
|
*
|