@powersync/web 1.10.1 → 1.11.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 (20) hide show
  1. package/dist/24cd027f23123a1360de.wasm +0 -0
  2. package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d0.index.umd.js +325 -0
  3. package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d0.index.umd.js.map +1 -0
  4. package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d1.index.umd.js +325 -0
  5. package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js-async-mutex-c-3cff7d1.index.umd.js.map +1 -0
  6. package/dist/index.umd.js +48 -177
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/worker/SharedSyncImplementation.umd.js +223 -233
  9. package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
  10. package/dist/worker/WASQLiteDB.umd.js +223 -233
  11. package/dist/worker/WASQLiteDB.umd.js.map +1 -1
  12. package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js +2 -132
  13. package/dist/worker/node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs.umd.js.map +1 -1
  14. package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js +1707 -1372
  15. package/dist/worker/node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js.umd.js.map +1 -1
  16. package/lib/package.json +3 -3
  17. package/lib/src/shared/open-db.js +36 -35
  18. package/lib/tsconfig.tsbuildinfo +1 -1
  19. package/package.json +3 -3
  20. package/dist/d96c8ebf66d665ac9ff6.wasm +0 -0
@@ -779,8 +779,8 @@ __webpack_require__.r(__webpack_exports__);
779
779
  /* harmony export */ _openDB: () => (/* binding */ _openDB)
780
780
  /* harmony export */ });
781
781
  /* harmony import */ var _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @journeyapps/wa-sqlite */ "../../node_modules/@journeyapps/wa-sqlite/src/sqlite-api.js");
782
- /* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! comlink */ "../../node_modules/comlink/dist/esm/comlink.mjs");
783
782
  /* harmony import */ var async_mutex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! async-mutex */ "../../node_modules/async-mutex/index.mjs");
783
+ /* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! comlink */ "../../node_modules/comlink/dist/esm/comlink.mjs");
784
784
 
785
785
 
786
786
 
@@ -790,8 +790,13 @@ async function _openDB(dbFileName, options = { useWebWorker: true }) {
790
790
  const { default: moduleFactory } = await __webpack_require__.e(/*! import() */ "node_modules_journeyapps_wa-sqlite_dist_wa-sqlite-async_mjs").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/dist/wa-sqlite-async.mjs */ "../../node_modules/@journeyapps/wa-sqlite/dist/wa-sqlite-async.mjs"));
791
791
  const module = await moduleFactory();
792
792
  const sqlite3 = _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.Factory(module);
793
+ /**
794
+ * Register the PowerSync core SQLite extension
795
+ */
796
+ module.ccall('powersync_init_static', 'int', []);
793
797
  const { IDBBatchAtomicVFS } = await __webpack_require__.e(/*! import() */ "node_modules_journeyapps_wa-sqlite_src_examples_IDBBatchAtomicVFS_js").then(__webpack_require__.bind(__webpack_require__, /*! @journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js */ "../../node_modules/@journeyapps/wa-sqlite/src/examples/IDBBatchAtomicVFS.js"));
794
- const vfs = new IDBBatchAtomicVFS(dbFileName);
798
+ // @ts-expect-error The types for this static method are missing upstream
799
+ const vfs = await IDBBatchAtomicVFS.create(dbFileName, module, { lockPolicy: 'exclusive' });
795
800
  sqlite3.vfs_register(vfs, true);
796
801
  const db = await sqlite3.open_v2(dbFileName);
797
802
  const statementMutex = new async_mutex__WEBPACK_IMPORTED_MODULE_1__.Mutex();
@@ -807,7 +812,10 @@ async function _openDB(dbFileName, options = { useWebWorker: true }) {
807
812
  updatedTables.clear();
808
813
  Array.from(listeners.values()).forEach((l) => l(event));
809
814
  }
