deepbase-sqlite 3.4.12 → 3.6.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 CHANGED
@@ -27,7 +27,8 @@ import SqliteDriver from 'deepbase-sqlite';
27
27
 
28
28
  const db = new DeepBase(new SqliteDriver({
29
29
  path: './data',
30
- name: 'mydb'
30
+ name: 'mydb',
31
+ pragma: 'balanced' // default — omit for same result
31
32
  }));
32
33
 
33
34
  await db.connect();
@@ -42,6 +43,7 @@ const alice = await db.get('users', 'alice');
42
43
  new SqliteDriver({
43
44
  path: './data', // Directory to store database files
44
45
  name: 'default', // Database filename (without .db)
46
+ pragma: 'balanced', // Performance profile: 'none' | 'safe' | 'balanced' | 'fast'
45
47
  nidAlphabet: 'ABC...', // Alphabet for ID generation
46
48
  nidLength: 10 // Length of generated IDs
47
49
  })
@@ -75,6 +77,8 @@ Efficiently stores nested objects using a key-value schema:
75
77
  - Values are stored as JSON
76
78
  - Fast lookups for both exact keys and partial paths
77
79
 
80
+ Each row also stores a monotonic `seq` so reads that rebuild objects use `ORDER BY seq, key`. That matches JavaScript insertion order for sibling keys and keeps `shift()` / `pop()` (via `DeepBase.keys()`) aligned with `JsonDriver`. Existing databases pick up `seq` via `ALTER TABLE` on connect (legacy rows default to `0`, then tie-break by `key`).
81
+
78
82
  ### ACID Compliance
79
83
 
80
84
  SQLite provides:
@@ -84,15 +88,56 @@ SQLite provides:
84
88
  - **Isolation**: Concurrent operations don't interfere
85
89
  - **Durability**: Committed data persists even after crashes
86
90
 
91
+ ## Pragma Modes
92
+
93
+ `SqliteDriver` ships with four configurable performance profiles via the `pragma` option:
94
+
95
+ | Mode | `synchronous` | `cache_size` | `mmap_size` | `WITHOUT ROWID` | Use case |
96
+ |------|--------------|-------------|-------------|-----------------|----------|
97
+ | **none** | — | — | — | No | Backward-compatible with databases created by older versions |
98
+ | **safe** | FULL | 2 MB | off | Yes | Durability first, WAL + full fsync |
99
+ | **balanced** *(default)* | NORMAL | 8 MB | 256 MB | Yes | Best mix of speed and safety for most apps |
100
+ | **fast** | OFF | 16 MB | 256 MB | Yes | Maximum throughput — data may be lost on OS crash |
101
+
102
+ All WAL modes use `journal_mode=WAL`, `temp_store=MEMORY`, and `busy_timeout=5000ms`.
103
+
104
+ ```javascript
105
+ // Backward-compatible (no PRAGMAs, no WITHOUT ROWID)
106
+ new SqliteDriver({ name: 'mydb', pragma: 'none' })
107
+
108
+ // Maximum durability
109
+ new SqliteDriver({ name: 'mydb', pragma: 'safe' })
110
+
111
+ // Recommended (default)
112
+ new SqliteDriver({ name: 'mydb', pragma: 'balanced' })
113
+
114
+ // Maximum throughput
115
+ new SqliteDriver({ name: 'mydb', pragma: 'fast' })
116
+ ```
117
+
118
+ `SqliteFastDriver` is kept as a named alias for backward compatibility:
119
+
120
+ ```javascript
121
+ import { SqliteFastDriver } from 'deepbase-sqlite';
122
+ // SqliteFastDriver === SqliteDriver (same class, same options)
123
+ ```
124
+
87
125
  ## Database Structure
88
126
 
89
127
  Data is stored in a simple key-value table:
90
128
 
91
129
  ```sql
130
+ -- pragma: 'none' (legacy-compatible)
92
131
  CREATE TABLE deepbase (
93
132
  key TEXT PRIMARY KEY,
94
133
  value TEXT NOT NULL
95
134
  )
135
+
136
+ -- pragma: 'safe' | 'balanced' | 'fast' (optimized)
137
+ CREATE TABLE deepbase (
138
+ key TEXT PRIMARY KEY,
139
+ value TEXT NOT NULL
140
+ ) WITHOUT ROWID
96
141
  ```
