@powersync/web 1.39.0 → 1.39.1

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 (35) hide show
  1. package/dist/index.umd.js +85 -32
  2. package/dist/index.umd.js.map +1 -1
  3. package/dist/worker/SharedSyncImplementation.umd.js +15 -9
  4. package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
  5. package/dist/worker/WASQLiteDB.umd.js +24 -9
  6. package/dist/worker/WASQLiteDB.umd.js.map +1 -1
  7. package/lib/package.json +2 -2
  8. package/lib/src/db/adapters/AsyncWebAdapter.js +1 -1
  9. package/lib/src/db/adapters/AsyncWebAdapter.js.map +1 -1
  10. package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.d.ts +8 -0
  11. package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js +9 -0
  12. package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js.map +1 -1
  13. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +8 -2
  14. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js.map +1 -1
  15. package/lib/src/db/sync/SharedWebStreamingSyncImplementation.d.ts +1 -0
  16. package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +10 -5
  17. package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js.map +1 -1
  18. package/lib/src/worker/db/open-worker-database.d.ts +3 -2
  19. package/lib/src/worker/db/open-worker-database.js +30 -22
  20. package/lib/src/worker/db/open-worker-database.js.map +1 -1
  21. package/lib/src/worker/errors.d.ts +2 -0
  22. package/lib/src/worker/errors.js +7 -0
  23. package/lib/src/worker/errors.js.map +1 -0
  24. package/lib/src/worker/sync/SharedSyncImplementation.d.ts +1 -0
  25. package/lib/src/worker/sync/SharedSyncImplementation.js +2 -1
  26. package/lib/src/worker/sync/SharedSyncImplementation.js.map +1 -1
  27. package/lib/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +3 -3
  29. package/src/db/adapters/AsyncWebAdapter.ts +1 -1
  30. package/src/db/adapters/wa-sqlite/RawSqliteConnection.ts +10 -0
  31. package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +24 -9
  32. package/src/db/sync/SharedWebStreamingSyncImplementation.ts +17 -11
  33. package/src/worker/db/open-worker-database.ts +34 -22
  34. package/src/worker/errors.ts +9 -0
  35. package/src/worker/sync/SharedSyncImplementation.ts +3 -1
package/dist/index.umd.js CHANGED
@@ -4923,7 +4923,7 @@ function readWritePoolState(writer, readers) {
4923
4923
  let timeout = null;
4924
4924
  let release;
4925
4925
  if (options?.timeoutMs) {
4926
- timeout = setTimeout(() => abortController.abort, options.timeoutMs);
4926
+ timeout = setTimeout(() => abortController.abort('requesting database timed out'), options.timeoutMs);
4927
4927
  }
4928
4928
  try {
4929
4929
  if (allowReadOnly) {
@@ -5642,12 +5642,21 @@ class DatabaseServer {
5642
5642
 
5643
5643
  __webpack_require__.r(__webpack_exports__);
5644
5644
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5645
- /* harmony export */ RawSqliteConnection: () => (/* binding */ RawSqliteConnection)
5645
+ /* harmony export */ RawSqliteConnection: () => (/* binding */ RawSqliteConnection),
5646
+ /* harmony export */ maxPathNameLength: () => (/* binding */ maxPathNameLength)
5646
5647
  /* harmony export */ });
5647
5648
  /* harmony import */ var _journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @journeyapps/wa-sqlite */ "@journeyapps/wa-sqlite");
5648
5649
  /* harmony import */ var _vfs_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vfs.js */ "./lib/src/db/adapters/wa-sqlite/vfs.js");
5649
5650
 
5650
5651
 