810
- sqlite3.register_table_onchange_hook(db, (opType, tableName, rowId) => {
815
+ sqlite3.update_hook(db, (updateType, dbName, tableName) => {
816
+ if (!tableName) {
817
+ return;
818
+ }
811
819
  updatedTables.add(tableName);
812
820
  if (updateTimer == null) {
813
821
  updateTimer = setTimeout(fireUpdates, 0);
@@ -889,40 +897,36 @@ async function _openDB(dbFileName, options = { useWebWorker: true }) {
889
897
  const executeBatch = async (sql, bindings) => {
890
898
  return _acquireExecuteLock(async () => {
891
899
  let affectedRows = 0;
892
- const str = sqlite3.str_new(db, sql);
893
- const query = sqlite3.str_value(str);
894
900
  try {
895
901
  await executeSingleStatement('BEGIN TRANSACTION');
896
- //Prepare statement once
897
- const prepared = await sqlite3.prepare_v2(db, query);
898
- if (prepared === null) {
899
- return {
900
- rowsAffected: 0,
901
- rows: { _array: [], length: 0 }
902
- };
903
- }
904
902
  const wrappedBindings = bindings ? bindings : [];
905
- for (const binding of wrappedBindings) {
906
- // TODO not sure why this is needed currently, but booleans break
907
- for (let i = 0; i < binding.length; i++) {
908
- const b = binding[i];
909
- if (typeof b == 'boolean') {
910
- binding[i] = b ? 1 : 0;
911
- }
912
- }
913
- //Reset bindings
914
- sqlite3.reset(prepared.stmt);
915
- if (bindings) {
916
- sqlite3.bind_collection(prepared.stmt, binding);
903
+ for await (const stmt of sqlite3.statements(db, sql)) {
904
+ if (stmt === null) {
905
+ return {
906
+ rowsAffected: 0,
907
+ rows: { _array: [], length: 0 }
908
+ };
917
909
  }
918
- const result = await sqlite3.step(prepared.stmt);
919
- if (result === _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.SQLITE_DONE) {
920
- //The value returned by sqlite3_changes() immediately after an INSERT, UPDATE or DELETE statement run on a view is always zero.
921
- affectedRows += sqlite3.changes(db);
910
+ //Prepare statement once
911
+ for (const binding of wrappedBindings) {
912
+ // TODO not sure why this is needed currently, but booleans break
913
+ for (let i = 0; i < binding.length; i++) {
914
+ const b = binding[i];
915
+ if (typeof b == 'boolean') {
916
+ binding[i] = b ? 1 : 0;
917
+ }
918
+ }
919
+ if (bindings) {
920
+ sqlite3.bind_collection(stmt, binding);
921
+ }
922
+ const result = await sqlite3.step(stmt);
923
+ if (result === _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.SQLITE_DONE) {
924
+ //The value returned by sqlite3_changes() immediately after an INSERT, UPDATE or DELETE statement run on a view is always zero.
925
+ affectedRows += sqlite3.changes(db);
926
+ }
927
+ sqlite3.reset(stmt);
922
928
  }
923
929
  }
924
- //Finalize prepared statement
925
- await sqlite3.finalize(prepared.stmt);
926
930
  await executeSingleStatement('COMMIT');
927
931
  }
928
932
  catch (err) {
@@ -932,9 +936,6 @@ async function _openDB(dbFileName, options = { useWebWorker: true }) {
932
936
  rows: { _array: [], length: 0 }
933
937
  };
934
938
  }
935
- finally {
936
- sqlite3.str_finish(str);
937
- }
938
939
  const result = {
939
940
  rowsAffected: affectedRows,
940
941
  rows: { _array: [], length: 0 }
@@ -2283,6 +2284,9 @@ __webpack_require__.r(__webpack_exports__);
2283
2284
  /* harmony export */ SQLITE_OPEN_WAL: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_OPEN_WAL),
2284
2285
  /* harmony export */ SQLITE_PERM: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_PERM),
2285
2286
  /* harmony export */ SQLITE_PRAGMA: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_PRAGMA),
2287
+ /* harmony export */ SQLITE_PREPARE_NORMALIZED: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_PREPARE_NORMALIZED),
2288
+ /* harmony export */ SQLITE_PREPARE_NO_VTAB: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_PREPARE_NO_VTAB),
2289
+ /* harmony export */ SQLITE_PREPARE_PERSISTENT: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_PREPARE_PERSISTENT),
2286
2290
  /* harmony export */ SQLITE_PROTOCOL: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_PROTOCOL),
2287
2291
  /* harmony export */ SQLITE_RANGE: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_RANGE),
2288
2292
  /* harmony export */ SQLITE_READ: () => (/* reexport safe */ _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_READ),
@@ -2329,6 +2333,8 @@ if (typeof BigInt.prototype['toJSON'] == 'undefined') {
2329
2333
  const MAX_INT64 = 0x7fffffffffffffffn;
2330
2334
  const MIN_INT64 = -0x8000000000000000n;
2331
2335
 
2336
+ const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
2337
+
2332
2338
  class SQLiteError extends Error {
2333
2339
  constructor(message, code) {
2334
2340
  super(message);
@@ -2338,10 +2344,6 @@ class SQLiteError extends Error {
2338
2344
 
2339
2345
  const async = true;
2340
2346
 
2341
- const onTableChangeCallbacks = {};
2342
- globalThis.__onTablesChanged = function(db, opType, tableName, rowId) {
2343
- onTableChangeCallbacks[db]?.(opType, tableName, rowId);
2344
- };
2345
2347
 
2346
2348
  /**
2347
2349
  * Builds a Javascript API from the Emscripten module. This API is still
@@ -2353,6 +2355,7 @@ globalThis.__onTablesChanged = function(db, opType, tableName, rowId) {
2353
2355
  function Factory(Module) {
2354
2356
  /** @type {SQLiteAPI} */ const sqlite3 = {};
2355
2357
 
2358
+ Module.retryOps = [];
2356
2359
  const sqliteFreeAddress = Module._getSqliteFree();
2357
2360
 
2358
2361
  // Allocate some space for 32-bit returned values.
@@ -2363,9 +2366,10 @@ function Factory(Module) {
2363
2366
  // memory (use sqlite3_free to deallocate).
2364
2367
  function createUTF8(s) {
2365
2368
  if (typeof s !== 'string') return 0;
2366
- const n = Module.lengthBytesUTF8(s);
2367
- const zts = Module._sqlite3_malloc(n + 1);
2368
- Module.stringToUTF8(s, zts, n + 1);
2369
+ const utf8 = new TextEncoder().encode(s);
2370
+ const zts = Module._sqlite3_malloc(utf8.byteLength + 1);
2371
+ Module.HEAPU8.set(utf8, zts);
2372
+ Module.HEAPU8[zts + utf8.byteLength] = 0;
2369
2373
  return zts;
2370
2374
  }
2371
2375
 
@@ -2475,7 +2479,6 @@ function Factory(Module) {
2475
2479
  const ptr = Module._sqlite3_malloc(byteLength);
2476
2480
  Module.HEAPU8.subarray(ptr).set(value);
2477
2481
  const result = f(stmt, i, ptr, byteLength, sqliteFreeAddress);
2478
- // trace(fname, result);
2479
2482
  return check(fname, result, mapStmtToDB.get(stmt));
2480
2483
  };
2481
2484
  })();
@@ -2486,7 +2489,6 @@ function Factory(Module) {
2486
2489
  return function(stmt) {
2487
2490
  verifyStatement(stmt);
2488
2491
  const result = f(stmt);
2489
- // trace(fname, result);
2490
2492
  return result;
2491
2493
  };
2492
2494
  })();
@@ -2497,7 +2499,6 @@ function Factory(Module) {
2497
2499
  return function(stmt, i, value) {
2498
2500
  verifyStatement(stmt);
2499
2501
  const result = f(stmt, i, value);
2500
- // trace(fname, result);
2501
2502
  return check(fname, result, mapStmtToDB.get(stmt));
2502
2503
  };
2503
2504
  })();
@@ -2510,7 +2511,6 @@ function Factory(Module) {
2510
2511
  if (value > 0x7fffffff || value < -0x80000000) return _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_RANGE;
2511
2512
 
2512
2513
  const result = f(stmt, i, value);
2513
- // trace(fname, result);
2514
2514
  return check(fname, result, mapStmtToDB.get(stmt));
2515
2515
  };
2516
2516
  })();
@@ -2525,7 +2525,6 @@ function Factory(Module) {
2525
2525
  const lo32 = value & 0xffffffffn;
2526
2526
  const hi32 = value >> 32n;
2527
2527
  const result = f(stmt, i, Number(lo32), Number(hi32));
2528
- // trace(fname, result);
2529
2528
  return check(fname, result, mapStmtToDB.get(stmt));
2530
2529
  };
2531
2530
  })();
@@ -2536,7 +2535,6 @@ function Factory(Module) {
2536
2535
  return function(stmt, i) {
2537
2536
  verifyStatement(stmt);
2538
2537
  const result = f(stmt, i);
2539
- // trace(fname, result);
2540
2538
  return check(fname, result, mapStmtToDB.get(stmt));
2541
2539
  };
2542
2540
  })();
@@ -2547,7 +2545,6 @@ function Factory(Module) {
2547
2545
  return function(stmt, i) {
2548
2546
  verifyStatement(stmt);
2549
2547
  const result = f(stmt, i);
2550
- // trace(fname, result);
2551
2548
  return result;
2552
2549
  };
2553
2550
  })();
