@procedures/sqlite 0.4.0 → 0.5.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.
@@ -0,0 +1,68 @@
1
+ /**
2
+ * The two SQLite engines of `SqliteStorage`: `node:sqlite` and sql.js.
3
+ *
4
+ * - The engine `node` is the module `node:sqlite` of Node.js. It writes only the changed pages of
5
+ * the file, and SQLite locks the file for each write.
6
+ * - The engine `sqljs` is sql.js (SQLite in WebAssembly), through `@mark1russell7/docker-sqlite`.
7
+ * It keeps the database in memory and writes the whole file after a write.
8
+ * - The two engines read and write the same file format.
9
+ *
10
+ * This module imports `node:sqlite` only when a storage opens: an import of the package does not
11
+ * load it.
12
+ */
13
+ /** The path of a database that is only in memory. */
14
+ export declare const MEMORY_PATH = ":memory:";
15
+ /** The engine of a database: `node:sqlite` (`node`) or sql.js (`sqljs`). */
16
+ export type SqliteEngineName = "node" | "sqljs";
17
+ /**
18
+ * The engine choice of a `SqliteStorage`. With `auto`, the storage uses `node` when Node.js has
19
+ * `node:sqlite`, and `sqljs` when it does not.
20
+ */
21
+ export type SqliteEngine = "auto" | SqliteEngineName;
22
+ /** This function gives the engine choice when it is known. Else it throws a `TypeError`. */
23
+ export declare function checkEngine(engine: unknown): SqliteEngine;
24
+ /** A value that a statement takes or gives. */
25
+ export type SqlValue = string | number | null;
26
+ /** The calls of an open database that a storage uses. Each call is synchronous. */
27
+ export interface EngineDatabase {
28
+ /** The rows of a query, as objects. */
29
+ all<R>(sql: string, params?: SqlValue[]): R[];
30
+ /** The first row of a statement for each list of parameters, or undefined for no row. */
31
+ firstOfEach<R>(sql: string, params: SqlValue[][]): Array<R | undefined>;
32
+ /** This method runs one statement, and gives the number of rows that it changed. */
33
+ run(sql: string, params?: SqlValue[]): number;
34
+ /** This method runs SQL text that can have several statements. */
35
+ exec(sql: string): void;
36
+ close(): void;
37
+ }
38
+ /**
39
+ * This function gives true when this Node.js has `node:sqlite` without a flag (Node.js 22.13 or
40
+ * later). Then the engine `auto` uses it.
41
+ */
42
+ export declare function isNodeSqliteAvailable(): Promise<boolean>;
43
+ /**
44
+ * This function copies the schema of the storages from one database to another. The node engine
45
+ * calls it when it makes the file at the first write.
46
+ */
47
+ export type CopySchema = (from: EngineDatabase, to: EngineDatabase) => void;
48
+ /** An open database of a path, with the file work of its engine. */
49
+ export interface OpenDatabase {
50
+ readonly engine: SqliteEngineName;
51
+ /** The current database. The node engine changes it when it opens the file. */
52
+ readonly db: EngineDatabase;
53
+ /**
54
+ * True when the node engine waits for the first write to make the file. Until then, the
55
+ * database is in memory, and it has the tables and no item.
56
+ */
57
+ readonly waiting: boolean;
58
+ /** This method opens the file and copies the schema to it. The node engine uses it before the first write. */
59
+ makeFile(copy: CopySchema): void;
60
+ /** This method opens a file that another process made after the open, before a read. */
61
+ refresh(copy: CopySchema): void;
62
+ /** This method writes the database to the file. Only sql.js has a write to do. */
63
+ saveFile(): Promise<void>;
64
+ close(): void;
65
+ }
66
+ /** This function opens the database of a path with an engine. `auto` uses `node` when it can. */
67
+ export declare function openEngine(path: string, engine: SqliteEngine, busyTimeoutMs: number): Promise<OpenDatabase>;
68
+ //# sourceMappingURL=engines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engines.d.ts","sourceRoot":"","sources":["../src/engines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,qDAAqD;AACrD,eAAO,MAAM,WAAW,aAAa,CAAC;AAEtC,4EAA4E;AAC5E,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,gBAAgB,CAAC;AAIrD,4FAA4F;AAC5F,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY,CAKzD;AAED,+CAA+C;AAC/C,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAE9C,mFAAmF;AACnF,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;IAC9C,yFAAyF;IACzF,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IACxE,oFAAoF;IACpF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAC9C,kEAAkE;IAClE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACf;AAyCD;;;GAGG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAE9D;AAyHD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,KAAK,IAAI,CAAC;AAE5E,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,8GAA8G;IAC9G,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACjC,wFAAwF;IACxF,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,kFAAkF;IAClF,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf;AAyGD,iGAAiG;AACjG,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CASjH"}
@@ -0,0 +1,268 @@
1
+ /**
2
+ * The two SQLite engines of `SqliteStorage`: `node:sqlite` and sql.js.
3
+ *
4
+ * - The engine `node` is the module `node:sqlite` of Node.js. It writes only the changed pages of
5
+ * the file, and SQLite locks the file for each write.
6
+ * - The engine `sqljs` is sql.js (SQLite in WebAssembly), through `@mark1russell7/docker-sqlite`.
7
+ * It keeps the database in memory and writes the whole file after a write.
8
+ * - The two engines read and write the same file format.
9
+ *
10
+ * This module imports `node:sqlite` only when a storage opens: an import of the package does not
11
+ * load it.
12
+ */
13
+ import { existsSync, mkdirSync, statSync } from "node:fs";
14
+ import { dirname } from "node:path";
15
+ import { createConnection } from "@mark1russell7/docker-sqlite";
16
+ /** The path of a database that is only in memory. */
17
+ export const MEMORY_PATH = ":memory:";
18
+ const ENGINES = new Set(["auto", "node", "sqljs"]);
19
+ /** This function gives the engine choice when it is known. Else it throws a `TypeError`. */
20
+ export function checkEngine(engine) {
21
+ if (typeof engine !== "string" || !ENGINES.has(engine)) {
22
+ throw new TypeError(`Unknown SQLite engine ${JSON.stringify(engine)}: use auto, node or sqljs`);
23
+ }
24
+ return engine;
25
+ }
26
+ let nodeModule;
27
+ /**
28
+ * This function loads `node:sqlite` one time. The promise gives undefined when the import fails,
29
+ * or when the module has no database class. Node.js before 22.13 has the module only with the
30
+ * flag `--experimental-sqlite`.
31
+ */
32
+ function loadNodeSqlite() {
33
+ nodeModule ??= import("node:sqlite")
34
+ .then((module) => {
35
+ const exports = module;
36
+ const found = "Database" in exports ? exports.Database : exports.DatabaseSync;
37
+ return typeof found === "function" ? found : undefined;
38
+ })
39
+ .catch(() => undefined);
40
+ return nodeModule;
41
+ }
42
+ /**
43
+ * This function gives true when this Node.js has `node:sqlite` without a flag (Node.js 22.13 or
44
+ * later). Then the engine `auto` uses it.
45
+ */
46
+ export async function isNodeSqliteAvailable() {
47
+ return (await loadNodeSqlite()) !== undefined;
48
+ }
49
+ /** A database of `node:sqlite`. It keeps the prepared statements of the storage. */
50
+ class NodeDatabase {
51
+ handle;
52
+ statements = new Map();
53
+ constructor(handle) {
54
+ this.handle = handle;
55
+ }
56
+ all(sql, params = []) {
57
+ return this.statement(sql).all(...params);
58
+ }
59
+ firstOfEach(sql, params) {
60
+ const statement = this.statement(sql);
61
+ return params.map((list) => statement.get(...list));
62
+ }
63
+ run(sql, params = []) {
64
+ return Number(this.statement(sql).run(...params).changes);
65
+ }
66
+ exec(sql) {
67
+ this.handle.exec(sql);
68
+ }
69
+ close() {
70
+ this.statements.clear();
71
+ this.handle.close();
72
+ }
73
+ statement(sql) {
74
+ let statement = this.statements.get(sql);
75
+ if (!statement) {
76
+ statement = this.handle.prepare(sql);
77
+ this.statements.set(sql, statement);
78
+ }
79
+ return statement;
80
+ }
81
+ }
82
+ /** The error code of SQLite for a write to a read-only database. */
83
+ const SQLITE_READONLY = 8;
84
+ /**
85
+ * This function opens a database file with `node:sqlite`, and makes the file when it is missing.
86
+ * The file gets WAL mode, so a read in another process does not wait for a write. The busy
87
+ * timeout makes a write wait for the lock of another process.
88
+ */
89
+ function openNodeFile(Database, path, busyTimeoutMs) {
90
+ const handle = new Database(path);
91
+ try {
92
+ handle.exec(`PRAGMA busy_timeout = ${Math.max(0, Math.floor(busyTimeoutMs))}`);
93
+ try {
94
+ handle.prepare("PRAGMA journal_mode = WAL").get();
95
+ }
96
+ catch (error) {
97
+ // A read-only file keeps its journal mode: the reads work, and a write gives the error. An
98
+ // error of an older Node.js can have no `errcode`: then its message tells it.
99
+ const { errcode, message } = error;
100
+ if (errcode !== SQLITE_READONLY && !/readonly database/i.test(String(message)))
101
+ throw error;
102
+ }
103
+ // In WAL mode, NORMAL keeps the file consistent after a crash, with fewer disk syncs
104
+ handle.exec("PRAGMA synchronous = NORMAL");
105
+ }
106
+ catch (error) {
107
+ handle.close();
108
+ throw error;
109
+ }
110
+ return new NodeDatabase(handle);
111
+ }
112
+ // ---------------------------------------------------------------------------
113
+ // sql.js
114
+ // ---------------------------------------------------------------------------
115
+ /** A database of sql.js. */
116
+ class SqlJsDatabase {
117
+ raw;
118
+ constructor(raw) {
119
+ this.raw = raw;
120
+ }
121
+ all(sql, params = []) {
122
+ const statement = this.raw.prepare(sql);
123
+ try {
124
+ statement.bind(params);
125
+ const out = [];
126
+ while (statement.step())
127
+ out.push(statement.getAsObject());
128
+ return out;
129
+ }
130
+ finally {
131
+ statement.free();
132
+ }
133
+ }
134
+ firstOfEach(sql, params) {
135
+ const statement = this.raw.prepare(sql);
136
+ try {
137
+ return params.map((list) => {
138
+ statement.bind(list);
139
+ const row = statement.step() ? statement.getAsObject() : undefined;
140
+ statement.reset();
141
+ return row;
142
+ });
143
+ }
144
+ finally {
145
+ statement.free();
146
+ }
147
+ }
148
+ run(sql, params = []) {
149
+ this.raw.run(sql, params);
150
+ return this.raw.getRowsModified();
151
+ }
152
+ exec(sql) {
153
+ this.raw.exec(sql);
154
+ }
155
+ close() {
156
+ this.raw.close();
157
+ }
158
+ }
159
+ /**
160
+ * A database of `node:sqlite`. A missing file stays missing until the first write that changes
161
+ * an item: until then, the database is in memory.
162
+ */
163
+ class NodeOpenDatabase {
164
+ Database;
165
+ path;
166
+ busyTimeoutMs;
167
+ engine = "node";
168
+ db;
169
+ waiting;
170
+ constructor(Database, path, busyTimeoutMs) {
171
+ this.Database = Database;
172
+ this.path = path;
173
+ this.busyTimeoutMs = busyTimeoutMs;
174
+ if (path === MEMORY_PATH) {
175
+ this.db = new NodeDatabase(new Database(MEMORY_PATH));
176
+ this.waiting = false;
177
+ }
178
+ else if (existsSync(path)) {
179
+ this.db = openNodeFile(Database, path, busyTimeoutMs);
180
+ this.waiting = false;
181
+ }
182
+ else {
183
+ this.db = new NodeDatabase(new Database(MEMORY_PATH));
184
+ this.waiting = true;
185
+ }
186
+ }
187
+ makeFile(copy) {
188
+ if (!this.waiting)
189
+ return;
190
+ mkdirSync(dirname(this.path), { recursive: true });
191
+ const file = openNodeFile(this.Database, this.path, this.busyTimeoutMs);
192
+ try {
193
+ copy(this.db, file);
194
+ }
195
+ catch (error) {
196
+ file.close();
197
+ throw error;
198
+ }
199
+ this.db.close();
200
+ this.db = file;
201
+ this.waiting = false;
202
+ }
203
+ refresh(copy) {
204
+ if (this.waiting && existsSync(this.path))
205
+ this.makeFile(copy);
206
+ }
207
+ saveFile() {
208
+ return Promise.resolve();
209
+ }
210
+ close() {
211
+ this.db.close();
212
+ }
213
+ }
214
+ /** A database of sql.js: the database is in memory, and `saveFile()` writes the whole file. */
215
+ class SqlJsOpenDatabase {
216
+ db;
217
+ save;
218
+ engine = "sqljs";
219
+ waiting = false;
220
+ constructor(db, save) {
221
+ this.db = db;
222
+ this.save = save;
223
+ }
224
+ makeFile() { }
225
+ refresh() { }
226
+ saveFile() {
227
+ return this.save();
228
+ }
229
+ close() {
230
+ this.db.close();
231
+ }
232
+ }
233
+ /**
234
+ * sql.js reads only the main file. A write-ahead log of the node engine (`<file>-wal`) can hold
235
+ * changes that are not in the main file yet. A whole-file write of sql.js does not agree with the
236
+ * log. Thus sql.js refuses such a file.
237
+ */
238
+ function checkNoWriteAheadLog(path) {
239
+ let size = 0;
240
+ try {
241
+ size = statSync(`${path}-wal`).size;
242
+ }
243
+ catch {
244
+ return;
245
+ }
246
+ if (size > 0) {
247
+ throw new Error(`The file ${path} has a write-ahead log (${path}-wal) of the engine node: open it with the engine node, or close the process that uses it`);
248
+ }
249
+ }
250
+ /** The error of the engine `node` when this Node.js has no `node:sqlite`. */
251
+ function noNodeSqlite() {
252
+ return new Error(`The SQLite engine node needs node:sqlite, and this Node.js (${process.version}) does not have it without a flag: use Node.js 22.13 or later, or the engine sqljs or auto`);
253
+ }
254
+ /** This function opens the database of a path with an engine. `auto` uses `node` when it can. */
255
+ export async function openEngine(path, engine, busyTimeoutMs) {
256
+ if (engine !== "sqljs") {
257
+ const Database = await loadNodeSqlite();
258
+ if (Database)
259
+ return new NodeOpenDatabase(Database, path, busyTimeoutMs);
260
+ if (engine === "node")
261
+ throw noNodeSqlite();
262
+ }
263
+ if (path !== MEMORY_PATH)
264
+ checkNoWriteAheadLog(path);
265
+ const { db, save } = await createConnection({ dbPath: path });
266
+ return new SqlJsOpenDatabase(new SqlJsDatabase(db), save);
267
+ }
268
+ //# sourceMappingURL=engines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engines.js","sourceRoot":"","sources":["../src/engines.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -37,7 +37,7 @@ export type { DbQueryInput, DbQueryOutput, DbExecuteInput, DbExecuteOutput, Logs
37
37
  export { DEFAULT_DB_PATH, LOG_LEVELS } from "./types.js";