5652
+ /**
5653
+ * The maximum length of a db filename we support.
5654
+ *
5655
+ * We configure the same on WA-SQLite (which otherwise defaults to a maximum length of 64). We don't want to support
5656
+ * very long path names as Safari maps OPFS files directly to OS files, and APFS has a 255-byte filename limit. Since
5657
+ * some VFS append additional characters for pooled file access handles, we want to stay well below that.
5658
+ */
5659
+ const maxPathNameLength = 128;
5651
5660
  /**
5652
5661
  * A small wrapper around WA-sqlite to help with opening databases and running statements by preparing them internally.
5653
5662
  *
@@ -5680,6 +5689,7 @@ class RawSqliteConnection {
5680
5689
  }
5681
5690
  async openSQLiteAPI() {
5682
5691
  const { module, vfs } = await (0,_vfs_js__WEBPACK_IMPORTED_MODULE_1__.loadModuleAndVfs)(this.options);
5692
+ vfs.mxPathname = maxPathNameLength;
5683
5693
  const sqlite3 = (0,_journeyapps_wa_sqlite__WEBPACK_IMPORTED_MODULE_0__.Factory)(module);
5684
5694
  sqlite3.vfs_register(vfs, true);
5685
5695
  /**
@@ -5812,6 +5822,8 @@ __webpack_require__.r(__webpack_exports__);
5812
5822
  /* harmony import */ var _DatabaseClient_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./DatabaseClient.js */ "./lib/src/db/adapters/wa-sqlite/DatabaseClient.js");
5813
5823
  /* harmony import */ var _shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../shared/tab_close_signal.js */ "./lib/src/shared/tab_close_signal.js");
5814
5824
  /* harmony import */ var _AsyncWebAdapter_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../AsyncWebAdapter.js */ "./lib/src/db/adapters/AsyncWebAdapter.js");
5825
+ /* harmony import */ var _RawSqliteConnection_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./RawSqliteConnection.js */ "./lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js");
5826
+
5815
5827
 
5816
5828
 
5817
5829
 
@@ -5888,8 +5900,8 @@ class WASQLiteOpenFactory {
5888
5900
  cacheSizeKb,
5889
5901
  flags: this.resolvedFlags,
5890
5902
  encryptionKey
5891
- }))
5892
- : (0,_worker_db_open_worker_database_js__WEBPACK_IMPORTED_MODULE_2__.openWorkerDatabasePort)(this.options.dbFilename, enableMultiTabs, optionsDbWorker, this.waOptions.vfs);
5903
+ }), this.logger)
5904
+ : (0,_worker_db_open_worker_database_js__WEBPACK_IMPORTED_MODULE_2__.openWorkerDatabasePort)(this.options.dbFilename, enableMultiTabs, optionsDbWorker, this.waOptions.vfs, this.logger);
5893
5905
  const source = comlink__WEBPACK_IMPORTED_MODULE_1__.wrap(workerPort);
5894
5906
  const closeSignal = new AbortController();
5895
5907
  const connection = await source.connect({
@@ -5956,6 +5968,11 @@ function assertValidWASQLiteOpenFactoryOptions(options) {
5956
5968
  throw new Error(`Invalid configuration: The 'useWebWorker' flag must be true when using an OPFS-based VFS (${vfs}).`);
5957
5969
  }
5958
5970
  }
5971
+ // Account for the fact that SQLite might append -journal suffixes
5972
+ const maxLength = _RawSqliteConnection_js__WEBPACK_IMPORTED_MODULE_10__.maxPathNameLength - 16;
5973
+ if (options.dbFilename.length > maxLength) {
5974
+ throw new Error(`dbFilename too long (max length is ${maxLength})`);
5975
+ }
5959
5976
  }
5960
5977
 
5961
5978
 
@@ -6262,6 +6279,8 @@ __webpack_require__.r(__webpack_exports__);
6262
6279
  /* harmony import */ var _adapters_web_sql_flags_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../adapters/web-sql-flags.js */ "./lib/src/db/adapters/web-sql-flags.js");
6263
6280
  /* harmony import */ var _WebStreamingSyncImplementation_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./WebStreamingSyncImplementation.js */ "./lib/src/db/sync/WebStreamingSyncImplementation.js");
6264
6281
  /* harmony import */ var _shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../shared/tab_close_signal.js */ "./lib/src/shared/tab_close_signal.js");
6282
+ /* harmony import */ var _worker_errors_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../worker/errors.js */ "./lib/src/worker/errors.js");
6283
+
6265
6284
 
6266
6285
 
6267
6286
 
@@ -6367,21 +6386,21 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
6367
6386
  const syncWorker = options.sync?.worker;