@@ -2559,7 +2556,6 @@ function Factory(Module) {
2559
2556
  verifyStatement(stmt);
2560
2557
  const ptr = createUTF8(value);
2561
2558
  const result = f(stmt, i, ptr, -1, sqliteFreeAddress);
2562
- // trace(fname, result);
2563
2559
  return check(fname, result, mapStmtToDB.get(stmt));
2564
2560
  };
2565
2561
  })();
@@ -2570,11 +2566,20 @@ function Factory(Module) {
2570
2566
  return function(db) {
2571
2567
  verifyDatabase(db);
2572
2568
  const result = f(db);
2573
- // trace(fname, result);
2574
2569
  return result;
2575
2570
  };
2576
2571
  })();
2577
2572
 
2573
+ sqlite3.clear_bindings = (function() {
2574
+ const fname = 'sqlite3_clear_bindings';
2575
+ const f = Module.cwrap(fname, ...decl('n:n'));
2576
+ return function(stmt) {
2577
+ verifyStatement(stmt);
2578
+ const result = f(stmt);
2579
+ return check(fname, result, mapStmtToDB.get(stmt));
2580
+ };
2581
+ })();
2582
+
2578
2583
  sqlite3.last_insert_id = (function() {
2579
2584
  const fname = 'sqlite3_last_insert_rowid';
2580
2585
  const f = Module.cwrap(fname, ...decl('n:n'));
@@ -2585,7 +2590,7 @@ function Factory(Module) {
2585
2590
  return result;
2586
2591
  };
2587
2592
  })();
2588
-
2593
+
2589
2594
  sqlite3.close = (function() {
2590
2595
  const fname = 'sqlite3_close';
2591
2596
  const f = Module.cwrap(fname, ...decl('n:n'), { async });
@@ -2626,7 +2631,6 @@ function Factory(Module) {
2626
2631
  const nBytes = sqlite3.column_bytes(stmt, iCol);
2627
2632
  const address = f(stmt, iCol);
2628
2633
  const result = Module.HEAPU8.subarray(address, address + nBytes);
2629
- // trace(fname, result);
2630
2634
  return result;
2631
2635
  };
2632
2636
  })();
@@ -2637,7 +2641,6 @@ function Factory(Module) {
2637
2641
  return function(stmt, iCol) {
2638
2642
  verifyStatement(stmt);
2639
2643
  const result = f(stmt, iCol);
2640
- // trace(fname, result);
2641
2644
  return result;
2642
2645
  };
2643
2646
  })();