97
142
 
98
143
  Example data:
@@ -167,6 +212,27 @@ data/
167
212
  | Reliability | 💪 Very High | ⚠️ File corruption risk |
168
213
  | Debugging | 🔧 SQL tools | 👁️ Easy to inspect |
169
214
 
215
+ ## Benchmark — pragma modes
216
+
217
+ Median of 3 runs, 1 000 iterations per operation. `balanced` vs `none`:
218
+
219
+ ```
220
+ Operation none safe balanced fast Bal vs None
221
+ ─────────────────────────────────────────────────────────────────────────
222
+ Sequential Write 4,525 17,296 84,701 98,238 +1772%
223
+ Sequential Read 20,705 22,871 23,405 23,040 +13%
224
+ Update 2,689 10,666 17,764 18,857 +561%
225
+ Increment 4,291 14,129 25,734 26,364 +500%
226
+ Delete 3,806 12,010 20,884 21,074 +449%
227
+ Batch Write 3,813 17,763 87,209 83,045 +2187%
228
+ Concurrent Write 4,449 22,196 72,613 102,458 +1532%
229
+ Deep Write (5-lvl) 4,311 26,740 53,957 91,312 +1152%
230
+ Obj Expansion 1,997 365 34,633 47,318 +1634%
231
+ Session Lifecycle 572 2,465 3,700 3,792 +546%
232
+ ```
233
+
234
+ Disk usage is **29 % smaller** after compaction compared to `none`. All correctness checks pass on every mode.
235
+
170
236
  ## Best Practices
171
237
 
172
238
  ### Use Transactions for Bulk Operations
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepbase-sqlite",
3
- "version": "3.4.12",
3
+ "version": "3.6.0",
4
4
  "description": "⚡ DeepBase SQLite - SQLite database driver",
5
5
  "type": "module",
6
6
  "main": "src/index.cjs",
@@ -17,7 +17,7 @@
17
17
  "better-sqlite3": "^11.8.1"
18
18
  },
19
19
  "peerDependencies": {
20
- "deepbase": "^3.4.12"
20
+ "deepbase": "^3.6.0"
21
21
  },
