@powersync/web 2.4.2 → 2.5.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 (49) hide show
  1. package/dist/index.react_native_web.js +64 -6
  2. package/dist/index.react_native_web.js.map +1 -1
  3. package/dist/worker/{AccessHandlePoolVFS-BPUHfZME.js → AccessHandlePoolVFS-B9CKqcQ3.js} +2 -2
  4. package/dist/worker/AccessHandlePoolVFS-B9CKqcQ3.js.map +1 -0
  5. package/dist/worker/FacadeVFS-d1ZDvud7.js.map +1 -1
  6. package/dist/worker/IDBBatchAtomicVFS-BfRzbRoV.js +2 -0
  7. package/dist/worker/IDBBatchAtomicVFS-BfRzbRoV.js.map +1 -0
  8. package/dist/worker/MemoryVFS-DVJL5F8j.js.map +1 -1
  9. package/dist/worker/OPFSCoopSyncVFS-BxXAVpVQ.js +2 -0
  10. package/dist/worker/OPFSCoopSyncVFS-BxXAVpVQ.js.map +1 -0
  11. package/dist/worker/OPFSWriteAheadVFS-DuqXaOct.js +2 -0
  12. package/dist/worker/OPFSWriteAheadVFS-DuqXaOct.js.map +1 -0
  13. package/dist/worker/mc-wa-sqlite-PubB6u8c.js.map +1 -1
  14. package/dist/worker/mc-wa-sqlite-async-DJG_ANKO.js.map +1 -1
  15. package/dist/worker/wa-sqlite-D1_4mGs8.js.map +1 -1
  16. package/dist/worker/wa-sqlite-async-BxkwNY-2.js.map +1 -1
  17. package/dist/worker/worker.js +1 -1
  18. package/dist/worker/worker.js.map +1 -1
  19. package/lib/db/PowerSyncDatabase.js +6 -2
  20. package/lib/db/PowerSyncDatabase.js.map +1 -1
  21. package/lib/db/sync/SharedWebStreamingSyncImplementation.d.ts +1 -0
  22. package/lib/db/sync/SharedWebStreamingSyncImplementation.js +17 -3
  23. package/lib/db/sync/SharedWebStreamingSyncImplementation.js.map +1 -1
  24. package/lib/db/sync/WebStreamingSyncImplementation.d.ts +8 -1
  25. package/lib/db/sync/WebStreamingSyncImplementation.js +14 -0
  26. package/lib/db/sync/WebStreamingSyncImplementation.js.map +1 -1
  27. package/lib/devtools/index.d.ts +7 -0
  28. package/lib/devtools/index.js +8 -0
  29. package/lib/devtools/index.js.map +1 -0
  30. package/lib/devtools/registry.d.ts +12 -0
  31. package/lib/devtools/registry.js +42 -0
  32. package/lib/devtools/registry.js.map +1 -0
  33. package/lib/worker/sync/BroadcastLogger.d.ts +1 -4
  34. package/lib/worker/sync/BroadcastLogger.js +14 -15
  35. package/lib/worker/sync/BroadcastLogger.js.map +1 -1
  36. package/package.json +12 -8
  37. package/src/db/PowerSyncDatabase.ts +6 -2
  38. package/src/db/sync/SharedWebStreamingSyncImplementation.ts +22 -4
  39. package/src/db/sync/WebStreamingSyncImplementation.ts +18 -0
  40. package/src/devtools/index.ts +7 -0
  41. package/src/devtools/registry.ts +53 -0
  42. package/src/worker/sync/BroadcastLogger.ts +15 -15
  43. package/dist/worker/AccessHandlePoolVFS-BPUHfZME.js.map +0 -1
  44. package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js +0 -2
  45. package/dist/worker/IDBBatchAtomicVFS-DbkDb777.js.map +0 -1
  46. package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js +0 -2
  47. package/dist/worker/OPFSCoopSyncVFS-BgTiWPfa.js.map +0 -1
  48. package/dist/worker/OPFSWriteAheadVFS-BW9pqSNn.js +0 -2
  49. package/dist/worker/OPFSWriteAheadVFS-BW9pqSNn.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { DBAdapter, LockContext, LogLevels, queryResultWithoutRows, BaseObserver } from '@powersync/common';
2
2
  export * from '@powersync/common';
3
3
  import * as Comlink from 'comlink';
4
- import { Mutex, ConnectionClosedError, Semaphore, LockType, AbstractRemote, AbstractStreamingSyncImplementation, BasePowerSyncDatabase, openDatabase } from '@powersync/shared-internals';
4
+ import { Mutex, ConnectionClosedError, Semaphore, LockType, AbstractRemote, AbstractStreamingSyncImplementation, serializeErrorForRelay, BasePowerSyncDatabase, openDatabase } from '@powersync/shared-internals';
5
5
  import { Factory, SQLITE_ROW } from '@journeyapps/wa-sqlite';
6
6
 