@@ -2648,7 +2651,6 @@ function Factory(Module) {
2648
2651
  return function(stmt) {
2649
2652
  verifyStatement(stmt);
2650
2653
  const result = f(stmt);
2651
- // trace(fname, result);
2652
2654
  return result;
2653
2655
  };
2654
2656
  })();
@@ -2659,7 +2661,6 @@ function Factory(Module) {
2659
2661
  return function(stmt, iCol) {
2660
2662
  verifyStatement(stmt);
2661
2663
  const result = f(stmt, iCol);
2662
- // trace(fname, result);
2663
2664
  return result;
2664
2665
  };
2665
2666
  })();
@@ -2672,7 +2673,6 @@ function Factory(Module) {
2672
2673
  return function(stmt, iCol) {
2673
2674
  verifyStatement(stmt);
2674
2675
  const result = f(stmt, iCol);
2675
- // trace(fname, result);
2676
2676
  return result;
2677
2677
  };
2678
2678
  })();
@@ -2685,7 +2685,6 @@ function Factory(Module) {
2685
2685
  const lo32 = f(stmt, iCol);
2686
2686
  const hi32 = Module.getTempRet0();
2687
2687
  const result = cvt32x2ToBigInt(lo32, hi32);
2688
- // trace(fname, result);
2689
2688
  return result;
2690
2689
  };
2691
2690
  })();
@@ -2696,7 +2695,6 @@ function Factory(Module) {
2696
2695
  return function(stmt, iCol) {
2697
2696
  verifyStatement(stmt);
2698
2697
  const result = f(stmt, iCol);
2699
- // trace(fname, result);
2700
2698
  return result;
2701
2699
  };
2702
2700
  })();
@@ -2716,7 +2714,6 @@ function Factory(Module) {
2716
2714
  return function(stmt, iCol) {
2717
2715
  verifyStatement(stmt);
2718
2716
  const result = f(stmt, iCol);
2719
- // trace(fname, result);
2720
2717
  return result;
2721
2718
  };
2722
2719
  })();
@@ -2727,30 +2724,30 @@ function Factory(Module) {
2727
2724
  return function(stmt, iCol) {
2728
2725
  verifyStatement(stmt);
2729
2726
  const result = f(stmt, iCol);
2730
- // trace(fname, result);
2731
2727
  return result;
2732
2728
  };
2733
2729
  })();
2734
2730
 
