@livestore/wa-sqlite 0.0.0-snapshot-b9a2e1dee494215d8c403be013e25cbf4d2cf380

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 (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/dist/README.md +64 -0
  4. package/dist/fts5/wa-sqlite.mjs +2 -0
  5. package/dist/fts5/wa-sqlite.node.mjs +2 -0
  6. package/dist/fts5/wa-sqlite.node.wasm +0 -0
  7. package/dist/fts5/wa-sqlite.wasm +0 -0
  8. package/dist/wa-sqlite-async.mjs +2 -0
  9. package/dist/wa-sqlite-async.wasm +0 -0
  10. package/dist/wa-sqlite-jspi.mjs +2 -0
  11. package/dist/wa-sqlite-jspi.wasm +0 -0
  12. package/dist/wa-sqlite.mjs +2 -0
  13. package/dist/wa-sqlite.node.mjs +2 -0
  14. package/dist/wa-sqlite.node.wasm +0 -0
  15. package/dist/wa-sqlite.wasm +0 -0
  16. package/package.json +57 -0
  17. package/src/FacadeVFS.js +681 -0
  18. package/src/VFS.js +222 -0
  19. package/src/WebLocksMixin.js +414 -0
  20. package/src/examples/AccessHandlePoolVFS.js +458 -0
  21. package/src/examples/IDBBatchAtomicVFS.js +827 -0
  22. package/src/examples/IDBMirrorVFS.js +889 -0
  23. package/src/examples/MemoryAsyncVFS.js +100 -0
  24. package/src/examples/MemoryVFS.js +176 -0
  25. package/src/examples/OPFSAdaptiveVFS.js +437 -0
  26. package/src/examples/OPFSAnyContextVFS.js +300 -0
  27. package/src/examples/OPFSCoopSyncVFS.js +590 -0
  28. package/src/examples/OPFSPermutedVFS.js +1217 -0
  29. package/src/examples/README.md +89 -0
  30. package/src/examples/tag.js +82 -0
  31. package/src/sqlite-api.js +1339 -0
  32. package/src/sqlite-constants.js +275 -0
  33. package/src/types/globals.d.ts +60 -0
  34. package/src/types/index.d.ts +1531 -0
  35. package/src/types/tsconfig.json +6 -0
  36. package/test/AccessHandlePoolVFS.test.js +27 -0
  37. package/test/IDBBatchAtomicVFS.test.js +97 -0
  38. package/test/IDBMirrorVFS.test.js +27 -0
  39. package/test/MemoryAsyncVFS.test.js +27 -0
  40. package/test/MemoryVFS.test.js +27 -0
  41. package/test/OPFSAdaptiveVFS.test.js +27 -0
  42. package/test/OPFSAnyContextVFS.test.js +27 -0
  43. package/test/OPFSCoopSyncVFS.test.js +27 -0
  44. package/test/OPFSPermutedVFS.test.js +27 -0
  45. package/test/TestContext.js +96 -0
  46. package/test/WebLocksMixin.test.js +521 -0
  47. package/test/api.test.js +49 -0
  48. package/test/api_exec.js +89 -0
  49. package/test/api_misc.js +63 -0
  50. package/test/api_statements.js +447 -0
  51. package/test/callbacks.test.js +581 -0
  52. package/test/data/idbv5.json +1 -0
  53. package/test/sql.test.js +64 -0
  54. package/test/sql_0001.js +49 -0
  55. package/test/sql_0002.js +52 -0
  56. package/test/sql_0003.js +83 -0
  57. package/test/sql_0004.js +81 -0
  58. package/test/sql_0005.js +76 -0
  59. package/test/test-worker.js +204 -0
  60. package/test/vfs_xAccess.js +2 -0
  61. package/test/vfs_xClose.js +52 -0
  62. package/test/vfs_xOpen.js +91 -0
  63. package/test/vfs_xRead.js +38 -0
  64. package/test/vfs_xWrite.js +36 -0
@@ -0,0 +1,681 @@
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 a DataView-like class.
409
+ * This wrapper class prevents use of incorrect type or endianness, and
410
+ * reacquires the underlying buffer when the WebAssembly memory is resized.
411
+ * @param {'Int32'|'BigInt64'} type
412
+ * @param {number} byteOffset
413
+ * @returns {DataView}
414
+ */
415
+ #makeTypedDataView(type, byteOffset) {
416
+ // @ts-ignore
417
+ return new DataViewProxy(this._module, byteOffset, type);
418
+ }
419
+
420
+ /**
421
+ * Wrapped Uint8Array for buffer arguments.
422
+ * Memory blocks are passed as a Uint8Array-like class. This wrapper
423
+ * class reacquires the underlying buffer when the WebAssembly memory
424
+ * is resized.
425
+ * @param {number} byteOffset
426
+ * @param {number} byteLength
427
+ * @returns {Uint8Array}
428
+ */
429
+ #makeDataArray(byteOffset, byteLength) {
430
+ // @ts-ignore
431
+ return new Uint8ArrayProxy(this._module, byteOffset, byteLength);
432
+ }
433
+
434
+ #decodeFilename(zName, flags) {
435
+ if (flags & VFS.SQLITE_OPEN_URI) {
436
+ // The first null-terminated string is the URI path. Subsequent
437
+ // strings are query parameter keys and values.
438
+ // https://www.sqlite.org/c3ref/open.html#urifilenamesinsqlite3open
439
+ let pName = zName;
440
+ let state = 1;
441
+ const charCodes = [];
442
+ while (state) {
443
+ const charCode = this._module.HEAPU8[pName++];
444
+ if (charCode) {
445
+ charCodes.push(charCode);
446
+ } else {
447
+ if (!this._module.HEAPU8[pName]) state = null;
448
+ switch (state) {
449
+ case 1: // path
450
+ charCodes.push('?'.charCodeAt(0));
451
+ state = 2;
452
+ break;
453
+ case 2: // key
454
+ charCodes.push('='.charCodeAt(0));
455
+ state = 3;
456
+ break;
457
+ case 3: // value
458
+ charCodes.push('&'.charCodeAt(0));
459
+ state = 2;
460
+ break;
461
+ }
462
+ }
463
+ }
464
+ return new TextDecoder().decode(new Uint8Array(charCodes));
465
+ }
466
+ return zName ? this._module.UTF8ToString(zName) : null;
467
+ }
468
+ }
469
+
470
+ // Emscripten "legalizes" 64-bit integer arguments by passing them as
471
+ // two 32-bit signed integers.
472
+ function delegalize(lo32, hi32) {
473
+ return (hi32 * 0x100000000) + lo32 + (lo32 < 0 ? 2**32 : 0);
474
+ }
475
+
476
+ // This class provides a Uint8Array-like interface for a WebAssembly memory
477
+ // buffer. It is used to access memory blocks passed as arguments to
478
+ // xRead, xWrite, etc. The class reacquires the underlying buffer when the
479
+ // WebAssembly memory is resized, which can happen when the memory is
480
+ // detached and resized by the WebAssembly module.
481
+ //
482
+ // Note that although this class implements the same methods as Uint8Array,
483
+ // it is not a real Uint8Array and passing it to functions that expect
484
+ // a Uint8Array may not work. Use subarray() to get a real Uint8Array
485
+ // if needed.
486
+ class Uint8ArrayProxy {
487
+ #module;
488
+
489
+ #_array = new Uint8Array()
490
+ get #array() {
491
+ if (this.#_array.buffer.byteLength === 0) {
492
+ // WebAssembly memory resize detached the buffer so re-create the
493
+ // array with the new buffer.
494
+ this.#_array = this.#module.HEAPU8.subarray(
495
+ this.byteOffset,
496
+ this.byteOffset + this.byteLength);
497
+ }
498
+ return this.#_array;
499
+ }
500
+
501
+ /**
502
+ * @param {*} module
503
+ * @param {number} byteOffset
504
+ * @param {number} byteLength
505
+ */
506
+ constructor(module, byteOffset, byteLength) {
507
+ this.#module = module;
508
+ this.byteOffset = byteOffset;
509
+ this.length = this.byteLength = byteLength;
510
+ }
511
+
512
+ get buffer() {
513
+ return this.#array.buffer;
514
+ }
515
+
516
+ at(index) {
517
+ return this.#array.at(index);
518
+ }
519
+ copyWithin(target, start, end) {
520
+ this.#array.copyWithin(target, start, end);
521
+ }
522
+ entries() {
523
+ return this.#array.entries();
524
+ }
525
+ every(predicate) {
526
+ return this.#array.every(predicate);
527
+ }
528
+ fill(value, start, end) {
529
+ this.#array.fill(value, start, end);
530
+ }
531
+ filter(predicate) {
532
+ return this.#array.filter(predicate);
533
+ }
534
+ find(predicate) {
535
+ return this.#array.find(predicate);
536
+ }
537
+ findIndex(predicate) {
538
+ return this.#array.findIndex(predicate);
539
+ }
540
+ findLast(predicate) {
541
+ return this.#array.findLast(predicate);
542
+ }
543
+ findLastIndex(predicate) {
544
+ return this.#array.findLastIndex(predicate);
545
+ }
546
+ forEach(callback) {
547
+ this.#array.forEach(callback);
548
+ }
549
+ includes(value, start) {
550
+ return this.#array.includes(value, start);
551
+ }
552
+ indexOf(value, start) {
553
+ return this.#array.indexOf(value, start);
554
+ }
555
+ join(separator) {
556
+ return this.#array.join(separator);
557
+ }
558
+ keys() {
559
+ return this.#array.keys();
560
+ }
561
+ lastIndexOf(value, start) {
562
+ return this.#array.lastIndexOf(value, start);
563
+ }
564
+ map(callback) {
565
+ return this.#array.map(callback);
566
+ }
567
+ reduce(callback, initialValue) {
568
+ return this.#array.reduce(callback, initialValue);
569
+ }
570
+ reduceRight(callback, initialValue) {
571
+ return this.#array.reduceRight(callback, initialValue);
572
+ }
573
+ reverse() {
574
+ this.#array.reverse();
575
+ }
576
+ set(array, offset) {
577
+ this.#array.set(array, offset);
578
+ }
579
+ slice(start, end) {
580
+ return this.#array.slice(start, end);
581
+ }
582
+ some(predicate) {
583
+ return this.#array.some(predicate);
584
+ }
585
+ sort(compareFn) {
586
+ this.#array.sort(compareFn);
587
+ }
588
+ subarray(begin, end) {
589
+ return this.#array.subarray(begin, end);
590
+ }
591
+ toLocaleString(locales, options) {
592
+ // @ts-ignore
593
+ return this.#array.toLocaleString(locales, options);
594
+ }
595
+ toReversed() {
596
+ return this.#array.toReversed();
597
+ }
598
+ toSorted(compareFn) {
599
+ return this.#array.toSorted(compareFn);
600
+ }
601
+ toString() {
602
+ return this.#array.toString();
603
+ }
604
+ values() {
605
+ return this.#array.values();
606
+ }
607
+ with(index, value) {
608
+ return this.#array.with(index, value);
609
+ }
610
+ [Symbol.iterator]() {
611
+ return this.#array[Symbol.iterator]();
612
+ }
613
+ }
614
+
615
+ // This class provides a DataView-like interface for a WebAssembly memory
616
+ // buffer, restricted to either Int32 or BigInt64 types. It also reacquires
617
+ // the underlying buffer when the WebAssembly memory is resized, which can
618
+ // happen when the memory is detached and resized by the WebAssembly module.
619
+ class DataViewProxy {
620
+ #module;
621
+ #type;
622
+
623
+ #_view = new DataView(new ArrayBuffer(0));
624
+ get #view() {
625
+ if (this.#_view.buffer.byteLength === 0) {
626
+ // WebAssembly memory resize detached the buffer so re-create the
627
+ // view with the new buffer.
628
+ this.#_view = new DataView(
629
+ this.#module.HEAPU8.buffer,
630
+ this.#module.HEAPU8.byteOffset + this.byteOffset);
631
+ }
632
+ return this.#_view;
633
+ }
634
+
635
+ /**
636
+ * @param {*} module
637
+ * @param {number} byteOffset
638
+ * @param {'Int32'|'BigInt64'} type
639
+ */
640
+ constructor(module, byteOffset, type) {
641
+ this.#module = module;
642
+ this.byteOffset = byteOffset;
643
+ this.#type = type;
644
+ }
645
+
646
+ get buffer() {
647
+ return this.#view.buffer;
648
+ }
649
+ get byteLength() {
650
+ return this.#type === 'Int32' ? 4 : 8;
651
+ }
652
+
653
+ getInt32(byteOffset, littleEndian) {
654
+ if (this.#type !== 'Int32') {
655
+ throw new Error('invalid type');
656
+ }
657
+ if (!littleEndian) throw new Error('must be little endian');
658
+ return this.#view.getInt32(byteOffset, littleEndian);
659
+ }
660
+ setInt32(byteOffset, value, littleEndian) {
661
+ if (this.#type !== 'Int32') {
662
+ throw new Error('invalid type');
663
+ }
664
+ if (!littleEndian) throw new Error('must be little endian');
665
+ this.#view.setInt32(byteOffset, value, littleEndian);
666
+ }
667
+ getBigInt64(byteOffset, littleEndian) {
668
+ if (this.#type !== 'BigInt64') {
669
+ throw new Error('invalid type');
670
+ }
671
+ if (!littleEndian) throw new Error('must be little endian');
672
+ return this.#view.getBigInt64(byteOffset, littleEndian);
673
+ }
674
+ setBigInt64(byteOffset, value, littleEndian) {
675
+ if (this.#type !== 'BigInt64') {
676
+ throw new Error('invalid type');
677
+ }
678
+ if (!littleEndian) throw new Error('must be little endian');
679
+ this.#view.setBigInt64(byteOffset, value, littleEndian);
680
+ }
681
+ }