sqlite-executor 4.0.1
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 +46 -0
- package/README.md +312 -0
- package/dist/cjs/constants.d.cts +2 -0
- package/dist/cjs/core/classifier.d.cts +13 -0
- package/dist/cjs/core/executor.d.cts +94 -0
- package/dist/cjs/core/lruCache.d.cts +16 -0
- package/dist/cjs/core/metrics.d.cts +84 -0
- package/dist/cjs/core/parser.d.cts +55 -0
- package/dist/cjs/core/pipelineEngine.d.cts +91 -0
- package/dist/cjs/core/process.d.cts +38 -0
- package/dist/cjs/core/protocol.d.cts +23 -0
- package/dist/cjs/core/queue.d.cts +40 -0
- package/dist/cjs/core/readerPool.d.cts +40 -0
- package/dist/cjs/core/settleUtils.d.cts +36 -0
- package/dist/cjs/core/taskWorker.d.cts +50 -0
- package/dist/cjs/core/transactionScope.d.cts +83 -0
- package/dist/cjs/index.cjs +3939 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +28 -0
- package/dist/cjs/stream/stream.d.cts +43 -0
- package/dist/cjs/transaction/transaction.d.cts +32 -0
- package/dist/cjs/utils/escape.d.cts +7 -0
- package/dist/cjs/utils/interpolate.d.cts +8 -0
- package/dist/cjs/utils/normalize.d.cts +7 -0
- package/dist/cjs/utils/timeout.d.cts +11 -0
- package/dist/cjs/utils/token.d.cts +7 -0
- package/dist/cjs/which.d.cts +8 -0
- package/dist/esm/constants.d.mts +2 -0
- package/dist/esm/core/classifier.d.mts +13 -0
- package/dist/esm/core/executor.d.mts +94 -0
- package/dist/esm/core/lruCache.d.mts +16 -0
- package/dist/esm/core/metrics.d.mts +84 -0
- package/dist/esm/core/parser.d.mts +55 -0
- package/dist/esm/core/pipelineEngine.d.mts +91 -0
- package/dist/esm/core/process.d.mts +38 -0
- package/dist/esm/core/protocol.d.mts +23 -0
- package/dist/esm/core/queue.d.mts +40 -0
- package/dist/esm/core/readerPool.d.mts +40 -0
- package/dist/esm/core/settleUtils.d.mts +36 -0
- package/dist/esm/core/taskWorker.d.mts +50 -0
- package/dist/esm/core/transactionScope.d.mts +83 -0
- package/dist/esm/index.d.mts +28 -0
- package/dist/esm/index.mjs +3865 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/stream/stream.d.mts +43 -0
- package/dist/esm/transaction/transaction.d.mts +32 -0
- package/dist/esm/utils/escape.d.mts +7 -0
- package/dist/esm/utils/interpolate.d.mts +8 -0
- package/dist/esm/utils/normalize.d.mts +7 -0
- package/dist/esm/utils/timeout.d.mts +11 -0
- package/dist/esm/utils/token.d.mts +7 -0
- package/dist/esm/which.d.mts +8 -0
- package/package.json +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Copyright (c) 2025 Axetroy
|
|
2
|
+
|
|
3
|
+
"Anti 996" License Version 1.0 (Draft)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted to any individual or legal entity
|
|
6
|
+
obtaining a copy of this licensed work (including the source code,
|
|
7
|
+
documentation and/or related items, hereinafter collectively referred
|
|
8
|
+
to as the "licensed work"), free of charge, to deal with the licensed
|
|
9
|
+
work for any purpose, including without limitation, the rights to use,
|
|
10
|
+
reproduce, modify, prepare derivative works of, distribute, publish
|
|
11
|
+
and sublicense the licensed work, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
1. The individual or the legal entity must conspicuously display,
|
|
14
|
+
without modification, this License and the notice on each redistributed
|
|
15
|
+
or derivative copy of the Licensed Work.
|
|
16
|
+
|
|
17
|
+
2. The individual or the legal entity must strictly comply with all
|
|
18
|
+
applicable laws, regulations, rules and standards of the jurisdiction
|
|
19
|
+
relating to labor and employment where the individual is physically
|
|
20
|
+
located or where the individual was born or naturalized; or where the
|
|
21
|
+
legal entity is registered or is operating (whichever is stricter). In
|
|
22
|
+
case that the jurisdiction has no such laws, regulations, rules and
|
|
23
|
+
standards or its laws, regulations, rules and standards are
|
|
24
|
+
unenforceable, the individual or the legal entity are required to
|
|
25
|
+
comply with Core International Labor Standards.
|
|
26
|
+
|
|
27
|
+
3. The individual or the legal entity shall not induce, suggest or force
|
|
28
|
+
its employee(s), whether full-time or part-time, or its independent
|
|
29
|
+
contractor(s), in any methods, to agree in oral or written form, to
|
|
30
|
+
directly or indirectly restrict, weaken or relinquish his or her
|
|
31
|
+
rights or remedies under such laws, regulations, rules and standards
|
|
32
|
+
relating to labor and employment as mentioned above, no matter whether
|
|
33
|
+
such written or oral agreements are enforceable under the laws of the
|
|
34
|
+
said jurisdiction, nor shall such individual or the legal entity
|
|
35
|
+
limit, in any methods, the rights of its employee(s) or independent
|
|
36
|
+
contractor(s) from reporting or complaining to the copyright holder or
|
|
37
|
+
relevant authorities monitoring the compliance of the license about
|
|
38
|
+
its violation(s) of the said license.
|
|
39
|
+
|
|
40
|
+
THE LICENSED WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
41
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
42
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
43
|
+
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM,
|
|
44
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
45
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN ANY WAY CONNECTION WITH THE
|
|
46
|
+
LICENSED WORK OR THE USE OR OTHER DEALINGS IN THE LICENSED WORK.
|
package/README.md
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# sqlite-executor
|
|
2
|
+
|
|
3
|
+
[](https://996.icu/#/en_US)
|
|
4
|
+
[](https://github.com/996icu/996.ICU/blob/master/LICENSE)
|
|
5
|
+

|
|
6
|
+
[](https://badge.fury.io/js/sqlite-executor)
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
A lightweight, zero-dependency SQLite wrapper for Node.js that communicates with the `sqlite3` CLI via stdin/stdout — no native addons, no `node-gyp`, no ABI headaches.
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- 🚀 **Zero native dependencies** — pure JavaScript, no compilation needed
|
|
14
|
+
- ⚡ **Long-lived process** — single `sqlite3` process for the entire app lifecycle
|
|
15
|
+
- 🔄 **Promise-based API** — `execute()`, `query()`, `stream()`
|
|
16
|
+
- 📦 **Async Iterator support** — `for await (const row of db.stream(sql))`
|
|
17
|
+
- 🔐 **Transactions** — automatic `BEGIN … COMMIT / ROLLBACK` with concurrent caller serialization
|
|
18
|
+
- 📊 **Read/Write Split** — dedicated reader pool for concurrent read queries
|
|
19
|
+
- ⏱️ **Timeout control** — per-statement timeout with process-level failure recovery
|
|
20
|
+
- 🔁 **Auto-restart** — crashed process restarts automatically
|
|
21
|
+
- 📈 **Runtime metrics** — QPS, avg query time, timeout count, process restarts
|
|
22
|
+
- 📝 **Full TypeScript types** — included
|
|
23
|
+
- 📦 **Dual module** — ESM + CommonJS
|
|
24
|
+
|
|
25
|
+
## Requirements
|
|
26
|
+
|
|
27
|
+
- Node.js >= 18
|
|
28
|
+
- `sqlite3` CLI executable available on the system
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install sqlite-executor --save
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
import { SQLiteExecutor } from "sqlite-executor";
|
|
40
|
+
|
|
41
|
+
const db = new SQLiteExecutor({ database: "./app.db" });
|
|
42
|
+
|
|
43
|
+
await db.execute(`CREATE TABLE IF NOT EXISTS users (
|
|
44
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
45
|
+
name TEXT
|
|
46
|
+
)`);
|
|
47
|
+
|
|
48
|
+
await db.execute("INSERT INTO users (name) VALUES (?)", ["Alice"]);
|
|
49
|
+
await db.execute("INSERT INTO users (name) VALUES (?)", ["Bob"]);
|
|
50
|
+
|
|
51
|
+
const rows = await db.query("SELECT * FROM users ORDER BY id ASC");
|
|
52
|
+
console.log(rows);
|
|
53
|
+
// [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]
|
|
54
|
+
|
|
55
|
+
await db.close();
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## API Reference
|
|
59
|
+
|
|
60
|
+
### `SQLiteExecutor`
|
|
61
|
+
|
|
62
|
+
#### Constructor
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
new SQLiteExecutor(options?)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Option | Type | Default | Description |
|
|
69
|
+
| ------------------- | --------- | -------------- | -------------------------------------------------------- |
|
|
70
|
+
| `binary` | `string` | `"sqlite3"` | Path to the `sqlite3` executable |
|
|
71
|
+
| `database` | `string` | `":memory:"` | Database file path |
|
|
72
|
+
| `logger` | `Logger` | — | Optional logger (`log`, `info`, `warn`, `error`, `debug`) |
|
|
73
|
+
| `statementTimeout` | `number` | `30000` | Per-statement timeout in milliseconds |
|
|
74
|
+
| `autoRestart` | `boolean` | `true` | Auto-restart on process crash |
|
|
75
|
+
| `poolSize` | `number` | `0` | Reader pool size (read/write split, file DB only) |
|
|
76
|
+
| `metrics` | `Metrics` | auto-created | Shared metrics instance |
|
|
77
|
+
|
|
78
|
+
#### `db.execute(sql, params?, options?)`
|
|
79
|
+
|
|
80
|
+
Executes a SQL statement without returning rows. Use for `CREATE`, `INSERT`, `UPDATE`, `DELETE`.
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
await db.execute("CREATE TABLE t (id INTEGER)");
|
|
84
|
+
await db.execute("INSERT INTO t (id) VALUES (?)", [1]);
|
|
85
|
+
await db.execute("UPDATE t SET id = ? WHERE id = ?", [2, 1]);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### `db.query(sql, params?, options?)`
|
|
89
|
+
|
|
90
|
+
Executes a query and returns all result rows as an array.
|
|
91
|
+
|
|
92
|
+
```js
|
|
93
|
+
const rows = await db.query("SELECT * FROM users WHERE id = ?", [1]);
|
|
94
|
+
// [ { id: 1, name: 'Alice' } ]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### `db.stream(sql, params?, options?)`
|
|
98
|
+
|
|
99
|
+
Returns an `AsyncIterable` for `for await` consumption.
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
for await (const row of db.stream("SELECT * FROM huge_table")) {
|
|
103
|
+
process(row);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Supports early `break` — the underlying process is not affected.
|
|
108
|
+
|
|
109
|
+
#### `db.transaction(fn, options?)`
|
|
110
|
+
|
|
111
|
+
Executes a callback inside a SQLite transaction (`BEGIN` / `COMMIT` / `ROLLBACK`). Concurrent calls are serialized — they never interleave.
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
await db.transaction(async (tx) => {
|
|
115
|
+
await tx.execute("INSERT INTO accounts (id, balance) VALUES (?, ?)", [1, 100]);
|
|
116
|
+
await tx.execute("INSERT INTO accounts (id, balance) VALUES (?, ?)", [2, 200]);
|
|
117
|
+
}, "IMMEDIATE");
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Inside the transaction callback, use the `tx` handle (`execute`, `query`, `stream`) — bare `db.*` calls would break transactional isolation.
|
|
121
|
+
|
|
122
|
+
| Option | Type | Default | Description |
|
|
123
|
+
| ------ | ---- | ------- | ----------- |
|
|
124
|
+
| `mode` | `"DEFERRED"` \| `"IMMEDIATE"` \| `"EXCLUSIVE"` | `"DEFERRED"` | SQLite transaction lock mode |
|
|
125
|
+
|
|
126
|
+
#### `db.close()`
|
|
127
|
+
|
|
128
|
+
Closes the sqlite3 process and rejects all pending tasks.
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
await db.close();
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`SQLiteExecutor` also implements `Symbol.asyncDispose` and `Symbol.dispose`:
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
// Using explicit resource management (ES2025)
|
|
138
|
+
await using db = new SQLiteExecutor({ database: "./app.db" });
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### `db.pendingStatements`
|
|
142
|
+
|
|
143
|
+
Returns the total number of pending statements across the writer queue, reader pool, and deferred queue.
|
|
144
|
+
|
|
145
|
+
#### `db.readerPool`
|
|
146
|
+
|
|
147
|
+
Returns the `ReaderPool` instance when `poolSize > 0` and the database is a file DB. Returns `null` otherwise.
|
|
148
|
+
|
|
149
|
+
#### `db.metrics`
|
|
150
|
+
|
|
151
|
+
Returns the `Metrics` instance. See below.
|
|
152
|
+
|
|
153
|
+
### `Metrics`
|
|
154
|
+
|
|
155
|
+
Runtime metrics collector, accessible via `db.metrics`.
|
|
156
|
+
|
|
157
|
+
```js
|
|
158
|
+
const stats = db.metrics.snapshot();
|
|
159
|
+
console.log(stats);
|
|
160
|
+
// {
|
|
161
|
+
// tasksTotal: 42,
|
|
162
|
+
// tasksSuccess: 40,
|
|
163
|
+
// tasksFailed: 2,
|
|
164
|
+
// tasksTimeout: 1,
|
|
165
|
+
// processRestarts: 0,
|
|
166
|
+
// executeCount: 20,
|
|
167
|
+
// queryCount: 22,
|
|
168
|
+
// streamCount: 0,
|
|
169
|
+
// avgQueryTime: 15.3, // ms
|
|
170
|
+
// qps: 8.2, // queries per second
|
|
171
|
+
// uptime: 5.1, // seconds
|
|
172
|
+
// }
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
| Method / Getter | Returns | Description |
|
|
176
|
+
| ---------------------- | -------------- | ------------------------------------ |
|
|
177
|
+
| `snapshot()` | `object` | All metrics as a plain object |
|
|
178
|
+
| `tasksTotal` | `number` | Total tasks enqueued |
|
|
179
|
+
| `tasksSuccess` | `number` | Successfully completed tasks |
|
|
180
|
+
| `tasksFailed` | `number` | Failed tasks |
|
|
181
|
+
| `tasksTimeout` | `number` | Timed-out tasks |
|
|
182
|
+
| `processRestarts` | `number` | sqlite3 process restarts |
|
|
183
|
+
| `executeCount` | `number` | `execute` calls |
|
|
184
|
+
| `queryCount` | `number` | `query` calls |
|
|
185
|
+
| `streamCount` | `number` | `stream` calls |
|
|
186
|
+
|
|
187
|
+
Multiple executors / workers can share the same `Metrics` instance:
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
import { SQLiteExecutor, Metrics } from "sqlite-executor";
|
|
191
|
+
|
|
192
|
+
const metrics = new Metrics();
|
|
193
|
+
|
|
194
|
+
const db1 = new SQLiteExecutor({ database: "./a.db", metrics });
|
|
195
|
+
const db2 = new SQLiteExecutor({ database: "./b.db", metrics });
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### TypeScript Usage
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { SQLiteExecutor } from "sqlite-executor";
|
|
202
|
+
|
|
203
|
+
interface User {
|
|
204
|
+
id: number;
|
|
205
|
+
name: string;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const db = new SQLiteExecutor({ database: "./users.db" });
|
|
209
|
+
|
|
210
|
+
await db.execute(`CREATE TABLE IF NOT EXISTS users (
|
|
211
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
212
|
+
name TEXT NOT NULL
|
|
213
|
+
)`);
|
|
214
|
+
|
|
215
|
+
const users = await db.query<User>("SELECT * FROM users");
|
|
216
|
+
// users: User[]
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Advanced Usage
|
|
220
|
+
|
|
221
|
+
### Read/Write Split with Reader Pool
|
|
222
|
+
|
|
223
|
+
For file-based databases, you can enable a reader pool for concurrent read queries:
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
const db = new SQLiteExecutor({
|
|
227
|
+
database: "./app.db",
|
|
228
|
+
poolSize: 3, // 3 reader processes
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Writes always go through the main writer process. Reads (`SELECT`, `WITH`, `VALUES`, `EXPLAIN`) are dispatched to a pool of `TaskWorker` instances via round-robin. This prevents long-running reads from blocking writes.
|
|
233
|
+
|
|
234
|
+
### Parameterized Queries
|
|
235
|
+
|
|
236
|
+
SQL parameters use `?` placeholders with automatic escaping:
|
|
237
|
+
|
|
238
|
+
```js
|
|
239
|
+
await db.execute("INSERT INTO users (name, email) VALUES (?, ?)", ["Alice", "alice@example.com"]);
|
|
240
|
+
const rows = await db.query("SELECT * FROM users WHERE email = ?", ["alice@example.com"]);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Supported parameter types:
|
|
244
|
+
|
|
245
|
+
| Type | SQL Output |
|
|
246
|
+
| -------------------- | --------------------------------------- |
|
|
247
|
+
| `string` | `'value'` (properly escaped) |
|
|
248
|
+
| `number` | `123` |
|
|
249
|
+
| `bigint` | `123` |
|
|
250
|
+
| `boolean` | `TRUE` / `FALSE` |
|
|
251
|
+
| `null` / `undefined` | `NULL` |
|
|
252
|
+
| `Date` | `'2024-01-15T10:30:00.000Z'` (ISO 8601) |
|
|
253
|
+
|
|
254
|
+
### Error Handling
|
|
255
|
+
|
|
256
|
+
SQL errors from sqlite3 are captured and the task promise is rejected:
|
|
257
|
+
|
|
258
|
+
```js
|
|
259
|
+
try {
|
|
260
|
+
await db.query("SELECT * FROM nonexistent");
|
|
261
|
+
} catch (err) {
|
|
262
|
+
console.log(err.message); // "Parse error near line 1: no such table: nonexistent"
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Process crashes are handled automatically — the current task and all queued tasks are rejected, and a new process is spawned (if `autoRestart` is enabled, which is the default).
|
|
267
|
+
|
|
268
|
+
### Using with Logger
|
|
269
|
+
|
|
270
|
+
```js
|
|
271
|
+
const db = new SQLiteExecutor({
|
|
272
|
+
database: "./app.db",
|
|
273
|
+
logger: {
|
|
274
|
+
log: console.log,
|
|
275
|
+
info: console.info,
|
|
276
|
+
warn: console.warn,
|
|
277
|
+
error: console.error,
|
|
278
|
+
debug: console.debug,
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Streaming Large Result Sets
|
|
284
|
+
|
|
285
|
+
```js
|
|
286
|
+
for await (const row of db.stream("SELECT * FROM logs WHERE created_at > ?", [date])) {
|
|
287
|
+
sendToClient(row);
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Benchmarks
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
npm run benchmark
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
See the [benchmark directory](./benchmark/README.md) for details.
|
|
298
|
+
|
|
299
|
+
## Project Structure
|
|
300
|
+
|
|
301
|
+
```text
|
|
302
|
+
src/ Source code
|
|
303
|
+
benchmark/ Performance benchmarks
|
|
304
|
+
script/ Utility scripts (e.g. sqlite binary download)
|
|
305
|
+
fixtures/ CJS/ESM fixtures for packaging tests
|
|
306
|
+
bin/ Downloaded sqlite3 binaries
|
|
307
|
+
dist/ Build outputs
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## License
|
|
311
|
+
|
|
312
|
+
The [Anti 996 License](LICENSE)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 对 SQL 语句进行分类,判断它是只读还是写入操作。
|
|
3
|
+
*
|
|
4
|
+
* 分类规则:
|
|
5
|
+
* - 以 SELECT / WITH / VALUES / EXPLAIN 开头 → `"read"`
|
|
6
|
+
* - 其余(INSERT、UPDATE、CREATE、DELETE 等)→ `"write"`
|
|
7
|
+
* - 多语句(以 `;` 分隔)中若包含任意写语句,整体返回 `"write"`
|
|
8
|
+
* - 空字符串或非字符串输入返回 `"write"`
|
|
9
|
+
*
|
|
10
|
+
* @param sql - 要分类的 SQL 语句
|
|
11
|
+
* @returns `"read"` 或 `"write"`
|
|
12
|
+
*/
|
|
13
|
+
export function classifySQL(sql: string): "read" | "write";
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** 日志接口,可选实现多个级别 */
|
|
2
|
+
export interface Logger {
|
|
3
|
+
log?(...messages: unknown[]): void;
|
|
4
|
+
info?(...messages: unknown[]): void;
|
|
5
|
+
warn?(...messages: unknown[]): void;
|
|
6
|
+
error?(...messages: unknown[]): void;
|
|
7
|
+
debug?(...messages: unknown[]): void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** SQLiteExecutor 构造选项 */
|
|
11
|
+
export interface SQLiteExecutorOptions {
|
|
12
|
+
/** sqlite3 可执行文件路径,默认自动查找 */
|
|
13
|
+
binary?: string;
|
|
14
|
+
/** 数据库文件路径,默认 ":memory:" */
|
|
15
|
+
database?: string;
|
|
16
|
+
/** 日志记录器 */
|
|
17
|
+
logger?: Logger;
|
|
18
|
+
/** 单条语句超时时间(毫秒),默认 30000 */
|
|
19
|
+
statementTimeout?: number;
|
|
20
|
+
/** 子进程崩溃后是否自动重启,默认 true */
|
|
21
|
+
autoRestart?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* 只读 Worker 池大小。
|
|
24
|
+
* - 设为 0(默认):不使用读写分离,所有操作走同一个 writer 进程
|
|
25
|
+
* - 设为 >0:启用读写分离,读操作分发到 reader pool
|
|
26
|
+
* - `:memory:` 数据库忽略此选项(始终为 0)
|
|
27
|
+
*/
|
|
28
|
+
poolSize?: number;
|
|
29
|
+
/**
|
|
30
|
+
* 运行时指标收集器。
|
|
31
|
+
* 未指定时自动创建内部实例。
|
|
32
|
+
*/
|
|
33
|
+
metrics?: import("./metrics.js").Metrics;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** 单条语句的执行选项 */
|
|
37
|
+
export interface StatementOptions {
|
|
38
|
+
/** 覆盖超时时间(毫秒) */
|
|
39
|
+
timeout?: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** 事务选项 */
|
|
43
|
+
export interface TransactionOptions {
|
|
44
|
+
/** 事务锁模式 */
|
|
45
|
+
mode?: "DEFERRED" | "IMMEDIATE" | "EXCLUSIVE";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** 事务句柄,在事务回调中代替 SQLiteExecutor 执行语句 */
|
|
49
|
+
export interface TransactionHandle {
|
|
50
|
+
execute(sql: string, params?: any[], options?: StatementOptions): Promise<void>;
|
|
51
|
+
query<T = any>(sql: string, params?: any[], options?: StatementOptions): Promise<T[]>;
|
|
52
|
+
stream<T = any>(sql: string, params?: any[], options?: StatementOptions): AsyncIterable<T>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* SQLiteExecutor - 异步 SQLite 执行器。
|
|
57
|
+
*
|
|
58
|
+
* 通过衍生 sqlite3 子进程(JSON 模式)执行 SQL 语句。
|
|
59
|
+
* 支持连接池、自动重启、超时控制、读写分离和流式查询。
|
|
60
|
+
*/
|
|
61
|
+
export declare class SQLiteExecutor implements AsyncDisposable, Disposable {
|
|
62
|
+
constructor(options?: SQLiteExecutorOptions);
|
|
63
|
+
|
|
64
|
+
/** 当前排队等待执行的语句数量 */
|
|
65
|
+
get pendingStatements(): number;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 只读 Worker 池实例。
|
|
69
|
+
* - 启用读写分离时(poolSize > 0 且非 :memory:)返回 ReaderPool
|
|
70
|
+
* - 否则返回 null
|
|
71
|
+
*/
|
|
72
|
+
get readerPool(): import("./readerPool.js").ReaderPool | null;
|
|
73
|
+
|
|
74
|
+
/** 运行时指标收集器。 */
|
|
75
|
+
get metrics(): import("./metrics.js").Metrics;
|
|
76
|
+
|
|
77
|
+
/** 执行写操作(INSERT/UPDATE/CREATE 等),返回无行结果 */
|
|
78
|
+
execute(sql: string, params?: any[], options?: StatementOptions): Promise<void>;
|
|
79
|
+
|
|
80
|
+
/** 执行查询并返回所有结果行数组 */
|
|
81
|
+
query<T = any>(sql: string, params?: any[], options?: StatementOptions): Promise<T[]>;
|
|
82
|
+
|
|
83
|
+
/** 流式执行查询,返回 AsyncIterable,可配合 `for await` 逐行消费 */
|
|
84
|
+
stream<T = any>(sql: string, params?: any[], options?: StatementOptions): AsyncIterable<T>;
|
|
85
|
+
|
|
86
|
+
/** 在事务中执行回调,所有操作在同一连接上完成 */
|
|
87
|
+
transaction<T>(fn: (tx: TransactionHandle) => Promise<T>, options?: TransactionOptions): Promise<T>;
|
|
88
|
+
|
|
89
|
+
/** 关闭所有子进程,释放资源 */
|
|
90
|
+
close(): Promise<void>;
|
|
91
|
+
|
|
92
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
93
|
+
[Symbol.dispose](): void;
|
|
94
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** 基于 Map 插入顺序的 LRU 缓存。 */
|
|
2
|
+
export declare class LRUCache<T> {
|
|
3
|
+
constructor(options?: { maxSize?: number; maxKeyLength?: number });
|
|
4
|
+
|
|
5
|
+
/** 获取缓存值,命中时提升到末尾。未命中或 key 不合法时返回 undefined。 */
|
|
6
|
+
get(key: string): T | undefined;
|
|
7
|
+
|
|
8
|
+
/** 设置缓存值。达到容量上限时淘汰最旧条目。超长 key 不缓存。 */
|
|
9
|
+
set(key: string, value: T): void;
|
|
10
|
+
|
|
11
|
+
/** 当前缓存条目数。 */
|
|
12
|
+
get size(): number;
|
|
13
|
+
|
|
14
|
+
/** 清空缓存。 */
|
|
15
|
+
clear(): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** Metrics.snapshot() 返回的快照结构 */
|
|
2
|
+
export interface MetricsSnapshot {
|
|
3
|
+
/** 总任务数 */
|
|
4
|
+
tasksTotal: number;
|
|
5
|
+
/** 成功任务数 */
|
|
6
|
+
tasksSuccess: number;
|
|
7
|
+
/** 失败任务数 */
|
|
8
|
+
tasksFailed: number;
|
|
9
|
+
/** 超时任务数 */
|
|
10
|
+
tasksTimeout: number;
|
|
11
|
+
/** 子进程重启次数 */
|
|
12
|
+
processRestarts: number;
|
|
13
|
+
/** execute 操作执行次数 */
|
|
14
|
+
executeCount: number;
|
|
15
|
+
/** query 操作执行次数 */
|
|
16
|
+
queryCount: number;
|
|
17
|
+
/** stream 操作执行次数 */
|
|
18
|
+
streamCount: number;
|
|
19
|
+
/** 平均查询耗时(毫秒) */
|
|
20
|
+
avgQueryTime: number;
|
|
21
|
+
/** 每秒查询数 */
|
|
22
|
+
qps: number;
|
|
23
|
+
/** 运行时长(秒) */
|
|
24
|
+
uptime: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 运行时指标收集器。
|
|
29
|
+
*
|
|
30
|
+
* 追踪 SQL 执行任务的吞吐、耗时、错误、超时和进程重启。
|
|
31
|
+
* 可通过 `snapshot()` 获取当前快照用于监控和告警。
|
|
32
|
+
*/
|
|
33
|
+
export declare class Metrics {
|
|
34
|
+
/** 总任务数 */
|
|
35
|
+
get tasksTotal(): number;
|
|
36
|
+
/** 成功任务数 */
|
|
37
|
+
get tasksSuccess(): number;
|
|
38
|
+
/** 失败任务数 */
|
|
39
|
+
get tasksFailed(): number;
|
|
40
|
+
/** 超时任务数 */
|
|
41
|
+
get tasksTimeout(): number;
|
|
42
|
+
/** 子进程重启次数 */
|
|
43
|
+
get processRestarts(): number;
|
|
44
|
+
/** execute 操作执行次数 */
|
|
45
|
+
get executeCount(): number;
|
|
46
|
+
/** query 操作执行次数 */
|
|
47
|
+
get queryCount(): number;
|
|
48
|
+
/** stream 操作执行次数 */
|
|
49
|
+
get streamCount(): number;
|
|
50
|
+
/** 所有成功任务的总耗时(毫秒) */
|
|
51
|
+
get totalDuration(): number;
|
|
52
|
+
/** Metrics 实例的创建时间戳 */
|
|
53
|
+
get startTime(): number;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 增加任务总数计数。
|
|
57
|
+
*
|
|
58
|
+
* @param kind - 任务类型:execute(写操作)、query(查询)、stream(流式查询)
|
|
59
|
+
*/
|
|
60
|
+
incrementTasksTotal(kind: "execute" | "query" | "stream"): void;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 增加成功任务计数,并累加耗时。
|
|
64
|
+
*
|
|
65
|
+
* @param duration - 任务执行耗时(毫秒)
|
|
66
|
+
*/
|
|
67
|
+
incrementTasksSuccess(duration: number): void;
|
|
68
|
+
|
|
69
|
+
/** 增加失败任务计数。 */
|
|
70
|
+
incrementTasksFailed(): void;
|
|
71
|
+
|
|
72
|
+
/** 增加超时任务计数。 */
|
|
73
|
+
incrementTasksTimeout(): void;
|
|
74
|
+
|
|
75
|
+
/** 增加子进程重启次数计数。 */
|
|
76
|
+
incrementProcessRestarts(): void;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 获取当前运行时指标快照。
|
|
80
|
+
*
|
|
81
|
+
* @returns 当前所有指标的汇总快照
|
|
82
|
+
*/
|
|
83
|
+
snapshot(): MetricsSnapshot;
|
|
84
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** JSON 值流式解析器的状态 */
|
|
2
|
+
export interface JsonValueParser {
|
|
3
|
+
feed(chunk: string): void;
|
|
4
|
+
reset(): void;
|
|
5
|
+
buffer: string;
|
|
6
|
+
start: number;
|
|
7
|
+
readPos: number;
|
|
8
|
+
nesting: number;
|
|
9
|
+
inString: boolean;
|
|
10
|
+
escaped: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** 行流解析器的状态 */
|
|
14
|
+
export interface RowStreamParser {
|
|
15
|
+
feed(chunk: string): string;
|
|
16
|
+
reset(): void;
|
|
17
|
+
buffer: string;
|
|
18
|
+
started: boolean;
|
|
19
|
+
finished: boolean;
|
|
20
|
+
inString: boolean;
|
|
21
|
+
escaped: boolean;
|
|
22
|
+
elementStart: number;
|
|
23
|
+
elementEnd: number;
|
|
24
|
+
nesting: number;
|
|
25
|
+
readPos: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 将任意值转为 Error 对象。
|
|
30
|
+
* 如果值已经是 Error 则直接返回,否则包装为 Error。
|
|
31
|
+
*
|
|
32
|
+
* @param value - 可能为 Error、string 或其他类型的值
|
|
33
|
+
* @returns Error 实例
|
|
34
|
+
*/
|
|
35
|
+
export function toError(value: unknown): Error;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 创建一个 JSON 值流式解析器。
|
|
39
|
+
* 从 JSON 数组的块式输入中逐个提取完整值,通过回调通知。
|
|
40
|
+
* 适用于 parse 完整的 JSON 结果。
|
|
41
|
+
*
|
|
42
|
+
* @param onValue - 每次解析出一个完整值时的回调
|
|
43
|
+
* @returns 解析器实例
|
|
44
|
+
*/
|
|
45
|
+
export function createJsonValueParser(onValue: (raw: string) => void): JsonValueParser;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 创建一个行流解析器。
|
|
49
|
+
* 从 JSON 数组的块式输入中逐行提取原始字符串,通过回调通知。
|
|
50
|
+
* 适用于流式逐行处理结果而不缓存全部数据。
|
|
51
|
+
*
|
|
52
|
+
* @param onRow - 每解析出一行时的回调
|
|
53
|
+
* @returns 解析器实例
|
|
54
|
+
*/
|
|
55
|
+
export function createRowStreamParser(onRow: (rawRow: string) => void): RowStreamParser;
|