7
7
  /**
@@ -1683,10 +1683,24 @@ class WebRemote extends AbstractRemote {
1683
1683
  let websockets;
1684
1684
 
1685
1685
  class WebStreamingSyncImplementation extends AbstractStreamingSyncImplementation {
1686
+ diagnosticsChannel;
1686
1687
  constructor(options) {
1687
1688
  // Super will store and provide default values for options
1688
1689
  super(options);
1689
1690
  }
1691
+ /**
1692
+ * Broadcasts a core diagnostics event on a same-origin channel for diagnostics tooling to consume.
1693
+ * The channel reaches the page even when sync runs in a shared worker.
1694
+ */
1695
+ emitDiagnostics(event) {
1696
+ this.diagnosticsChannel ??= new BroadcastChannel('powersync-diagnostics-events');
1697
+ this.diagnosticsChannel.postMessage(event);
1698
+ }
1699
+ async dispose() {
1700
+ await super.dispose();
1701
+ this.diagnosticsChannel?.close();
1702
+ this.diagnosticsChannel = undefined;
1703
+ }
1690
1704
  get webOptions() {
1691
1705
  return this.options;
1692
1706
  }
@@ -1731,11 +1745,24 @@ class SharedSyncClientProvider extends AbstractSharedSyncClientProvider {
1731
1745
  const { port } = await this.webDB.shareConnection();
1732
1746
  return Comlink.transfer(port, [port]);
1733
1747
  }
1748
+ async #relay(action) {
1749
+ try {
1750
+ return await action();
1751
+ }
1752
+ catch (ex) {
1753
+ /**
1754
+ * Connector callbacks run in this tab and their rejection crosses the
1755
+ * MessagePort to the sync worker, so serialize it here, where the error
1756
+ * originates, before Comlink's error transfer can drop custom fields.
1757
+ */
1758
+ throw serializeErrorForRelay(ex);
1759
+ }
1760
+ }
1734
1761
  invalidateCredentials() {
1735
1762
  this.options.remote.invalidateCredentials();
1736
1763
  }
1737
1764
  async fetchCredentials() {
1738
- const credentials = await this.options.remote.getCredentials();
1765
+ const credentials = await this.#relay(() => this.options.remote.getCredentials());
1739
1766
  if (credentials == null) {
1740
1767
  return null;
1741
1768
  }
@@ -1755,10 +1782,10 @@ class SharedSyncClientProvider extends AbstractSharedSyncClientProvider {
1755
1782
  * Don't return anything here, just incase something which is not
1756
1783
  * serializable is returned from the `uploadCrud` function.
1757
1784
  */
1758
- await this.options.uploadCrud();
1785
+ await this.#relay(() => this.options.uploadCrud());
1759
1786
  }
1760
1787
  async postCheckpointRequest(clientId, requestId) {
1761
- return await this.options.postCheckpointRequest(clientId, requestId);
1788
+ return await this.#relay(async () => (await this.options.postCheckpointRequest(clientId, requestId)) ?? null);
1762
1789
  }
1763
1790
  get logger() {
1764
1791
  return this.options.logger;
@@ -1963,6 +1990,34 @@ class TabLocalStreamingSyncImplementation extends WebStreamingSyncImplementation
1963
1990
  }
1964
1991
  }
1965
1992
 
1993
+ /**
1994
+ * Live database instances in this page, for development tooling.
1995
+ *
1996
+ * Every {@link WebPowerSyncDatabase} registers itself when constructed and leaves when closed, so a
1997
+ * tool that runs in the same page (for example the diagnostics Vite plugin's injected agent) can find
1998
+ * the app's databases without the app wiring anything up. The set holds only instances that already
1999
+ * exist, so it adds nothing to a production bundle beyond the references themselves.
2000
+ */
2001
+ class DatabaseRegistry extends BaseObserver {
2002
+ databases = new Set();
2003
+ notify() {
2004
+ const snapshot = [...this.databases];
2005
+ this.iterateListeners((listener) => listener.databasesChanged?.(snapshot));
2006
+ }
2007
+ }
2008
+ const registry = new DatabaseRegistry();
2009
+ /** @internal Called by the database constructor. */
2010
+ function registerDatabase(db) {
2011
+ registry.databases.add(db);
2012
+ registry.notify();
2013
+ }
2014
+ /** @internal Called when the database closes. */
2015
+ function unregisterDatabase(db) {
2016
+ if (registry.databases.delete(db)) {
2017
+ registry.notify();
2018
+ }
2019
+ }
2020
+
1966
2021
  /**
1967
2022
  * @internal Use {@link PowerSyncDatabase} instead, this class is only used by other SDKs also needing web support.
1968
2023
  */
@@ -1975,6 +2030,8 @@ class WebPowerSyncDatabase extends BasePowerSyncDatabase {
1975
2030
  super(options);
1976
2031
  this.resolvedOpenOptions = resolvedOpenOptions;
1977
2032
  this.enableBroadcastLogs = options.broadcastLogs ?? true;
2033
+ // Lets development tooling in this page find the live databases.
2034
+ registerDatabase(this);
1978
2035
  }
1979
2036
  async _initialize() {
1980
2037
  if (this.database instanceof AsyncDbAdapter) {
@@ -2015,11 +2072,12 @@ class WebPowerSyncDatabase extends BasePowerSyncDatabase {
2015
2072
  * By default the sync stream client is only disconnected if
2016
2073
  * multiple tabs are not enabled.
2017
2074
  */
2018
- close(options) {
2019
- return super.close({
2075
+ async close(options) {
2076
+ await super.close({
2020
2077
  // Don't disconnect by default if multiple tabs are enabled
2021
2078
  disconnect: options?.disconnect ?? !this.resolvedOpenOptions.enableMultiTabs
2022
2079
  });
2080
+ unregisterDatabase(this);
2023
2081
  }
2024
2082
  async loadVersion() {
2025
2083
  if (this.resolvedOpenOptions.ssrMode) {