38
38
  export { dbTables, dbSchema, dbTransaction, dbMigrate, dbBackup } from "./procedures/db/index.js";
39
39
  export { registerSqliteProcedures } from "./module.js";
40
- export { SqliteStorage, checkTableName, MEMORY_PATH, type SqliteStorageOptions } from "./storage.js";
40
+ export { SqliteStorage, checkTableName, isNodeSqliteAvailable, MEMORY_PATH, type SqliteEngine, type SqliteEngineName, type SqliteStorageOptions, } from "./storage.js";
41
41
  export { withConnection, createConnection, query, execute, execMultiple, lastInsertRowId, tableExists, getMigrationStatus, runMigrations, rollbackMigration, createMigration, } from "@mark1russell7/docker-sqlite";
42
42
  export type { ConnectionConfig, ConnectionCallback, QueryResult, ExecuteResult, Migration, MigrationStatus, Database, } from "@mark1russell7/docker-sqlite";
43
43
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAMH,YAAY,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGzD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAMlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAMvD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAMrG,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,KAAK,EACL,OAAO,EACP,YAAY,EACZ,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,eAAe,GAChB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,SAAS,EACT,eAAe,EACf,QAAQ,GACT,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAMH,YAAY,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,EACb,cAAc,EACd,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGzD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAMlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAMvD,OAAO,EACL,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC;AAMtB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,KAAK,EACL,OAAO,EACP,YAAY,EACZ,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,eAAe,GAChB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,SAAS,EACT,eAAe,EACf,QAAQ,GACT,MAAM,8BAA8B,CAAC"}
package/dist/index.js CHANGED
@@ -43,7 +43,7 @@ export { registerSqliteProcedures } from "./module.js";
43
43
  // =============================================================================