2735
2731
  sqlite3.create_function = function(db, zFunctionName, nArg, eTextRep, pApp, xFunc, xStep, xFinal) {
2736
2732
  verifyDatabase(db);
2737
- if (xFunc && !xStep && !xFinal) {
2738
- const result = Module.createFunction(db, zFunctionName, nArg, eTextRep, pApp, xFunc);
2739
- return check('sqlite3_create_function', result, db);
2740
- }
2741
-
2742
- if (!xFunc && xStep && xFinal) {
2743
- const result = Module.createAggregate(db, zFunctionName, nArg, eTextRep, pApp, xStep, xFinal);
2744
- return check('sqlite3_create_function', result, db);
2733
+
2734
+ // Convert SQLite callback arguments to JavaScript-friendly arguments.
2735
+ function adapt(f) {
2736
+ return f instanceof AsyncFunction ?
2737
+ (async (ctx, n, values) => f(ctx, Module.HEAP32.subarray(values / 4, values / 4 + n))) :
2738
+ ((ctx, n, values) => f(ctx, Module.HEAP32.subarray(values / 4, values / 4 + n)));
2745
2739
  }
2746
2740
 
2747
- throw new SQLiteError('invalid function combination', _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_MISUSE);
2748
- };
2749
-
2750
- sqlite3.create_module = function(db, zName, module, appData) {
2751
- verifyDatabase(db);
2752
- const result = Module.createModule(db, zName, module, appData);
2753
- return check('sqlite3_create_module', result, db);
2741
+ const result = Module.create_function(
2742
+ db,
2743
+ zFunctionName,
2744
+ nArg,
2745
+ eTextRep,
2746
+ pApp,
2747
+ xFunc && adapt(xFunc),
2748
+ xStep && adapt(xStep),
2749
+ xFinal);
2750
+ return check('sqlite3_create_function', result, db);
2754
2751
  };
2755
2752
 
2756
2753
  sqlite3.data_count = (function() {
@@ -2759,20 +2756,10 @@ function Factory(Module) {
2759
2756
  return function(stmt) {
2760
2757
  verifyStatement(stmt);
2761
2758
  const result = f(stmt);
2762
- // trace(fname, result);
2763
2759
  return result;
2764
2760
  };
2765
2761
  })();
2766
2762
 
2767
- sqlite3.declare_vtab = (function() {
2768
- const fname = 'sqlite3_declare_vtab';
2769
- const f = Module.cwrap(fname, ...decl('ns:n'));
2770
- return function(pVTab, zSQL) {
2771
- const result = f(pVTab, zSQL);
2772
- return check('sqlite3_declare_vtab', result);
2773
- }
2774
- })();
2775
-
2776
2763
  sqlite3.exec = async function(db, sql, callback) {
2777
2764
  for await (const stmt of sqlite3.statements(db, sql)) {
2778
2765
  let columns;
@@ -2791,13 +2778,8 @@ function Factory(Module) {
2791
2778
  const fname = 'sqlite3_finalize';
2792
2779
  const f = Module.cwrap(fname, ...decl('n:n'), { async });
2793
2780
  return async function(stmt) {
2794
- if (!mapStmtToDB.has(stmt)) {
2795
- return _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_MISUSE;
2796
- }
2797
2781
  const result = await f(stmt);
2798
-
2799
- const db = mapStmtToDB.get(stmt);
2800
- mapStmtToDB.delete(stmt);
2782
+ mapStmtToDB.delete(stmt)
2801
2783
 
2802
2784
  // Don't throw on error here. Typically the error has already been
2803
2785
  // thrown and finalize() is part of the cleanup.
@@ -2847,70 +2829,26 @@ function Factory(Module) {
2847
2829
  return async function(zFilename, flags, zVfs) {
2848
2830
  flags = flags || _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_OPEN_CREATE | _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_OPEN_READWRITE;
2849
2831
  zVfs = createUTF8(zVfs);
2850
- Module.ccall('setup_powersync', 'int', []);
2851
-
2852
- const result = await f(zFilename, tmpPtr[0], flags, zVfs);
2853
-
2854
- const db = Module.getValue(tmpPtr[0], '*');
2855
-
2856
- databases.add(db);
2857
- Module._sqlite3_free(zVfs);
2858
-
2859
- Module.ccall('RegisterExtensionFunctions', 'void', ['number'], [db]);
2860
- check(fname, result);
2861
- return db;
2862
- };
2863
- })();
2864
-
2865
- sqlite3.register_table_onchange_hook = function(db, callback) {
2866
- // Register hooks for this DB as a global hook
2867
- // It will call the global handler above
2868
- Module.ccall('register_table_update_hook', 'int', ['number'], [db]);
2869
-
2870
- onTableChangeCallbacks[db] = function(opType, tableNamePtr, rowId) {
2871
- // Need to get the string from the pointer
2872
- // const tableName = Module.UTF8ToString(Module.getValue(tableNamePtr, '*'));
2873
- const memory = new DataView(Module.HEAPU8.buffer);
2874
-
2875
- // Find the null terminator to determine the string length
2876
- let length = 0;
2877
- while (memory.getUint8(tableNamePtr + length) !== 0) {
2878
- length++;
2879
- }
2880
-
2881
- // Extract the string content
2882
- const stringBytes = new Uint8Array(Module.HEAPU8.buffer, tableNamePtr, length);
2883
- const tableName = new TextDecoder().decode(stringBytes);
2832
+ try {
2833
+ // Allow retry operations.
2834
+ const rc = await retry(() => f(zFilename, tmpPtr[0], flags, zVfs));
2884
2835
 
2885
- /**
2886
- * Call the callback inside a setTimeout to avoid blocking SQLite.
2887
- * We use a setTimeout only after fetching data from the heap to avoid
2888
- * accessing memory which has been freed.
2889
- */
2890
- setTimeout(() => callback(opType, tableName, rowId), 0)
2891
- };
2892
- };
2836
+ const db = Module.getValue(tmpPtr[0], '*');
2837
+ databases.add(db);
2893
2838
 
2894
- sqlite3.prepare_v2 = (function() {
2895
- const fname = 'sqlite3_prepare_v2';
2896
- const f = Module.cwrap(fname, ...decl('nnnnn:n'), { async });
2897
- return async function(db, sql) {
2898
- const result = await f(db, sql, -1, tmpPtr[0], tmpPtr[1]);
2899
- check(fname, result, db);
2900
-
2901
- const stmt = Module.getValue(tmpPtr[0], '*');
2902
- if (stmt) {
2903
- mapStmtToDB.set(stmt, db);
2904
- return { stmt, sql: Module.getValue(tmpPtr[1], '*') };
2839
+ Module.ccall('RegisterExtensionFunctions', 'number', ['number'], [db]);
2840
+ check(fname, rc);
2841
+ return db;
2842
+ } finally {
2843
+ Module._sqlite3_free(zVfs);
2905
2844
  }
2906
- return null;
2907
2845
  };
2908
2846
  })();
2909
2847
 
2910
2848
  sqlite3.progress_handler = function(db, nProgressOps, handler, userData) {
2911
2849
  verifyDatabase(db);
2912
- Module.progressHandler(db, nProgressOps, handler, userData);
2913
- };
2850
+ Module.progress_handler(db, nProgressOps, handler, userData);
2851
+ };;
2914
2852
 
2915
2853
  sqlite3.reset = (function() {
2916
2854
  const fname = 'sqlite3_reset';
@@ -3020,9 +2958,27 @@ function Factory(Module) {
3020
2958
  return row;
3021
2959
  };
3022
2960
 
3023
- sqlite3.set_authorizer = function(db, authFunction, userData) {
2961
+ sqlite3.set_authorizer = function(db, xAuth, pApp) {
3024
2962
  verifyDatabase(db);
3025
- const result = Module.setAuthorizer(db, authFunction, userData);
2963
+
2964
+ // Convert SQLite callback arguments to JavaScript-friendly arguments.
2965
+ function cvtArgs(_, iAction, p3, p4, p5, p6) {
2966
+ return [
2967
+ _,
2968
+ iAction,
2969
+ Module.UTF8ToString(p3),
2970
+ Module.UTF8ToString(p4),
2971
+ Module.UTF8ToString(p5),
2972
+ Module.UTF8ToString(p6)
2973
+ ];
2974
+ };
2975
+ function adapt(f) {
2976
+ return f instanceof AsyncFunction ?
2977
+ (async (_, iAction, p3, p4, p5, p6) => f(...cvtArgs(_, iAction, p3, p4, p5, p6))) :
2978
+ ((_, iAction, p3, p4, p5, p6) => f(...cvtArgs(_, iAction, p3, p4, p5, p6)));
2979
+ }
2980
+
2981
+ const result = Module.set_authorizer(db, adapt(xAuth), pApp);
3026
2982
  return check('sqlite3_set_authorizer', result, db);
3027
2983
  };
3028
2984
 
@@ -3032,27 +2988,80 @@ function Factory(Module) {
3032
2988
  return function(stmt) {
3033
2989
  verifyStatement(stmt);
3034
2990
  const result = f(stmt);
3035
- // trace(fname, result);
3036
2991
  return result;
3037
2992
  };
3038
2993
  })();
3039
2994
 
3040
- sqlite3.statements = function(db, sql) {
2995
+ sqlite3.statements = function(db, sql, options = {}) {
2996
+ const prepare = Module.cwrap(
2997
+ 'sqlite3_prepare_v3',
2998
+ 'number',
2999
+ ['number', 'number', 'number', 'number', 'number', 'number'],
3000
+ { async: true });
3001
+
3041
3002
  return (async function*() {
3042
- const str = sqlite3.str_new(db, sql);
3043
- let prepared = { stmt: null, sql: sqlite3.str_value(str) };
3003
+ const onFinally = [];
3044
3004
  try {
3045
- while ((prepared = await sqlite3.prepare_v2(db, prepared.sql))) {
3046
- // console.log(sqlite3.sql(prepared.stmt));
3047
- yield prepared.stmt;
3048
- sqlite3.finalize(prepared.stmt);
3049
- prepared.stmt = null;
3005
+ // Encode SQL string to UTF-8.
3006
+ const utf8 = new TextEncoder().encode(sql);
3007
+
3008
+ // Copy encoded string to WebAssembly memory. The SQLite docs say
3009
+ // zero-termination is a minor optimization so add room for that.
3010
+ // Also add space for the statement handle and SQL tail pointer.
3011
+ const allocSize = utf8.byteLength - (utf8.byteLength % 4) + 12;
3012
+ const pzHead = Module._sqlite3_malloc(allocSize);
3013
+ const pzEnd = pzHead + utf8.byteLength + 1;
3014
+ onFinally.push(() => Module._sqlite3_free(pzHead));
3015
+ Module.HEAPU8.set(utf8, pzHead);
3016
+ Module.HEAPU8[pzEnd - 1] = 0;
3017
+
3018
+ // Use extra space for the statement handle and SQL tail pointer.
3019
+ const pStmt = pzHead + allocSize - 8;
3020
+ const pzTail = pzHead + allocSize - 4;
3021
+
3022
+ // Ensure that statement handles are not leaked.
3023
+ let stmt;
3024
+ function maybeFinalize() {
3025
+ if (stmt && !options.unscoped) {
3026
+ sqlite3.finalize(stmt);
3027
+ }
3028
+ stmt = 0;
3050
3029
  }
3030
+ onFinally.push(maybeFinalize);
3031
+
3032
+ // Loop over statements.
3033
+ Module.setValue(pzTail, pzHead, '*');
3034
+ do {
3035
+ // Reclaim resources for the previous iteration.
3036
+ maybeFinalize();
3037
+
3038
+ // Call sqlite3_prepare_v3() for the next statement.
3039
+ // Allow retry operations.
3040
+ const zTail = Module.getValue(pzTail, '*');
3041
+ const rc = await retry(() => {
3042
+ return prepare(
3043
+ db,
3044
+ zTail,
3045
+ pzEnd - pzTail,
3046
+ options.flags || 0,
3047
+ pStmt,
3048
+ pzTail);
3049
+ });
3050
+
3051
+ if (rc !== _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_OK) {
3052
+ check('sqlite3_prepare_v3', rc, db);
3053
+ }
3054
+
3055
+ stmt = Module.getValue(pStmt, '*');
3056
+ if (stmt) {
3057
+ mapStmtToDB.set(stmt, db);
3058
+ yield stmt;
3059
+ }
3060
+ } while (stmt);
3051
3061
  } finally {
3052
- if (prepared?.stmt) {
3053
- sqlite3.finalize(prepared.stmt);
3062
+ while (onFinally.length) {
3063
+ onFinally.pop()();
3054
3064
  }
3055
- sqlite3.str_finish(str);
3056
3065
  }
3057
3066
  })();
3058
3067
  };
@@ -3062,68 +3071,39 @@ function Factory(Module) {
3062
3071
  const f = Module.cwrap(fname, ...decl('n:n'), { async });
3063
3072
  return async function(stmt) {
3064
3073
  verifyStatement(stmt);
3065
- const result = await f(stmt);
3066
- return check(fname, result, mapStmtToDB.get(stmt), [_sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_ROW, _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_DONE]);
3067
- };
3068
- })();
3069
3074
 
3070
- // Duplicate some of the SQLite dynamic string API but without
3071
- // calling SQLite (except for memory allocation). We need some way
3072
- // to transfer Javascript strings and might as well use an API
3073
- // that mimics the SQLite API.
3074
- let stringId = 0;
3075
- const strings = new Map();
3076
-
3077
- sqlite3.str_new = function(db, s = '') {
3078
- const sBytes = Module.lengthBytesUTF8(s);
3079
- const str = stringId++ & 0xffffffff;
3080
- const data = {
3081
- offset: Module._sqlite3_malloc(sBytes + 1),
3082
- bytes: sBytes
3075
+ // Allow retry operations.
3076
+ const rc = await retry(() => f(stmt));
3077
+
3078
+ return check(fname, rc, mapStmtToDB.get(stmt), [_sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_ROW, _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_DONE]);
3083
3079
  };
3084
- strings.set(str, data);
3085
- Module.stringToUTF8(s, data.offset, data.bytes + 1);
3086
- return str;
3087
- };
3080
+ })();
3088
3081
 
3089
- sqlite3.str_appendall = function(str, s) {
3090
- if (!strings.has(str)) {
3091
- throw new SQLiteError('not a string', _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_MISUSE);
3092
- }
3093
- const data = strings.get(str);
3094
-
3095
- const sBytes = Module.lengthBytesUTF8(s);
3096
- const newBytes = data.bytes + sBytes;
3097
- const newOffset = Module._sqlite3_malloc(newBytes + 1);
3098
- const newArray = Module.HEAPU8.subarray(newOffset, newOffset + newBytes + 1);
3099
- newArray.set(Module.HEAPU8.subarray(data.offset, data.offset + data.bytes));
3100
- Module.stringToUTF8(s, newOffset + data.bytes, sBytes + 1);
3101
-
3102
- Module._sqlite3_free(data.offset);
3103
- data.offset = newOffset;
3104
- data.bytes = newBytes;
3105
- strings.set(str, data);
3082
+ sqlite3.commit_hook = function(db, xCommitHook) {
3083
+ verifyDatabase(db);
3084
+ Module.commit_hook(db, xCommitHook);
3106
3085
  };
3107
3086
 
3108
- sqlite3.str_finish = function(str) {
3109
- if (!strings.has(str)) {
3110
- throw new SQLiteError('not a string', _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_MISUSE);
3111
- }
3112
- const data = strings.get(str);
3113
- strings.delete(str);
3114
- Module._sqlite3_free(data.offset);
3115
- };
3087
+ sqlite3.update_hook = function(db, xUpdateHook) {
3088
+ verifyDatabase(db);
3116
3089
 
3117
- sqlite3.str_value = function(str) {
3118
- if (!strings.has(str)) {
3119
- throw new SQLiteError('not a string', _sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_MISUSE);
3090
+ // Convert SQLite callback arguments to JavaScript-friendly arguments.
3091
+ function cvtArgs(iUpdateType, dbName, tblName, lo32, hi32) {
3092
+ return [
3093
+ iUpdateType,
3094
+ Module.UTF8ToString(dbName),
3095
+ Module.UTF8ToString(tblName),
3096
+ cvt32x2ToBigInt(lo32, hi32)
3097
+ ];
3098
+ };
3099
+ function adapt(f) {
3100
+ return f instanceof AsyncFunction ?
3101
+ (async (iUpdateType, dbName, tblName, lo32, hi32) => f(...cvtArgs(iUpdateType, dbName, tblName, lo32, hi32))) :
3102
+ ((iUpdateType, dbName, tblName, lo32, hi32) => f(...cvtArgs(iUpdateType, dbName, tblName, lo32, hi32)));
3120
3103
  }
3121
- return strings.get(str).offset;
3122
- };
3123
3104
 
3124
- sqlite3.user_data = function(context) {
3125
- return Module.getFunctionUserData(context);
3126
- };
3105
+ Module.update_hook(db, adapt(xUpdateHook));
3106
+ };;
3127
3107
 
3128
3108
  sqlite3.value = function(pValue) {
3129
3109
  const type = sqlite3.value_type(pValue);
@@ -3152,7 +3132,6 @@ function Factory(Module) {
3152
3132
  const nBytes = sqlite3.value_bytes(pValue);
3153
3133
  const address = f(pValue);
3154
3134
  const result = Module.HEAPU8.subarray(address, address + nBytes);
3155
- // trace(fname, result);
3156
3135
  return result;
3157
3136
  };
3158
3137
  })();
@@ -3162,7 +3141,6 @@ function Factory(Module) {
3162
3141
  const f = Module.cwrap(fname, ...decl('n:n'));
3163
3142
  return function(pValue) {
3164
3143
  const result = f(pValue);
3165
- // trace(fname, result);
3166
3144
  return result;
3167
3145
  };
3168
3146
  })();
@@ -3172,7 +3150,6 @@ function Factory(Module) {
3172
3150
  const f = Module.cwrap(fname, ...decl('n:n'));
3173
3151
  return function(pValue) {
3174
3152
  const result = f(pValue);
3175
- // trace(fname, result);
3176
3153
  return result;
3177
3154
  };
3178
3155
  })();
@@ -3182,7 +3159,6 @@ function Factory(Module) {
3182
3159
  const f = Module.cwrap(fname, ...decl('n:n'));
3183
3160
  return function(pValue) {
3184
3161
  const result = f(pValue);
3185
- // trace(fname, result);
3186
3162
  return result;
3187
3163
  };
3188
3164
  })();
@@ -3194,7 +3170,6 @@ function Factory(Module) {
3194
3170
  const lo32 = f(pValue);
3195
3171
  const hi32 = Module.getTempRet0();
3196
3172
  const result = cvt32x2ToBigInt(lo32, hi32);
3197
- // trace(fname, result);
3198
3173
  return result;
3199
3174
  };
3200
3175
  })();
@@ -3204,7 +3179,6 @@ function Factory(Module) {
3204
3179
  const f = Module.cwrap(fname, ...decl('n:s'));
3205
3180
  return function(pValue) {
3206
3181
  const result = f(pValue);
3207
- // trace(fname, result);
3208
3182
  return result;
3209
3183
  };
3210
3184
  })();
@@ -3214,33 +3188,42 @@ function Factory(Module) {
3214
3188
  const f = Module.cwrap(fname, ...decl('n:n'));
3215
3189
  return function(pValue) {
3216
3190
  const result = f(pValue);
3217
- // trace(fname, result);
3218
3191
  return result;
3219
3192
  };
3220
3193
  })();
3221
3194
 
3222
3195
  sqlite3.vfs_register = function(vfs, makeDefault) {
3223
- const result = Module.registerVFS(vfs, makeDefault);
3196
+ const result = Module.vfs_register(vfs, makeDefault);
3224
3197
  return check('sqlite3_vfs_register', result);
3225
3198
  };
3226
3199
 
3227
3200
  function check(fname, result, db = null, allowed = [_sqlite_constants_js__WEBPACK_IMPORTED_MODULE_0__.SQLITE_OK]) {
3228
- // trace(fname, result);
3229
3201
  if (allowed.includes(result)) return result;
3230
3202
  const message = db ? Module.ccall('sqlite3_errmsg', 'string', ['number'], [db]) : fname;
3231
3203
  throw new SQLiteError(message, result);
3232
3204
  }
3233
3205
 
3234
- return sqlite3;
3235
- }
3206
+ // This function is used to automatically retry failed calls that
3207
+ // have pending retry operations that should allow the retry to
3208
+ // succeed.
3209
+ async function retry(f) {
3210
+ let rc;
3211
+ do {
3212
+ // Wait for all pending retry operations to complete. This is
3213
+ // normally empty on the first loop iteration.
3214
+ if (Module.retryOps.length) {
3215
+ await Promise.all(Module.retryOps);
3216
+ Module.retryOps = [];
3217
+ }
3218
+
3219
+ rc = await f();
3220
+
3221
+ // Retry on failure with new pending retry operations.
3222
+ } while (rc && Module.retryOps.length);
3223
+ return rc;
3224
+ }
3236
3225
 