6368
6387
  if (syncWorker) {
6369
6388
  if (typeof syncWorker === 'function') {
6370
- this.messagePort = syncWorker(resolvedWorkerOptions).port;
6389
+ this.messagePort = this.workerPort(syncWorker(resolvedWorkerOptions));
6371
6390
  }
6372
6391
  else {
6373
- this.messagePort = new SharedWorker(`${syncWorker}`, {
6392
+ this.messagePort = this.workerPort(new SharedWorker(`${syncWorker}`, {
6374
6393
  /* @vite-ignore */
6375
6394
  name: `shared-sync-${this.webOptions.identifier}`
6376
- }).port;
6395
+ }));
6377
6396
  }
6378
6397
  }
6379
6398
  else {
6380
- this.messagePort = new SharedWorker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("lib_src_worker_sync_SharedSyncImplementation_worker_js"), __webpack_require__.b), {
6399
+ this.messagePort = this.workerPort(new SharedWorker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("lib_src_worker_sync_SharedSyncImplementation_worker_js"), __webpack_require__.b), {
6381
6400
  /* @vite-ignore */
6382
6401
  name: `shared-sync-${this.webOptions.identifier}`,
6383
6402
  type: undefined
6384
- }).port;
6403
+ }));
6385
6404
  }
6386
6405
  /**
6387
6406
  * Pass along any sync status updates to this listener
@@ -6406,6 +6425,10 @@ class SharedWebStreamingSyncImplementation extends _WebStreamingSyncImplementati
6406
6425
  */
6407
6426
  this.isInitialized = this._init();
6408
6427
  }
6428
+ workerPort(worker) {
6429
+ (0,_worker_errors_js__WEBPACK_IMPORTED_MODULE_6__.logWorkerErrors)(worker, this.logger);
6430
+ return worker.port;
6431
+ }
6409
6432
  async _init() {
6410
6433
  /**
6411
6434
  * The general flow of initialization is:
@@ -6833,23 +6856,27 @@ __webpack_require__.r(__webpack_exports__);
6833
6856
  /* harmony export */ });
6834
6857
  /* harmony import */ var comlink__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! comlink */ "comlink");
6835
6858
  /* harmony import */ var _db_adapters_wa_sqlite_vfs_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../db/adapters/wa-sqlite/vfs.js */ "./lib/src/db/adapters/wa-sqlite/vfs.js");
6859
+ /* harmony import */ var _errors_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../errors.js */ "./lib/src/worker/errors.js");
6860
+
6836
6861
 
6837
6862
 
6838
6863
  /**
6839
6864
  * Opens a shared or dedicated worker which exposes opening of database connections
6840
6865
  */
6841
- function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, worker = '', vfs) {
6866
+ function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, worker = '', vfs, logger) {
6842
6867
  const needsDedicated = vfs && (0,_db_adapters_wa_sqlite_vfs_js__WEBPACK_IMPORTED_MODULE_1__.vfsRequiresDedicatedWorkers)(vfs);
6868
+ let resolvedWorker;
6843
6869
  if (worker) {
6844
- return !needsDedicated && multipleTabs
6845
- ? new SharedWorker(`${worker}`, {
6846
- /* @vite-ignore */
6847
- name: `shared-DB-worker-${workerIdentifier}`
6848
- }).port
6849
- : new Worker(`${worker}`, {
6850
- /* @vite-ignore */
6851
- name: `DB-worker-${workerIdentifier}`
6852
- });
6870
+ resolvedWorker =
6871
+ !needsDedicated && multipleTabs
6872
+ ? new SharedWorker(`${worker}`, {
6873
+ /* @vite-ignore */
6874
+ name: `shared-DB-worker-${workerIdentifier}`
6875
+ })
6876
+ : new Worker(`${worker}`, {
6877
+ /* @vite-ignore */
6878
+ name: `DB-worker-${workerIdentifier}`
6879
+ });
6853
6880
  }
6854
6881
  else {
6855
6882
  /**
@@ -6858,18 +6885,20 @@ function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, worker =
6858
6885
  * This enables multi tab support by default, but falls back if SharedWorker is not available
6859
6886
  * (in the case of Android)
6860
6887
  */
6861
- return !needsDedicated && multipleTabs
6862
- ? new SharedWorker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("lib_src_worker_db_WASQLiteDB_worker_js"), __webpack_require__.b), {
6863
- /* @vite-ignore */
6864
- name: `shared-DB-worker-${workerIdentifier}`,
6865
- type: undefined
6866
- }).port
6867
- : new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("lib_src_worker_db_WASQLiteDB_worker_js"), __webpack_require__.b), {
6868
- /* @vite-ignore */
6869
- name: `DB-worker-${workerIdentifier}`,
6870
- type: undefined
6871
- });
6888
+ resolvedWorker =
6889
+ !needsDedicated && multipleTabs
6890
+ ? new SharedWorker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("lib_src_worker_db_WASQLiteDB_worker_js"), __webpack_require__.b), {
6891
+ /* @vite-ignore */
6892
+ name: `shared-DB-worker-${workerIdentifier}`,
6893
+ type: undefined
6894
+ })
6895
+ : new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("lib_src_worker_db_WASQLiteDB_worker_js"), __webpack_require__.b), {
6896
+ /* @vite-ignore */
6897
+ name: `DB-worker-${workerIdentifier}`,
6898
+ type: undefined
6899
+ });
6872
6900
  }