44
44
  // The collection storage (roadmap R45). The entry @procedures/sqlite/storage has it alone.
45
45
  // =============================================================================
46
- export { SqliteStorage, checkTableName, MEMORY_PATH } from "./storage.js";
46
+ export { SqliteStorage, checkTableName, isNodeSqliteAvailable, MEMORY_PATH, } from "./storage.js";
47
47
  // =============================================================================
48
48
  // Re-export docker-sqlite utilities for direct use
49
49
  // =============================================================================
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAoCH,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEzD,yDAAyD;AACzD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAElG,gFAAgF;AAChF,eAAe;AACf,gFAAgF;AAEhF,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,gFAAgF;AAChF,2FAA2F;AAC3F,gFAAgF;AAEhF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAA6B,MAAM,cAAc,CAAC;AAErG,gFAAgF;AAChF,mDAAmD;AACnD,gFAAgF;AAEhF,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,KAAK,EACL,OAAO,EACP,YAAY,EACZ,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,eAAe,GAChB,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAoCH,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEzD,yDAAyD;AACzD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAElG,gFAAgF;AAChF,eAAe;AACf,gFAAgF;AAEhF,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAEvD,gFAAgF;AAChF,2FAA2F;AAC3F,gFAAgF;AAEhF,OAAO,EACL,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,WAAW,GAIZ,MAAM,cAAc,CAAC;AAEtB,gFAAgF;AAChF,mDAAmD;AACnD,gFAAgF;AAEhF,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,KAAK,EACL,OAAO,EACP,YAAY,EACZ,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,eAAe,GAChB,MAAM,8BAA8B,CAAC"}
package/dist/storage.d.ts CHANGED
@@ -3,28 +3,31 @@
3
3
  *
