@livestore/wa-sqlite 1.0.1-dev.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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -0
  3. package/dist/wa-sqlite-async.mjs +16 -0
  4. package/dist/wa-sqlite-async.wasm +0 -0
  5. package/dist/wa-sqlite-jspi.mjs +16 -0
  6. package/dist/wa-sqlite-jspi.wasm +0 -0
  7. package/dist/wa-sqlite.mjs +16 -0
  8. package/dist/wa-sqlite.wasm +0 -0
  9. package/package.json +45 -0
  10. package/src/FacadeVFS.js +508 -0
  11. package/src/VFS.js +222 -0
  12. package/src/WebLocksMixin.js +412 -0
  13. package/src/examples/AccessHandlePoolVFS.js +458 -0
  14. package/src/examples/IDBBatchAtomicVFS.js +820 -0
  15. package/src/examples/IDBMirrorVFS.js +875 -0
  16. package/src/examples/MemoryAsyncVFS.js +100 -0
  17. package/src/examples/MemoryVFS.js +176 -0
  18. package/src/examples/OPFSAdaptiveVFS.js +437 -0
  19. package/src/examples/OPFSAnyContextVFS.js +300 -0
  20. package/src/examples/OPFSCoopSyncVFS.js +590 -0
  21. package/src/examples/OPFSPermutedVFS.js +1214 -0
  22. package/src/examples/README.md +89 -0
  23. package/src/examples/tag.js +82 -0
  24. package/src/sqlite-api.js +914 -0
  25. package/src/sqlite-constants.js +275 -0
  26. package/src/types/globals.d.ts +60 -0
  27. package/src/types/index.d.ts +1302 -0
  28. package/src/types/tsconfig.json +6 -0
  29. package/test/AccessHandlePoolVFS.test.js +27 -0
  30. package/test/IDBBatchAtomicVFS.test.js +97 -0
  31. package/test/IDBMirrorVFS.test.js +27 -0
  32. package/test/MemoryAsyncVFS.test.js +27 -0
  33. package/test/MemoryVFS.test.js +27 -0
  34. package/test/OPFSAdaptiveVFS.test.js +27 -0
  35. package/test/OPFSAnyContextVFS.test.js +27 -0
  36. package/test/OPFSCoopSyncVFS.test.js +27 -0
  37. package/test/OPFSPermutedVFS.test.js +27 -0
  38. package/test/TestContext.js +96 -0
  39. package/test/WebLocksMixin.test.js +521 -0
  40. package/test/api.test.js +49 -0
  41. package/test/api_exec.js +89 -0
  42. package/test/api_misc.js +63 -0
  43. package/test/api_statements.js +426 -0
  44. package/test/callbacks.test.js +373 -0
  45. package/test/sql.test.js +64 -0
  46. package/test/sql_0001.js +49 -0
  47. package/test/sql_0002.js +52 -0
  48. package/test/sql_0003.js +83 -0
  49. package/test/sql_0004.js +81 -0
  50. package/test/sql_0005.js +76 -0
  51. package/test/test-worker.js +204 -0
  52. package/test/vfs_xAccess.js +2 -0
  53. package/test/vfs_xClose.js +52 -0
  54. package/test/vfs_xOpen.js +91 -0
  55. package/test/vfs_xRead.js +38 -0
  56. package/test/vfs_xWrite.js +36 -0