22
22
  "scripts": {
23
23
  "test": "mocha test/test.js"
@@ -3,54 +3,135 @@ import Database from 'better-sqlite3';
3
3
  import fs from 'fs';
4
4
  import * as pathModule from 'path';
5
5
 
6
+ const PRAGMA = {
7
+ none: null,
8
+ safe: {
9
+ journal_mode: 'WAL',
10
+ synchronous: 'FULL',
11
+ temp_store: 'MEMORY',
12
+ cache_size: -2000,
13
+ busy_timeout: 5000,
14
+ mmap_size: 0,
15
+ },
16
+ balanced: {
17
+ journal_mode: 'WAL',
18
+ synchronous: 'NORMAL',
19
+ temp_store: 'MEMORY',
20
+ cache_size: -8000,
21
+ busy_timeout: 5000,
22
+ mmap_size: 268435456,
23
+ },
24
+ fast: {
25
+ journal_mode: 'WAL',
26
+ synchronous: 'OFF',
27
+ temp_store: 'MEMORY',
28
+ cache_size: -16000,
29
+ busy_timeout: 5000,
30
+ mmap_size: 268435456,
31
+ },
32
+ };
33
+
6
34
  export class SqliteDriver extends DeepBaseDriver {
7
35
  static _instances = {};
8
-
9
- constructor({name, path, ...opts} = {}) {
36
+
37
+ constructor({ name, path, pragma, ...opts } = {}) {
10
38
  super(opts);
11
-
12
- this.name = name || "default";
39
+
40
+ this.name = name || 'default';
13
41
  this.path = path || new URL('../../../db', import.meta.url).pathname;
14
-
42
+ this.pragma = pragma || 'balanced';
43
+
15
44
  this.path = pathModule.resolve(this.path);
16
45
  this.fileName = pathModule.join(this.path, `${this.name}.db`);
17
-
18
- // Singleton pattern per file
46
+
19
47
  if (SqliteDriver._instances[this.fileName]) {
20
48
  return SqliteDriver._instances[this.fileName];
21
49
  }
22
-
50
+
23
51
  this.db = null;
24
52
  SqliteDriver._instances[this.fileName] = this;
25
53
  }
26
-
27
- async connect() {
54
+
55
+ _connectSync() {
28
56
  if (this._connected) return;
29
-
57
+
30
58
  if (!fs.existsSync(this.path)) {
31
59
  fs.mkdirSync(this.path, { recursive: true });
32
60
  }
33
-
61
+
34
62
  this.db = new Database(this.fileName);
35
-
36
- // Create table if it doesn't exist
63
+
64
+ const cfg = PRAGMA[this.pragma];
65
+ if (cfg) {
66
+ this.db.pragma(`journal_mode = ${cfg.journal_mode}`);
67
+ this.db.pragma(`synchronous = ${cfg.synchronous}`);
68
+ this.db.pragma(`temp_store = ${cfg.temp_store}`);
69
+ this.db.pragma(`cache_size = ${cfg.cache_size}`);
70
+ this.db.pragma(`busy_timeout = ${cfg.busy_timeout}`);
71
+ this.db.pragma(`mmap_size = ${cfg.mmap_size}`);
72
+ }
73
+
74
+ const withoutRowid = cfg ? ' WITHOUT ROWID' : '';
37
75
  this.db.exec(`
38
76
  CREATE TABLE IF NOT EXISTS deepbase (
39
77
  key TEXT PRIMARY KEY,
40
- value TEXT NOT NULL
41
- )
78
+ value TEXT NOT NULL,
79
+ seq INTEGER NOT NULL DEFAULT 0
80
+ )${withoutRowid}
42
81
  `);
43
-
44
- // Prepare statements for better performance
82
+
83
+ const tableCols = this.db.prepare('PRAGMA table_info(deepbase)').all();
84
+ if (!tableCols.some((c) => c.name === 'seq')) {
85
+ this.db.exec('ALTER TABLE deepbase ADD COLUMN seq INTEGER NOT NULL DEFAULT 0');
86
+ }
87
+
45
88
  this.getStmt = this.db.prepare('SELECT value FROM deepbase WHERE key = ?');
46
- this.setStmt = this.db.prepare('INSERT OR REPLACE INTO deepbase (key, value) VALUES (?, ?)');
89
+ this.setStmt = this.db.prepare(`
90
+ INSERT INTO deepbase (key, value, seq)
91
+ VALUES (?, ?, (SELECT IFNULL(MAX(seq), 0) + 1 FROM deepbase))
92
+ ON CONFLICT(key) DO UPDATE SET value = excluded.value
93
+ `);
47
94
  this.delStmt = this.db.prepare('DELETE FROM deepbase WHERE key = ?');
48
- this.getAllStmt = this.db.prepare('SELECT key, value FROM deepbase');
49
- this.getKeysLikeStmt = this.db.prepare('SELECT key, value FROM deepbase WHERE key LIKE ? ESCAPE \'!\'');
50
-
95
+ this.getAllStmt = this.db.prepare('SELECT key, value FROM deepbase ORDER BY seq, key');
96
+ this.getKeysLikeStmt = this.db.prepare(
97
+ "SELECT key, value FROM deepbase WHERE key LIKE ? ESCAPE '!' ORDER BY seq, key",
98
+ );
99
+ this.delChildrenStmt = this.db.prepare("DELETE FROM deepbase WHERE key LIKE ? ESCAPE '!'");
100
+ this.hasChildrenStmt = this.db.prepare("SELECT 1 FROM deepbase WHERE key LIKE ? ESCAPE '!' LIMIT 1");
101
+
102
+ this._setTxn = this.db.transaction((key, jsonValue, keys) => {
103
+ this._expandParentObjects(keys);
104
+ this.setStmt.run(key, jsonValue);
105
+ });
106
+
107
+ this._delTxn = this.db.transaction((key, likePattern) => {
108
+ this.delStmt.run(key);
109
+ this.delChildrenStmt.run(likePattern);
110
+ });
111
+
112
+ this._updTxn = this.db.transaction((keys, func) => {
113
+ const currentValue = this._getSync(keys);
114
+ const newValue = func(currentValue);
115
+ const key = this._pathToKey(keys);
116
+ this._expandParentObjects(keys);
117
+ this.setStmt.run(key, JSON.stringify(newValue));
118
+ return keys;
119
+ });
120
+
121
+ this._setRootTxn = this.db.transaction((entries) => {
122
+ this.db.exec('DELETE FROM deepbase');
123
+ for (const [key, value] of entries) {
124
+ this.setStmt.run(key, JSON.stringify(value));
125
+ }
126
+ });
127
+
51
128
  this._connected = true;
52
129
  }
53
-
130
+
131
+ async connect() {
132
+ this._connectSync();
133
+ }
134
+
54
135
  async disconnect() {
55
136
  if (this.db) {
56
137
  this.db.close();
@@ -58,178 +139,124 @@ export class SqliteDriver extends DeepBaseDriver {
58
139
  }
59
140
  this._connected = false;
60
141
  }
61
-
142
+
62
143
  async get(...args) {
63
144
  return this._getSync(args);
64
145
  }
65
-
146
+
147
+ getSync(...args) {
148
+ this._connectSync();
149
+ return this._getSync(args);
150
+ }
151
+
66
152
  _getSync(args) {
67
153
  if (args.length === 0) {
68
- // Get root object
69
154
  return this._getRootObject();
70
155
  }
71
-
156
+
72
157
  const key = this._pathToKey(args);
73
158
  const row = this.getStmt.get(key);
74
-
75
- // Check if there are child keys (nested properties)
76
- const children = this.getKeysLikeStmt.all(this._likePrefix(key));
77
-
78
- // If there are children, build object from them
79
- if (children.length > 0) {
80
- return this._buildObjectFromChildren(key);
81
- }
82
-
83
- // If direct key exists and no children, return it
159
+ const likePattern = this._likePrefix(key);
160
+
84
161
  if (row) {
162
+ if (this.hasChildrenStmt.get(likePattern)) {
163
+ return this._buildObjectFromChildren(key, likePattern);
164
+ }
85
165
  return JSON.parse(row.value);
86
166
  }
87
-
88
- // Check if we need to look into a parent object
89
- // For example: if we're looking for 'users.abc.name' but only 'users.abc' exists as a JSON object
90
- const parentPath = this._findParentWithValue(args);
91
- if (parentPath) {
92
- const parentKey = this._pathToKey(parentPath);
93
- const parentRow = this.getStmt.get(parentKey);
94
- if (parentRow) {
95
- const parentValue = JSON.parse(parentRow.value);
96
- const relativePath = args.slice(parentPath.length);
97
- return this._getFromObject(parentValue, relativePath);
98
- }
167
+
168
+ if (this.hasChildrenStmt.get(likePattern)) {
169
+ return this._buildObjectFromChildren(key, likePattern);
99
170
  }
100
-
101
- return null;
171
+
172
+ return this._getFromParent(args);
102
173
  }
103
-
174
+
104
175
  async set(...args) {
105
176
  if (args.length === 0) {
106
177
  throw new Error('set() requires at least one argument');
107
178
  }
108
-
179
+
109
180
  if (args.length === 1) {
110
- // Setting root object
111
181
  await this._setRootObject(args[0]);
112
182
  return [];
113
183
  }
114
-
184
+
115
185
  return this._setSync(args);
116
186
  }
117
-
187
+
118
188
  _setSync(args) {
119
189
  const keys = args.slice(0, -1);
120
190
  const value = args[args.length - 1];
121
191
  const key = this._pathToKey(keys);
122
-
123
- // Use transaction to make expansion and set atomic
124
- const transaction = this.db.transaction(() => {
125
- // Check if any parent path exists as an object that needs to be expanded
126
- this._expandParentObjects(keys);
127
-
128
- this.setStmt.run(key, JSON.stringify(value));
129
- });
130
-
131
- transaction();
192
+ this._setTxn(key, JSON.stringify(value), keys);
132
193
  return keys;
133
194
  }
134
-
195
+
135
196
  async del(...keys) {
136
197
  if (keys.length === 0) {
137
- // Delete everything
138
198
  this.db.exec('DELETE FROM deepbase');
139
199
  return;
140
200
  }
141
-
201
+
142
202
  const key = this._pathToKey(keys);
143
-
144
- // Use transaction to make deletion atomic
145
- const transaction = this.db.transaction(() => {
146
- // Delete the key itself
147
- this.delStmt.run(key);
148
-
149
- // Delete all children
150
- this.db.prepare('DELETE FROM deepbase WHERE key LIKE ? ESCAPE \'!\'').run(this._likePrefix(key));
151
- });
152
-
153
- transaction();
203
+ this._delTxn(key, this._likePrefix(key));
154
204
  }
155
-
205
+
156
206
  async inc(...args) {
157
207
  const i = args.pop();
158
208
  return this.upd(...args, n => n + i);
159
209
  }
160
-
210
+
161
211
  async dec(...args) {
162
212
  const i = args.pop();
163
213
  return this.upd(...args, n => n - i);
164
214
  }
165
-
215
+
166
216
  async add(...keys) {
167
217
  const value = keys.pop();
168
218
  const id = this.nanoid();
169
219
  await this.set(...[...keys, id], value);
170
220
  return [...keys, id];
171
221
  }
172
-
222
+
173
223
  async upd(...args) {
174
224
  const func = args.pop();
175
225
  const keys = args;
176
-
177
- // Use transaction to make get+set atomic
178
- const transaction = this.db.transaction(() => {
179
- const currentValue = this._getSync(keys);
180
- const newValue = func(currentValue);
181
- this._setSync([...keys, newValue]);
182
- return keys;
183
- });
184
-
185
- return transaction();
226
+ return this._updTxn(keys, func);
186
227
  }
187
-
228
+
188
229
  _getRootObject() {
189
230
  const rows = this.getAllStmt.all();
190
231
  const result = {};
191
-
192
232
  for (const row of rows) {
193
233
  const path = this._keyToPath(row.key);
194
234
  const value = JSON.parse(row.value);
195
235
  this._setNestedValue(result, path, value);
196
236
  }
197
-
198
237
  return result;
199
238
  }
200
-
239
+
201
240
  async _setRootObject(obj) {
202
- // Clear existing data
203
- this.db.exec('DELETE FROM deepbase');
204
-
205
- // Flatten and insert
206
241
  const entries = this._flattenObject(obj);
207
- const insertMany = this.db.transaction((entries) => {
208
- for (const [key, value] of entries) {
209
- this.setStmt.run(key, JSON.stringify(value));
210
- }
211
- });
212
-
213
- insertMany(entries);
242
+ this._setRootTxn(entries);
214
243
  }
215
-
216
- _buildObjectFromChildren(parentKey) {
217
- const rows = this.getKeysLikeStmt.all(parentKey ? this._likePrefix(parentKey) : '%');
244
+
245
+ _buildObjectFromChildren(parentKey, likePattern) {
246
+ const rows = this.getKeysLikeStmt.all(likePattern || (parentKey ? this._likePrefix(parentKey) : '%'));
218
247
  const result = {};
219
-
248
+ const parentPathLen = parentKey ? this._keyToPath(parentKey).length : 0;
249
+
220
250
  for (const row of rows) {
221
251
  const fullPath = this._keyToPath(row.key);
222
- const relativePath = parentKey
223
- ? fullPath.slice(this._keyToPath(parentKey).length)
224
- : fullPath;
225
-
252
+ const relativePath = fullPath.slice(parentPathLen);
226
253
  const value = JSON.parse(row.value);
227
254
  this._setNestedValue(result, relativePath, value);
228
255
  }
229
-
256
+
230
257
  return result;
231
258
  }
232
-
259
+
233
260
  _escapeLikePattern(str) {
234
261
  return str.replace(/[!%_]/g, '!$&');
235
262
  }
@@ -240,85 +267,76 @@ export class SqliteDriver extends DeepBaseDriver {
240
267
 
241
268
  _setNestedValue(obj, path, value) {
242
269
  if (path.length === 0) return;
243
-
270
+
244
271
  if (path.length === 1) {
245
272
  obj[path[0]] = value;
246
273
  return;
247
274
  }
248
-
275
+
249
276
  const key = path[0];
250
- if (!obj.hasOwnProperty(key) || typeof obj[key] !== "object") {
277
+ if (!obj.hasOwnProperty(key) || typeof obj[key] !== 'object') {
251
278
  obj[key] = {};
252
279
  }
253
-
280
+
254
281
  this._setNestedValue(obj[key], path.slice(1), value);
255
282
  }
256
-
283
+
257
284
  _flattenObject(obj, prefix = '') {
258
285
  const entries = [];
259
-
286
+
260
287
  for (const [key, value] of Object.entries(obj)) {
261
288
  const escapedKey = this._escapeDots(String(key));
262
289
  const fullKey = prefix ? `${prefix}.${escapedKey}` : escapedKey;
263
-
290
+
264
291
  if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
265
292
  entries.push(...this._flattenObject(value, fullKey));
266
293
  } else {
267
294
  entries.push([fullKey, value]);
268
295
  }
269
296
  }
270
-
297
+
271
298
  return entries;
272
299
  }
273
-
274
- _findParentWithValue(path) {
275
- // Try to find a parent path that has a stored value
276
- // For example: if looking for ['users', 'abc', 'name']
277
- // and 'users.abc' exists as a stored JSON object, return ['users', 'abc']
300
+
301
+ _getFromParent(path) {
278
302
  for (let i = path.length - 1; i > 0; i--) {
279
303
  const parentPath = path.slice(0, i);
280
304
  const parentKey = this._pathToKey(parentPath);
281
305
  const row = this.getStmt.get(parentKey);
282
306
  if (row) {
283
- const value = JSON.parse(row.value);
284
- // Only return if it's an object (not a primitive)
285
- if (value !== null && typeof value === 'object') {
286
- return parentPath;
307
+ const parentValue = JSON.parse(row.value);
308
+ if (parentValue !== null && typeof parentValue === 'object') {
309
+ return this._getFromObject(parentValue, path.slice(i));
287
310
  }
288
311
  }
289
312
  }
290
313
  return null;
291
314
  }
292
-
315
+
293
316
  _getFromObject(obj, path) {
294
317
  if (path.length === 0) return obj;
295
318
  if (path.length === 1) {
296
319
  return obj === null || obj[path[0]] === undefined ? null : obj[path[0]];
297
320
  }
298
-
321
+
299
322
  const key = path[0];
300
323
  if (!obj.hasOwnProperty(key)) return null;
301
-
324
+
302
325
  return this._getFromObject(obj[key], path.slice(1));
303
326
  }
304
-
327
+
305
328
  _expandParentObjects(path) {
306
- // Check each parent level (not including the path itself) to see if it exists as an object that needs expanding
307
- // For example, if path is ['config', 'theme'], check if 'config' exists as an object
308
329
  for (let i = 1; i < path.length; i++) {
309
330
  const parentPath = path.slice(0, i);
310
331
  const parentKey = this._pathToKey(parentPath);
311
332
  const parentRow = this.getStmt.get(parentKey);
312
-
333
+
313
334
  if (parentRow) {
314
335
  const parentValue = JSON.parse(parentRow.value);
315
-
316
- // If it's an object (not array or primitive), expand it
336
+
317
337
  if (parentValue !== null && typeof parentValue === 'object' && !Array.isArray(parentValue)) {
318
- // Delete the parent key
319
338
  this.delStmt.run(parentKey);
320
-
321
- // Insert all properties as individual keys
339
+
322
340
  const entries = this._flattenObject(parentValue, parentKey);
323
341
  for (const [key, value] of entries) {
324
342
  this.setStmt.run(key, JSON.stringify(value));
@@ -330,5 +348,3 @@ export class SqliteDriver extends DeepBaseDriver {
330
348
  }
331
349
 
332
350
  export default SqliteDriver;
333
-
334
-
package/src/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import { DeepBaseDriver, DeepBaseDriverOptions } from 'deepbase';
3
3
  export interface SqliteDriverOptions extends DeepBaseDriverOptions {
4
4
  name?: string;
5
5
  path?: string;
6
+ pragma?: 'none' | 'safe' | 'balanced' | 'fast';
6
7
  }
7
8
 
8
9
  export class SqliteDriver extends DeepBaseDriver {
@@ -11,6 +12,8 @@ export class SqliteDriver extends DeepBaseDriver {
11
12
  name: string;
12
13
  path: string;
13
14
  fileName: string;
15
+ pragma: string;
14
16
  }
15
17
 
18
+ export { SqliteDriver as SqliteFastDriver };
16
19
  export default SqliteDriver;
package/src/index.js CHANGED
@@ -1,4 +1,3 @@
1
1
  export { SqliteDriver } from './SqliteDriver.js';
2
+ export { SqliteDriver as SqliteFastDriver } from './SqliteDriver.js';
2
3
  export { SqliteDriver as default } from './SqliteDriver.js';
3
-
4
-