4
4
  * `SqliteStorage` keeps the items of one collection in one table of a SQLite database: a file,
5
5
  * or `:memory:`. It implements `CollectionStorage` of `@procedures/client`, so a
6
- * `ProcedureServer`, an `ApiStorage` server and a `HybridStorage` can use it. The engine is
7
- * sql.js (SQLite in WebAssembly), through `@mark1russell7/docker-sqlite`: no native build.
6
+ * `ProcedureServer`, an `ApiStorage` server and a `HybridStorage` can use it.
8
7
  *
8
+ * - The storage has two engines (the option `engine`). The engine `node` is `node:sqlite` of
9
+ * Node.js: it writes only the changed pages of the file. The engine `sqljs` is sql.js (SQLite in
10
+ * WebAssembly) through `@mark1russell7/docker-sqlite`: it keeps the database in memory and
11
+ * writes the whole file after a write. The default `auto` uses `node` when Node.js has it.
12
+ * - The two engines use the same file format: a file of one engine opens with the other.
9
13
  * - The table of a collection has the columns `id` (the key) and `value` (the JSON text of the
10
14
  * item). A value goes through `JSON.stringify` and `JSON.parse`.
11
15
  * - A change log gives `getChangesSince()`. The table `_storage_log` has the last change of each
12
16
  * id, and `_storage_versions` has the version of each collection: `<epoch>:<seq>`, as