3237
- function trace(...args) {
3238
- // const date = new Date();
3239
- // const t = date.getHours().toString().padStart(2, '0') + ':' +
3240
- // date.getMinutes().toString().padStart(2, '0') + ':' +
3241
- // date.getSeconds().toString().padStart(2, '0') + '.' +
3242
- // date.getMilliseconds().toString().padStart(3, '0');
3243
- // console.debug(t, ...args);
3226
+ return sqlite3;
3244
3227
  }
3245
3228
 
3246
3229
  // Helper function to use a more compact signature specification.
@@ -3490,6 +3473,9 @@ __webpack_require__.r(__webpack_exports__);
3490
3473
  /* harmony export */ SQLITE_OPEN_WAL: () => (/* binding */ SQLITE_OPEN_WAL),
3491
3474
  /* harmony export */ SQLITE_PERM: () => (/* binding */ SQLITE_PERM),
3492
3475
  /* harmony export */ SQLITE_PRAGMA: () => (/* binding */ SQLITE_PRAGMA),
3476
+ /* harmony export */ SQLITE_PREPARE_NORMALIZED: () => (/* binding */ SQLITE_PREPARE_NORMALIZED),
3477
+ /* harmony export */ SQLITE_PREPARE_NO_VTAB: () => (/* binding */ SQLITE_PREPARE_NO_VTAB),
3478
+ /* harmony export */ SQLITE_PREPARE_PERSISTENT: () => (/* binding */ SQLITE_PREPARE_PERSISTENT),
3493
3479
  /* harmony export */ SQLITE_PROTOCOL: () => (/* binding */ SQLITE_PROTOCOL),
3494
3480
  /* harmony export */ SQLITE_RANGE: () => (/* binding */ SQLITE_RANGE),
3495
3481
  /* harmony export */ SQLITE_READ: () => (/* binding */ SQLITE_READ),
@@ -3788,6 +3774,10 @@ const SQLITE_LIMIT_VARIABLE_NUMBER = 9;
3788
3774
  const SQLITE_LIMIT_TRIGGER_DEPTH = 10;
3789
3775
  const SQLITE_LIMIT_WORKER_THREADS = 11;
3790
3776
 
3777
+ const SQLITE_PREPARE_PERSISTENT = 0x01;
3778
+ const SQLITE_PREPARE_NORMALIZED = 0x02;
3779
+ const SQLITE_PREPARE_NO_VTAB = 0x04;
3780
+
3791
3781
  /***/ }),
3792
3782
 
3793
3783
  /***/ "../common/dist/bundle.mjs":