@@ -0,0 +1,508 @@
1
+ // Copyright 2024 Roy T. Hashimoto. All Rights Reserved.
2
+ import * as VFS from './VFS.js';
3
+
4
+ const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
5
+
6
+ // Convenience base class for a JavaScript VFS.
7
+ // The raw xOpen, xRead, etc. function signatures receive only C primitives
8
+ // which aren't easy to work with. This class provides corresponding calls
9
+ // like jOpen, jRead, etc., which receive JavaScript-friendlier arguments
10
+ // such as string, Uint8Array, and DataView.
11
+ export class FacadeVFS extends VFS.Base {
12
+ /**
13
+ * @param {string} name
14
+ * @param {object} module
15
+ */
16
+ constructor(name, module) {
17
+ super(name, module);
18
+ }
19
+
20
+ /**
21
+ * Override to indicate which methods are asynchronous.
22
+ * @param {string} methodName
23
+ * @returns {boolean}
24
+ */
25
+ hasAsyncMethod(methodName) {
26
+ // The input argument is a string like "xOpen", so convert to "jOpen".
27
+ // Then check if the method exists and is async.
28
+ const jMethodName = `j${methodName.slice(1)}`;
29
+ return this[jMethodName] instanceof AsyncFunction;
30
+ }
31
+
32
+ /**
33
+ * Return the filename for a file id for use by mixins.
34
+ * @param {number} pFile
35
+ * @returns {string}
36
+ */
37
+ getFilename(pFile) {
38
+ throw new Error('unimplemented');
39
+ }
40
+
41
+ /**
42
+ * @param {string?} filename
43
+ * @param {number} pFile
44
+ * @param {number} flags
45
+ * @param {DataView} pOutFlags
46
+ * @returns {number|Promise<number>}
47
+ */
48
+ jOpen(filename, pFile, flags, pOutFlags) {
49
+ return VFS.SQLITE_CANTOPEN;
50
+ }
51
+
52
+ /**
53
+ * @param {string} filename
54
+ * @param {number} syncDir
55
+ * @returns {number|Promise<number>}
56
+ */
57
+ jDelete(filename, syncDir) {
58
+ return VFS.SQLITE_OK;
59
+ }
60
+
61
+ /**
62
+ * @param {string} filename
63
+ * @param {number} flags
64
+ * @param {DataView} pResOut
65
+ * @returns {number|Promise<number>}
66
+ */
67
+ jAccess(filename, flags, pResOut) {
68
+ return VFS.SQLITE_OK;
69
+ }
70
+
71
+ /**
72
+ * @param {string} filename
73
+ * @param {Uint8Array} zOut
74
+ * @returns {number|Promise<number>}
75
+ */
76
+ jFullPathname(filename, zOut) {
77
+ // Copy the filename to the output buffer.
78
+ const { read, written } = new TextEncoder().encodeInto(filename, zOut);
79
+ if (read < filename.length) return VFS.SQLITE_IOERR;
80
+ if (written >= zOut.length) return VFS.SQLITE_IOERR;
81
+ zOut[written] = 0;
82
+ return VFS.SQLITE_OK;
83
+ }
84
+
85
+ /**
86
+ * @param {Uint8Array} zBuf
87
+ * @returns {number|Promise<number>}
88
+ */
89
+ jGetLastError(zBuf) {
90
+ return VFS.SQLITE_OK;
91
+ }
92
+
93
+ /**
94
+ * @param {number} pFile
95
+ * @returns {number|Promise<number>}
96
+ */
97
+ jClose(pFile) {
98
+ return VFS.SQLITE_OK;
99
+ }
100
+
101
+ /**
102
+ * @param {number} pFile
103
+ * @param {Uint8Array} pData
104
+ * @param {number} iOffset
105
+ * @returns {number|Promise<number>}
106
+ */
107
+ jRead(pFile, pData, iOffset) {
108
+ pData.fill(0);
109
+ return VFS.SQLITE_IOERR_SHORT_READ;
110
+ }
111
+
112
+ /**
113
+ * @param {number} pFile
114
+ * @param {Uint8Array} pData
115
+ * @param {number} iOffset
116
+ * @returns {number|Promise<number>}
117
+ */
118
+ jWrite(pFile, pData, iOffset) {
119
+ return VFS.SQLITE_IOERR_WRITE;
120
+ }
121
+
122
+ /**
123
+ * @param {number} pFile
124
+ * @param {number} size
125
+ * @returns {number|Promise<number>}
126
+ */
127
+ jTruncate(pFile, size) {
128
+ return VFS.SQLITE_OK;
129
+ }
130
+
131
+ /**
132
+ * @param {number} pFile
133
+ * @param {number} flags
134
+ * @returns {number|Promise<number>}
135
+ */
136
+ jSync(pFile, flags) {
137
+ return VFS.SQLITE_OK;
138
+ }
139
+
140
+ /**
141
+ * @param {number} pFile
142
+ * @param {DataView} pSize
143
+ * @returns {number|Promise<number>}
144
+ */
145
+ jFileSize(pFile, pSize) {
146
+ return VFS.SQLITE_OK;
147
+ }
148
+
149
+ /**
150
+ * @param {number} pFile
151
+ * @param {number} lockType
152
+ * @returns {number|Promise<number>}
153
+ */
154
+ jLock(pFile, lockType) {
155
+ return VFS.SQLITE_OK;
156
+ }
157
+
158
+ /**
159
+ * @param {number} pFile
160
+ * @param {number} lockType
161
+ * @returns {number|Promise<number>}
162
+ */
163
+ jUnlock(pFile, lockType) {
164
+ return VFS.SQLITE_OK;
165
+ }
166
+
167
+ /**
168
+ * @param {number} pFile
169
+ * @param {DataView} pResOut
170
+ * @returns {number|Promise<number>}
171
+ */
172
+ jCheckReservedLock(pFile, pResOut) {
173
+ pResOut.setInt32(0, 0, true);
174
+ return VFS.SQLITE_OK;
175
+ }
176
+
177
+ /**
178
+ * @param {number} pFile
179
+ * @param {number} op
180
+ * @param {DataView} pArg
181
+ * @returns {number|Promise<number>}
182
+ */
183
+ jFileControl(pFile, op, pArg) {
184
+ return VFS.SQLITE_NOTFOUND;
185
+ }
186
+
187
+ /**
188
+ * @param {number} pFile
189
+ * @returns {number|Promise<number>}
190
+ */
191
+ jSectorSize(pFile) {
192
+ return super.xSectorSize(pFile);
193
+ }
194
+
195
+ /**
196
+ * @param {number} pFile
197
+ * @returns {number|Promise<number>}
198
+ */
199
+ jDeviceCharacteristics(pFile) {
200
+ return 0;
201
+ }
202
+
203
+ /**
204
+ * @param {number} pVfs
205
+ * @param {number} zName
206
+ * @param {number} pFile
207
+ * @param {number} flags
208
+ * @param {number} pOutFlags
209
+ * @returns {number|Promise<number>}
210
+ */
211
+ xOpen(pVfs, zName, pFile, flags, pOutFlags) {
212
+ const filename = this.#decodeFilename(zName, flags);
213
+ const pOutFlagsView = this.#makeTypedDataView('Int32', pOutFlags);
214
+ this['log']?.('jOpen', filename, pFile, '0x' + flags.toString(16));
215
+ return this.jOpen(filename, pFile, flags, pOutFlagsView);
216
+ }
217
+
218
+ /**
219
+ * @param {number} pVfs
220
+ * @param {number} zName
221
+ * @param {number} syncDir
222
+ * @returns {number|Promise<number>}
223
+ */
224
+ xDelete(pVfs, zName, syncDir) {
225
+ const filename = this._module.UTF8ToString(zName);
226
+ this['log']?.('jDelete', filename, syncDir);
227
+ return this.jDelete(filename, syncDir);
228
+ }
229
+
230
+ /**
231
+ * @param {number} pVfs
232
+ * @param {number} zName
233
+ * @param {number} flags
234
+ * @param {number} pResOut
235
+ * @returns {number|Promise<number>}
236
+ */
237
+ xAccess(pVfs, zName, flags, pResOut) {
238
+ const filename = this._module.UTF8ToString(zName);
239
+ const pResOutView = this.#makeTypedDataView('Int32', pResOut);
240
+ this['log']?.('jAccess', filename, flags);
241
+ return this.jAccess(filename, flags, pResOutView);
242
+ }
243
+
244
+ /**
245
+ * @param {number} pVfs
246
+ * @param {number} zName
247
+ * @param {number} nOut
248
+ * @param {number} zOut
249
+ * @returns {number|Promise<number>}
250
+ */
251
+ xFullPathname(pVfs, zName, nOut, zOut) {
252
+ const filename = this._module.UTF8ToString(zName);
253
+ const zOutArray = this._module.HEAPU8.subarray(zOut, zOut + nOut);
254
+ this['log']?.('jFullPathname', filename, nOut);
255
+ return this.jFullPathname(filename, zOutArray);
256
+ }
257
+
258
+ /**
259
+ * @param {number} pVfs
260
+ * @param {number} nBuf
261
+ * @param {number} zBuf
262
+ * @returns {number|Promise<number>}
263
+ */
264
+ xGetLastError(pVfs, nBuf, zBuf) {
265
+ const zBufArray = this._module.HEAPU8.subarray(zBuf, zBuf + nBuf);
266
+ this['log']?.('jGetLastError', nBuf);
267
+ return this.jGetLastError(zBufArray);
268
+ }
269
+
270
+ /**
271
+ * @param {number} pFile
272
+ * @returns {number|Promise<number>}
273
+ */
274
+ xClose(pFile) {
275
+ this['log']?.('jClose', pFile);
276
+ return this.jClose(pFile);
277
+ }
278
+
279
+ /**
280
+ * @param {number} pFile
281
+ * @param {number} pData
282
+ * @param {number} iAmt
283
+ * @param {number} iOffsetLo
284
+ * @param {number} iOffsetHi
285
+ * @returns {number|Promise<number>}
286
+ */
287
+ xRead(pFile, pData, iAmt, iOffsetLo, iOffsetHi) {
288
+ const pDataArray = this.#makeDataArray(pData, iAmt);
289
+ const iOffset = delegalize(iOffsetLo, iOffsetHi);
290
+ this['log']?.('jRead', pFile, iAmt, iOffset);
291
+ return this.jRead(pFile, pDataArray, iOffset);
292
+ }
293
+
294
+ /**
295
+ * @param {number} pFile
296
+ * @param {number} pData
297
+ * @param {number} iAmt
298
+ * @param {number} iOffsetLo
299
+ * @param {number} iOffsetHi
300
+ * @returns {number|Promise<number>}
301
+ */
302
+ xWrite(pFile, pData, iAmt, iOffsetLo, iOffsetHi) {
303
+ const pDataArray = this.#makeDataArray(pData, iAmt);
304
+ const iOffset = delegalize(iOffsetLo, iOffsetHi);
305
+ this['log']?.('jWrite', pFile, pDataArray, iOffset);
306
+ return this.jWrite(pFile, pDataArray, iOffset);
307
+ }
308
+
309
+ /**
310
+ * @param {number} pFile
311
+ * @param {number} sizeLo
312
+ * @param {number} sizeHi
313
+ * @returns {number|Promise<number>}
314
+ */
315
+ xTruncate(pFile, sizeLo, sizeHi) {
316
+ const size = delegalize(sizeLo, sizeHi);
317
+ this['log']?.('jTruncate', pFile, size);
318
+ return this.jTruncate(pFile, size);
319
+ }
320
+
321
+ /**
322
+ * @param {number} pFile
323
+ * @param {number} flags
324
+ * @returns {number|Promise<number>}
325
+ */
326
+ xSync(pFile, flags) {
327
+ this['log']?.('jSync', pFile, flags);
328
+ return this.jSync(pFile, flags);
329
+ }
330
+
331
+ /**
332
+ *
333
+ * @param {number} pFile
334
+ * @param {number} pSize
335
+ * @returns {number|Promise<number>}
336
+ */
337
+ xFileSize(pFile, pSize) {
338
+ const pSizeView = this.#makeTypedDataView('BigInt64', pSize);
339
+ this['log']?.('jFileSize', pFile);
340
+ return this.jFileSize(pFile, pSizeView);
341
+ }
342
+
343
+ /**
344
+ * @param {number} pFile
345
+ * @param {number} lockType
346
+ * @returns {number|Promise<number>}
347
+ */
348
+ xLock(pFile, lockType) {
349
+ this['log']?.('jLock', pFile, lockType);
350
+ return this.jLock(pFile, lockType);
351
+ }
352
+
353
+ /**
354
+ * @param {number} pFile
355
+ * @param {number} lockType
356
+ * @returns {number|Promise<number>}
357
+ */
358
+ xUnlock(pFile, lockType) {
359
+ this['log']?.('jUnlock', pFile, lockType);
360
+ return this.jUnlock(pFile, lockType);
361
+ }
362
+
363
+ /**
364
+ * @param {number} pFile
365
+ * @param {number} pResOut
366
+ * @returns {number|Promise<number>}
367
+ */
368
+ xCheckReservedLock(pFile, pResOut) {
369
+ const pResOutView = this.#makeTypedDataView('Int32', pResOut);
370
+ this['log']?.('jCheckReservedLock', pFile);
371
+ return this.jCheckReservedLock(pFile, pResOutView);
372
+ }
373
+
374
+ /**
375
+ * @param {number} pFile
376
+ * @param {number} op
377
+ * @param {number} pArg
378
+ * @returns {number|Promise<number>}
379
+ */
380
+ xFileControl(pFile, op, pArg) {
381
+ const pArgView = new DataView(
382
+ this._module.HEAPU8.buffer,
383
+ this._module.HEAPU8.byteOffset + pArg);
384
+ this['log']?.('jFileControl', pFile, op, pArgView);
385
+ return this.jFileControl(pFile, op, pArgView);
386
+ }
387
+
388
+ /**
389
+ * @param {number} pFile
390
+ * @returns {number|Promise<number>}
391
+ */
392
+ xSectorSize(pFile) {
393
+ this['log']?.('jSectorSize', pFile);
394
+ return this.jSectorSize(pFile);
395
+ }
396
+
397
+ /**
398
+ * @param {number} pFile
399
+ * @returns {number|Promise<number>}
400
+ */
401
+ xDeviceCharacteristics(pFile) {
402
+ this['log']?.('jDeviceCharacteristics', pFile);
403
+ return this.jDeviceCharacteristics(pFile);
404
+ }
405
+
406
+ /**
407
+ * Wrapped DataView for pointer arguments.
408
+ * Pointers to a single value are passed using DataView. A Proxy
409
+ * wrapper prevents use of incorrect type or endianness.
410
+ * @param {'Int32'|'BigInt64'} type
411
+ * @param {number} byteOffset
412
+ * @returns {DataView}
413
+ */
414
+ #makeTypedDataView(type, byteOffset) {
415
+ const byteLength = type === 'Int32' ? 4 : 8;
416
+ const getter = `get${type}`;
417
+ const setter = `set${type}`;
418
+ const makeDataView = () => new DataView(
419
+ this._module.HEAPU8.buffer,
420
+ this._module.HEAPU8.byteOffset + byteOffset,
421
+ byteLength);
422
+ let dataView = makeDataView();
423
+ return new Proxy(dataView, {
424
+ get(_, prop) {
425
+ if (dataView.buffer.byteLength === 0) {
426
+ // WebAssembly memory resize detached the buffer.
427
+ dataView = makeDataView();
428
+ }
429
+ if (prop === getter) {
430
+ return function(byteOffset, littleEndian) {
431
+ if (!littleEndian) throw new Error('must be little endian');
432
+ return dataView[prop](byteOffset, littleEndian);
433
+ }
434
+ }
435
+ if (prop === setter) {
436
+ return function(byteOffset, value, littleEndian) {
437
+ if (!littleEndian) throw new Error('must be little endian');
438
+ return dataView[prop](byteOffset, value, littleEndian);
439
+ }
440
+ }
441
+ if (typeof prop === 'string' && (prop.match(/^(get)|(set)/))) {
442
+ throw new Error('invalid type');
443
+ }
444
+ const result = dataView[prop];
445
+ return typeof result === 'function' ? result.bind(dataView) : result;
446
+ }
447
+ });
448
+ }
449
+
450
+ /**
451
+ * @param {number} byteOffset
452
+ * @param {number} byteLength
453
+ */
454
+ #makeDataArray(byteOffset, byteLength) {
455
+ let target = this._module.HEAPU8.subarray(byteOffset, byteOffset + byteLength);
456
+ return new Proxy(target, {
457
+ get: (_, prop, receiver) => {
458
+ if (target.buffer.byteLength === 0) {
459
+ // WebAssembly memory resize detached the buffer.
460
+ target = this._module.HEAPU8.subarray(byteOffset, byteOffset + byteLength);
461
+ }
462
+ const result = target[prop];
463
+ return typeof result === 'function' ? result.bind(target) : result;
464
+ }
465
+ });
466
+ }
467
+
468
+ #decodeFilename(zName, flags) {
469
+ if (flags & VFS.SQLITE_OPEN_URI) {
470
+ // The first null-terminated string is the URI path. Subsequent
471
+ // strings are query parameter keys and values.
472
+ // https://www.sqlite.org/c3ref/open.html#urifilenamesinsqlite3open
473
+ let pName = zName;
474
+ let state = 1;
475
+ const charCodes = [];
476
+ while (state) {
477
+ const charCode = this._module.HEAPU8[pName++];
478
+ if (charCode) {
479
+ charCodes.push(charCode);
480
+ } else {
481
+ if (!this._module.HEAPU8[pName]) state = null;
482
+ switch (state) {
483
+ case 1: // path
484
+ charCodes.push('?'.charCodeAt(0));
485
+ state = 2;
486
+ break;
487
+ case 2: // key
488
+ charCodes.push('='.charCodeAt(0));
489
+ state = 3;
490
+ break;
491
+ case 3: // value
492
+ charCodes.push('&'.charCodeAt(0));
493
+ state = 2;
494
+ break;
495
+ }
496
+ }
497
+ }
498
+ return new TextDecoder().decode(new Uint8Array(charCodes));
499
+ }
500
+ return zName ? this._module.UTF8ToString(zName) : null;
501
+ }
502
+ }
503
+
504
+ // Emscripten "legalizes" 64-bit integer arguments by passing them as
505
+ // two 32-bit signed integers.
506
+ function delegalize(lo32, hi32) {
507
+ return (hi32 * 0x100000000) + lo32 + (lo32 < 0 ? 2**32 : 0);
508
+ }
package/src/VFS.js ADDED
@@ -0,0 +1,222 @@
1
+ // Copyright 2024 Roy T. Hashimoto. All Rights Reserved.
2
+ import * as VFS from './sqlite-constants.js';
3
+ export * from './sqlite-constants.js';
4
+
5
+ const DEFAULT_SECTOR_SIZE = 512;
6
+
7
+ // Base class for a VFS.
8
+ export class Base {
9
+ name;
10
+ mxPathname = 64;
11
+ _module;
12
+
13
+ /**
14
+ * @param {string} name
15
+ * @param {object} module
16
+ */
17
+ constructor(name, module) {
18
+ this.name = name;
19
+ this._module = module;
20
+ }
21
+
22
+ /**
23
+ * @returns {void|Promise<void>}
24
+ */
25
+ close() {
26
+ }
27
+
28
+ /**
29
+ * @returns {boolean|Promise<boolean>}
30
+ */
31
+ isReady() {
32
+ return true;
33
+ }
34
+
35
+ /**
36
+ * Overload in subclasses to indicate which methods are asynchronous.
37
+ * @param {string} methodName
38
+ * @returns {boolean}
39
+ */
40
+ hasAsyncMethod(methodName) {
41
+ return false;
42
+ }
43
+
44
+ /**
45
+ * @param {number} pVfs
46
+ * @param {number} zName
47
+ * @param {number} pFile
48
+ * @param {number} flags
49
+ * @param {number} pOutFlags
50
+ * @returns {number|Promise<number>}
51
+ */
52
+ xOpen(pVfs, zName, pFile, flags, pOutFlags) {
53
+ return VFS.SQLITE_CANTOPEN;
54
+ }
55
+
56
+ /**
57
+ * @param {number} pVfs
58
+ * @param {number} zName
59
+ * @param {number} syncDir
60
+ * @returns {number|Promise<number>}
61
+ */
62
+ xDelete(pVfs, zName, syncDir) {
63
+ return VFS.SQLITE_OK;
64
+ }
65
+
66
+ /**
67
+ * @param {number} pVfs
68
+ * @param {number} zName
69
+ * @param {number} flags
70
+ * @param {number} pResOut
71
+ * @returns {number|Promise<number>}
72
+ */
73
+ xAccess(pVfs, zName, flags, pResOut) {
74
+ return VFS.SQLITE_OK;
75
+ }
76
+
77
+ /**
78
+ * @param {number} pVfs
79
+ * @param {number} zName
80
+ * @param {number} nOut
81
+ * @param {number} zOut
82
+ * @returns {number|Promise<number>}
83
+ */
84
+ xFullPathname(pVfs, zName, nOut, zOut) {
85
+ return VFS.SQLITE_OK;
86
+ }
87
+
88
+ /**
89
+ * @param {number} pVfs
90
+ * @param {number} nBuf
91
+ * @param {number} zBuf
92
+ * @returns {number|Promise<number>}
93
+ */
94
+ xGetLastError(pVfs, nBuf, zBuf) {
95
+ return VFS.SQLITE_OK;
96
+ }
97
+
98
+ /**
99
+ * @param {number} pFile
100
+ * @returns {number|Promise<number>}
101
+ */
102
+ xClose(pFile) {
103
+ return VFS.SQLITE_OK;
104
+ }
105
+
106
+ /**
107
+ * @param {number} pFile
108
+ * @param {number} pData
109
+ * @param {number} iAmt
110
+ * @param {number} iOffsetLo
111
+ * @param {number} iOffsetHi
112
+ * @returns {number|Promise<number>}
113
+ */
114
+ xRead(pFile, pData, iAmt, iOffsetLo, iOffsetHi) {
115
+ return VFS.SQLITE_OK;
116
+ }
117
+
118
+ /**
119
+ * @param {number} pFile
120
+ * @param {number} pData
121
+ * @param {number} iAmt
122
+ * @param {number} iOffsetLo
123
+ * @param {number} iOffsetHi
124
+ * @returns {number|Promise<number>}
125
+ */
126
+ xWrite(pFile, pData, iAmt, iOffsetLo, iOffsetHi) {
127
+ return VFS.SQLITE_OK;
128
+ }
129
+
130
+ /**
131
+ * @param {number} pFile
132
+ * @param {number} sizeLo
133
+ * @param {number} sizeHi
134
+ * @returns {number|Promise<number>}
135
+ */
136
+ xTruncate(pFile, sizeLo, sizeHi) {
137
+ return VFS.SQLITE_OK;
138
+ }
139
+
140
+ /**
141
+ * @param {number} pFile
142
+ * @param {number} flags
143
+ * @returns {number|Promise<number>}
144
+ */
145
+ xSync(pFile, flags) {
146
+ return VFS.SQLITE_OK;
147
+ }
148
+
149
+ /**
150
+ *
151
+ * @param {number} pFile
152
+ * @param {number} pSize
153
+ * @returns {number|Promise<number>}
154
+ */
155
+ xFileSize(pFile, pSize) {
156
+ return VFS.SQLITE_OK;
157
+ }
158
+
159
+ /**
160
+ * @param {number} pFile
161
+ * @param {number} lockType
162
+ * @returns {number|Promise<number>}
163
+ */
164
+ xLock(pFile, lockType) {
165
+ return VFS.SQLITE_OK;
166
+ }
167
+
168
+ /**
169
+ * @param {number} pFile
170
+ * @param {number} lockType
171
+ * @returns {number|Promise<number>}
172
+ */
173
+ xUnlock(pFile, lockType) {
174
+ return VFS.SQLITE_OK;
175
+ }
176
+
177
+ /**
178
+ * @param {number} pFile
179
+ * @param {number} pResOut
180
+ * @returns {number|Promise<number>}
181
+ */
182
+ xCheckReservedLock(pFile, pResOut) {
183
+ return VFS.SQLITE_OK;
184
+ }
185
+
186
+ /**
187
+ * @param {number} pFile
188
+ * @param {number} op
189
+ * @param {number} pArg
190
+ * @returns {number|Promise<number>}
191
+ */
192
+ xFileControl(pFile, op, pArg) {
193
+ return VFS.SQLITE_NOTFOUND;
194
+ }
195
+
196
+ /**
197
+ * @param {number} pFile
198
+ * @returns {number|Promise<number>}
199
+ */
200
+ xSectorSize(pFile) {
201
+ return DEFAULT_SECTOR_SIZE;
202
+ }
203
+
204
+ /**
205
+ * @param {number} pFile
206
+ * @returns {number|Promise<number>}
207
+ */
208
+ xDeviceCharacteristics(pFile) {
209
+ return 0;
210
+ }
211
+ }
212
+
213
+ export const FILE_TYPE_MASK = [
214
+ VFS.SQLITE_OPEN_MAIN_DB,
215
+ VFS.SQLITE_OPEN_MAIN_JOURNAL,
216
+ VFS.SQLITE_OPEN_TEMP_DB,
217
+ VFS.SQLITE_OPEN_TEMP_JOURNAL,
218
+ VFS.SQLITE_OPEN_TRANSIENT_DB,
219
+ VFS.SQLITE_OPEN_SUBJOURNAL,
220
+ VFS.SQLITE_OPEN_SUPER_JOURNAL,
221
+ VFS.SQLITE_OPEN_WAL
222
+ ].reduce((mask, element) => mask | element);