13
17
  * `InMemoryStorage` has. The epoch stays in the file, so a version stays valid after a restart.
14
18
  * - Each write runs in a transaction. A batch that fails changes nothing.
15
- * - The storage keeps the database in memory and writes the file after each write. A write ends
16
- * after its file write. One file write can hold the changes of several writes.
17
- * - The storages of one file in one process share one database, so the storages of two tables in
18
- * one file do not write over the changes of each other.
19
+ * - The storages of one file in one process share one database. Thus the storages of two tables
20
+ * in one file keep the changes of each other.
21
+ * - A storage that only reads does not make the file.
19
22
  */
20
- import type { CollectionStorage, StorageChanges, StorageMetadata } from "@procedures/client";
21
- /** The path of a database that is only in memory. */
22
- export declare const MEMORY_PATH = ":memory:";
23
+ import { type CollectionStorage, type Duration, type StorageChanges, type StorageMetadata } from "@procedures/client";
24
+ import { type SqliteEngine, type SqliteEngineName } from "./engines.js";
25
+ export { MEMORY_PATH, isNodeSqliteAvailable, type SqliteEngine, type SqliteEngineName } from "./engines.js";
23
26
  /** The options of a `SqliteStorage`. */
24
27
  export interface SqliteStorageOptions {
25
28
  /**
26
29
  * The database file, or `:memory:` for a database that lives as long as the storage. The
27
- * storage makes the file, and its folder, at the first write.
30
+ * storage makes the file, and its folder, at the first write that changes an item.
28
31
  */
29
32
  path: string;
30
33
  /**
@@ -38,6 +41,28 @@ export interface SqliteStorageOptions {
38
41
  * @default 10000
39
42
  */
40
43
  maxTombstones?: number;
44
+ /**
45
+ * The SQLite engine.
46
+ *
47
+ * - `node`: the module `node:sqlite` of Node.js 22.13 or later. It writes only the changes, and
48
+ * the file is in WAL mode. Two processes can use one file.
49
+ * - `sqljs`: sql.js, SQLite in WebAssembly. It keeps the database in memory, and it writes the
50
+ * whole file after a write.
51
+ * - `auto`: `node` when Node.js has `node:sqlite`, and else `sqljs`.
52
+ *
53
+ * The storages of one file in one process share one database, and thus one engine. The first
54
+ * storage of the file sets it. A storage with another engine than `auto` refuses a database
55
+ * of the other engine.
56
+ * @default "auto"
57
+ */
58
+ engine?: SqliteEngine;
59
+ /**
60
+ * The time that a write of the engine `node` waits for the lock of another process, for example
61
+ * `seconds(5)`. After it, the write fails with the error `database is locked`. The first
62
+ * storage of a file sets it.
63
+ * @default 5 seconds
64
+ */
65
+ busyTimeout?: Duration;
41
66
  }