6901
+ return resolveWorkerDatabasePortFactory(() => resolvedWorker, logger);
6873
6902
  }
6874
6903
  /**
6875
6904
  * @returns A function which allows for opening database connections inside
@@ -6878,8 +6907,11 @@ function openWorkerDatabasePort(workerIdentifier, multipleTabs = true, worker =
6878
6907
  function getWorkerDatabaseOpener(workerIdentifier, multipleTabs = true, worker = '') {
6879
6908
  return comlink__WEBPACK_IMPORTED_MODULE_0__.wrap(openWorkerDatabasePort(workerIdentifier, multipleTabs, worker));
6880
6909
  }
6881
- function resolveWorkerDatabasePortFactory(worker) {
6910
+ function resolveWorkerDatabasePortFactory(worker, logger) {
6882
6911
  const workerInstance = worker();
6912
+ if (logger) {
6913
+ (0,_errors_js__WEBPACK_IMPORTED_MODULE_2__.logWorkerErrors)(workerInstance, logger);
6914
+ }
6883
6915
  return isSharedWorker(workerInstance) ? workerInstance.port : workerInstance;
6884
6916
  }
6885
6917
  function isSharedWorker(worker) {
@@ -6887,6 +6919,26 @@ function isSharedWorker(worker) {
6887
6919
  }
6888
6920
 
6889
6921
 
6922
+ /***/ },
6923
+
6924
+ /***/ "./lib/src/worker/errors.js"
6925
+ /*!**********************************!*\
6926
+ !*** ./lib/src/worker/errors.js ***!
6927
+ \**********************************/
6928
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
6929
+
6930
+ __webpack_require__.r(__webpack_exports__);
6931
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
6932
+ /* harmony export */ logWorkerErrors: () => (/* binding */ logWorkerErrors)
6933
+ /* harmony export */ });
6934
+ function logWorkerErrors(worker, logger) {
6935
+ function logError(event) {
6936
+ logger.error('Error in database or sync worker, this likely disrupts PowerSync.', event.error);
6937
+ }
6938
+ worker.addEventListener('error', logError);
6939
+ }
6940
+
6941
+
6890
6942
  /***/ },
6891
6943
 
6892
6944
  /***/ "./lib/src/worker/sync/AbstractSharedSyncClientProvider.js"
@@ -7114,6 +7166,7 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
7114
7166
  syncStatus;
7115
7167
  broadCastLogger;
7116
7168
  database = this.generateReconnectableDatabase();
7169
+ sharedCloseSignal = (0,_shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_6__.generateTabCloseSignal)();
7117
7170
  constructor() {
7118
7171
  super();
7119
7172
  this.ports = [];
@@ -7447,7 +7500,7 @@ class SharedSyncImplementation extends _powersync_common__WEBPACK_IMPORTED_MODUL
7447
7500
  });
7448
7501
  const remote = comlink__WEBPACK_IMPORTED_MODULE_1__.wrap(workerPort);
7449
7502
  const identifier = this.syncParams.dbParams.dbFilename;
7450
- const clientLockName = await (0,_shared_tab_close_signal_js__WEBPACK_IMPORTED_MODULE_6__.generateTabCloseSignal)();
7503
+ const clientLockName = await this.sharedCloseSignal;
7451
7504
  /**
7452
7505
  * The open could fail if the tab is closed while we're busy opening the database.
7453
7506
  * This operation is typically executed inside an exclusive portMutex lock.