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.
Files changed (53) hide show
  1. package/LICENSE +46 -0
  2. package/README.md +312 -0
  3. package/dist/cjs/constants.d.cts +2 -0
  4. package/dist/cjs/core/classifier.d.cts +13 -0
  5. package/dist/cjs/core/executor.d.cts +94 -0
  6. package/dist/cjs/core/lruCache.d.cts +16 -0
  7. package/dist/cjs/core/metrics.d.cts +84 -0
  8. package/dist/cjs/core/parser.d.cts +55 -0
  9. package/dist/cjs/core/pipelineEngine.d.cts +91 -0
  10. package/dist/cjs/core/process.d.cts +38 -0
  11. package/dist/cjs/core/protocol.d.cts +23 -0
  12. package/dist/cjs/core/queue.d.cts +40 -0
  13. package/dist/cjs/core/readerPool.d.cts +40 -0
  14. package/dist/cjs/core/settleUtils.d.cts +36 -0
  15. package/dist/cjs/core/taskWorker.d.cts +50 -0
  16. package/dist/cjs/core/transactionScope.d.cts +83 -0
  17. package/dist/cjs/index.cjs +3939 -0
  18. package/dist/cjs/index.cjs.map +1 -0
  19. package/dist/cjs/index.d.cts +28 -0
  20. package/dist/cjs/stream/stream.d.cts +43 -0
  21. package/dist/cjs/transaction/transaction.d.cts +32 -0
  22. package/dist/cjs/utils/escape.d.cts +7 -0
  23. package/dist/cjs/utils/interpolate.d.cts +8 -0
  24. package/dist/cjs/utils/normalize.d.cts +7 -0
  25. package/dist/cjs/utils/timeout.d.cts +11 -0
  26. package/dist/cjs/utils/token.d.cts +7 -0
  27. package/dist/cjs/which.d.cts +8 -0
  28. package/dist/esm/constants.d.mts +2 -0
  29. package/dist/esm/core/classifier.d.mts +13 -0
  30. package/dist/esm/core/executor.d.mts +94 -0
  31. package/dist/esm/core/lruCache.d.mts +16 -0
  32. package/dist/esm/core/metrics.d.mts +84 -0
  33. package/dist/esm/core/parser.d.mts +55 -0
  34. package/dist/esm/core/pipelineEngine.d.mts +91 -0
  35. package/dist/esm/core/process.d.mts +38 -0
  36. package/dist/esm/core/protocol.d.mts +23 -0
  37. package/dist/esm/core/queue.d.mts +40 -0
  38. package/dist/esm/core/readerPool.d.mts +40 -0
  39. package/dist/esm/core/settleUtils.d.mts +36 -0
  40. package/dist/esm/core/taskWorker.d.mts +50 -0
  41. package/dist/esm/core/transactionScope.d.mts +83 -0
  42. package/dist/esm/index.d.mts +28 -0
  43. package/dist/esm/index.mjs +3865 -0
  44. package/dist/esm/index.mjs.map +1 -0
  45. package/dist/esm/stream/stream.d.mts +43 -0
  46. package/dist/esm/transaction/transaction.d.mts +32 -0
  47. package/dist/esm/utils/escape.d.mts +7 -0
  48. package/dist/esm/utils/interpolate.d.mts +8 -0
  49. package/dist/esm/utils/normalize.d.mts +7 -0
  50. package/dist/esm/utils/timeout.d.mts +11 -0
  51. package/dist/esm/utils/token.d.mts +7 -0
  52. package/dist/esm/which.d.mts +8 -0
  53. 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
+ [![Badge](https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg?style=flat-square)](https://996.icu/#/en_US)
4
+ [![LICENSE](https://img.shields.io/badge/license-Anti%20996-blue.svg?style=flat-square)](https://github.com/996icu/996.ICU/blob/master/LICENSE)
5
+ ![Node](https://img.shields.io/badge/node-%3E=18-blue.svg?style=flat-square)
6
+ [![npm version](https://badge.fury.io/js/sqlite-executor.svg)](https://badge.fury.io/js/sqlite-executor)
7
+ ![CI](https://github.com/axetroy/sqlite-wrapper.js/actions/workflows/build.yml/badge.svg)
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,2 @@
1
+ /** 标记列名,用于在查询结果末尾标识语句结束 */
2
+ export const TOKEN_COLUMN: "__sqlite_executor_token__";
@@ -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;