42
67
  /**
43
68
  * This function gives the name when it is a permitted table name. Else it throws a `TypeError`. The name goes
@@ -53,6 +78,7 @@ export declare function checkTableName(name: unknown): string;
53
78
  * await users.set("123", { id: "123", name: "John" });
54
79
  * const user = await users.get("123"); // { id: "123", name: "John" }
55
80
  * const changes = await users.getChangesSince(); // { version, full: true, changed, deleted: [] }
81
+ * await users.getEngine(); // "node" on Node.js 22.13 or later, else "sqljs"
56
82
  * await users.close();
57
83
  * ```
58
84
  */
@@ -61,6 +87,8 @@ export declare class SqliteStorage<T> implements CollectionStorage<T> {
61
87
  readonly path: string;
62
88
  /** The table of the items. */
63
89
  readonly table: string;
90
+ /** The engine choice of the options. `getEngine()` gives the engine that the storage uses. */
91
+ readonly engine: SqliteEngine;
64
92
  private readonly maxTombstones;
65
93
  /** The quoted table name, for the SQL text. */
66
94
  private readonly quoted;
@@ -71,10 +99,13 @@ export declare class SqliteStorage<T> implements CollectionStorage<T> {
71
99
  getAll(): Promise<T[]>;
72
100
  /** Every item with its id, in the order of the first write of each id. */
73
101
  getEntries(): Promise<Array<[string, T]>>;
102
+ /** The ids of the items, in the order of the entries. The storage does not read the values. */
103
+ getIds(): Promise<string[]>;
74
104
  /**
75
105
  * The changes after a version (roadmap R28). A version of another storage, of another database
76
106
  * file, or older than the dropped deletes gives all items (`full: true`). A version stays valid
77
- * after a restart, because the change log is in the file.
107
+ * after a restart, because the change log is in the file. The reads run in one read
108
+ * transaction, so a write of another process does not come between them.
78
109
  */
79
110
  getChangesSince(since?: string): Promise<StorageChanges<T>>;
80
111
  find(predicate: (item: T) => boolean): Promise<T[]>;
@@ -88,30 +119,40 @@ export declare class SqliteStorage<T> implements CollectionStorage<T> {
88
119
  /** This method deletes several items in one transaction. */
89
120
  deleteBatch(ids: string[]): Promise<number>;
90
121
  getBatch(ids: string[]): Promise<Map<string, T>>;
122
+ /** The engine that the storage uses: `node` or `sqljs`. With the option `auto`, the open decides it. */
123
+ getEngine(): Promise<SqliteEngineName>;
91
124
  /**
92
125
  * This method writes the database file. Each write ends after its file write already, so a
93
- * caller needs it only after a failed file write.
126
+ * caller needs it only after a failed file write of the engine `sqljs`. The engine `node`
127
+ * writes each change at its commit.
94
128
  */
95
129
  flush(): Promise<void>;
96
130
  /**
97
131
  * This method writes the file and releases the database. The items stay in the file. A new
98
132
  * storage of the same file and table reads them, and the versions of this storage stay valid.
99
- * After `close()`, each operation throws.
133
+ * After `close()`, each operation rejects, and a second `close()` does nothing.
100
134
  */
101
135
  close(): Promise<void>;
102
136
  getMetadata(): Promise<StorageMetadata>;
103
137
  /** This method opens the database, and makes the tables of the collection and of the change log. */
104
138
  private open;
105
- /** The open database. It throws after `close()`. */
139
+ /** The open database. It throws after `close()`, so the promise of the operation rejects. */
106
140
  private database;
141
+ private sharedDatabase;
107
142
  private checkOpen;
108
143
  private entries;
109
144
  private counter;
110
145
  /**
111
- * One write: the change in a transaction with the change log, then the file write. `next` gives
112
- * the next number of the change log. A write that changes nothing writes no file.
146
+ * One write: the change in a transaction with the change log, then the file write of the engine
147
+ * `sqljs`. `next` gives the next number of the change log. A write that changes nothing writes
148
+ * no file.
149
+ *
150
+ * Before the first write, the engine `node` keeps the database of a missing file in memory, with
151
+ * no item. A write first tests its change there. When it changes an item, the storage makes the
152
+ * file and runs the write in it.
113
153
  */
114
154
  private write;
155
+ private runWrite;
115
156
  /** This method writes an item. An existing id keeps its place in the order. */
116
157
  private put;
117
158
  /** This method deletes an item. True when it existed. */
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}