@powersync/web 1.35.0 → 1.37.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 (91) hide show
  1. package/dist/index.umd.js +1126 -1231
  2. package/dist/index.umd.js.map +1 -1
  3. package/dist/worker/SharedSyncImplementation.umd.js +599 -3086
  4. package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
  5. package/dist/worker/WASQLiteDB.umd.js +860 -868
  6. package/dist/worker/WASQLiteDB.umd.js.map +1 -1
  7. package/lib/package.json +2 -3
  8. package/lib/src/db/PowerSyncDatabase.d.ts +1 -2
  9. package/lib/src/db/PowerSyncDatabase.js +3 -4
  10. package/lib/src/db/adapters/AsyncWebAdapter.d.ts +40 -0
  11. package/lib/src/db/adapters/AsyncWebAdapter.js +69 -0
  12. package/lib/src/db/adapters/SSRDBAdapter.d.ts +1 -2
  13. package/lib/src/db/adapters/SSRDBAdapter.js +5 -6
  14. package/lib/src/db/adapters/wa-sqlite/ConcurrentConnection.d.ts +56 -0
  15. package/lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js +121 -0
  16. package/lib/src/db/adapters/wa-sqlite/DatabaseClient.d.ts +54 -0
  17. package/lib/src/db/adapters/wa-sqlite/DatabaseClient.js +227 -0
  18. package/lib/src/db/adapters/wa-sqlite/DatabaseServer.d.ts +47 -0
  19. package/lib/src/db/adapters/wa-sqlite/DatabaseServer.js +146 -0
  20. package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.d.ts +46 -0
  21. package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js +147 -0
  22. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.d.ts +14 -6
  23. package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +66 -39
  24. package/lib/src/db/adapters/wa-sqlite/vfs.d.ts +61 -0
  25. package/lib/src/db/adapters/wa-sqlite/vfs.js +91 -0
  26. package/lib/src/db/adapters/web-sql-flags.d.ts +5 -0
  27. package/lib/src/db/sync/SSRWebStreamingSyncImplementation.d.ts +1 -2
  28. package/lib/src/db/sync/SSRWebStreamingSyncImplementation.js +2 -3
  29. package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +4 -19
  30. package/lib/src/index.d.ts +1 -4
  31. package/lib/src/index.js +1 -4
  32. package/lib/src/shared/tab_close_signal.d.ts +11 -0
  33. package/lib/src/shared/tab_close_signal.js +26 -0
  34. package/lib/src/worker/db/MultiDatabaseServer.d.ts +17 -0
  35. package/lib/src/worker/db/MultiDatabaseServer.js +86 -0
  36. package/lib/src/worker/db/WASQLiteDB.worker.js +9 -48
  37. package/lib/src/worker/db/open-worker-database.d.ts +3 -3
  38. package/lib/src/worker/db/open-worker-database.js +1 -1
  39. package/lib/src/worker/sync/SharedSyncImplementation.d.ts +5 -6
  40. package/lib/src/worker/sync/SharedSyncImplementation.js +92 -54
  41. package/lib/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +3 -4
  43. package/src/db/PowerSyncDatabase.ts +3 -3
  44. package/src/db/adapters/AsyncWebAdapter.ts +91 -0
  45. package/src/db/adapters/SSRDBAdapter.ts +7 -7
  46. package/src/db/adapters/wa-sqlite/ConcurrentConnection.ts +137 -0
  47. package/src/db/adapters/wa-sqlite/DatabaseClient.ts +325 -0
  48. package/src/db/adapters/wa-sqlite/DatabaseServer.ts +201 -0
  49. package/src/db/adapters/wa-sqlite/RawSqliteConnection.ts +191 -0
  50. package/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.ts +87 -43
  51. package/src/db/adapters/wa-sqlite/vfs.ts +112 -0
  52. package/src/db/adapters/web-sql-flags.ts +6 -0
  53. package/src/db/sync/SSRWebStreamingSyncImplementation.ts +2 -3
  54. package/src/db/sync/SharedWebStreamingSyncImplementation.ts +4 -20
  55. package/src/index.ts +1 -4
  56. package/src/shared/tab_close_signal.ts +28 -0
  57. package/src/worker/db/MultiDatabaseServer.ts +104 -0
  58. package/src/worker/db/WASQLiteDB.worker.ts +10 -57
  59. package/src/worker/db/open-worker-database.ts +3 -3
  60. package/src/worker/sync/SharedSyncImplementation.ts +118 -58
  61. package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapp-89f0ba.index.umd.js +0 -1878
  62. package/dist/_journeyapps_wa-sqlite-_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapp-89f0ba.index.umd.js.map +0 -1
  63. package/dist/_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapps_wa-sqlite_src_example-97ebe9.index.umd.js +0 -555
  64. package/dist/_journeyapps_wa-sqlite_src_examples_AccessHandlePoolVFS_js-_journeyapps_wa-sqlite_src_example-97ebe9.index.umd.js.map +0 -1
  65. package/lib/src/db/adapters/AbstractWebSQLOpenFactory.d.ts +0 -17
  66. package/lib/src/db/adapters/AbstractWebSQLOpenFactory.js +0 -33
  67. package/lib/src/db/adapters/AsyncDatabaseConnection.d.ts +0 -49
  68. package/lib/src/db/adapters/AsyncDatabaseConnection.js +0 -1
  69. package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.d.ts +0 -109
  70. package/lib/src/db/adapters/LockedAsyncDatabaseAdapter.js +0 -401
  71. package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.d.ts +0 -59
  72. package/lib/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.js +0 -147
  73. package/lib/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.d.ts +0 -12
  74. package/lib/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.js +0 -19
  75. package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.d.ts +0 -155
  76. package/lib/src/db/adapters/wa-sqlite/WASQLiteConnection.js +0 -401
  77. package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.d.ts +0 -32
  78. package/lib/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.js +0 -49
  79. package/lib/src/worker/db/SharedWASQLiteConnection.d.ts +0 -42
  80. package/lib/src/worker/db/SharedWASQLiteConnection.js +0 -90
  81. package/lib/src/worker/db/WorkerWASQLiteConnection.d.ts +0 -9
  82. package/lib/src/worker/db/WorkerWASQLiteConnection.js +0 -12
  83. package/src/db/adapters/AbstractWebSQLOpenFactory.ts +0 -48
  84. package/src/db/adapters/AsyncDatabaseConnection.ts +0 -55
  85. package/src/db/adapters/LockedAsyncDatabaseAdapter.ts +0 -490
  86. package/src/db/adapters/WorkerWrappedAsyncDatabaseConnection.ts +0 -201
  87. package/src/db/adapters/wa-sqlite/InternalWASQLiteDBAdapter.ts +0 -23
  88. package/src/db/adapters/wa-sqlite/WASQLiteConnection.ts +0 -497
  89. package/src/db/adapters/wa-sqlite/WASQLiteDBAdapter.ts +0 -86
  90. package/src/worker/db/SharedWASQLiteConnection.ts +0 -131
  91. package/src/worker/db/WorkerWASQLiteConnection.ts +0 -14
@@ -1,201 +0,0 @@
1
- import { BaseObserver, ConnectionClosedError } from '@powersync/common';
2
- import * as Comlink from 'comlink';
3
- import {
4
- AsyncDatabaseConnection,
5
- OnTableChangeCallback,
6
- OpenAsyncDatabaseConnection,
7
- ProxiedQueryResult
8
- } from './AsyncDatabaseConnection.js';
9
- import { ResolvedWebSQLOpenOptions } from './web-sql-flags.js';
10
-
11
- export type SharedConnectionWorker = {
12
- identifier: string;
13
- port: MessagePort;
14
- };
15
-
16
- export type WrappedWorkerConnectionOptions<Config extends ResolvedWebSQLOpenOptions = ResolvedWebSQLOpenOptions> = {
17
- baseConnection: AsyncDatabaseConnection;
18
- identifier: string;
19
- remoteCanCloseUnexpectedly: boolean;
20
- /**
21
- * Need a remote in order to keep a reference to the Proxied worker
22
- */
23
- remote: Comlink.Remote<OpenAsyncDatabaseConnection<Config>>;
24
- onClose?: () => void;
25
- };
26
-
27
- export type WorkerWrappedAsyncDatabaseConnectionListener = {
28
- closing: () => void;
29
- };
30
- /**
31
- * Wraps a provided instance of {@link AsyncDatabaseConnection}, providing necessary proxy
32
- * functions for worker listeners.
33
- */
34
- export class WorkerWrappedAsyncDatabaseConnection<Config extends ResolvedWebSQLOpenOptions = ResolvedWebSQLOpenOptions>
35
- extends BaseObserver<WorkerWrappedAsyncDatabaseConnectionListener>
36
- implements AsyncDatabaseConnection
37
- {
38
- protected lockAbortController = new AbortController();
39
- protected notifyRemoteClosed: AbortController | undefined;
40
-
41
- constructor(protected options: WrappedWorkerConnectionOptions<Config>) {
42
- super();
43
-
44
- if (options.remoteCanCloseUnexpectedly) {
45
- this.notifyRemoteClosed = new AbortController();
46
- }
47
- }
48
-
49
- protected get baseConnection() {
50
- return this.options.baseConnection;
51
- }
52
-
53
- init(): Promise<void> {
54
- return this.baseConnection.init();
55
- }
56
-
57
- /**
58
- * Marks the remote as closed.
59
- *
60
- * This can sometimes happen outside of our control, e.g. when a shared worker requests a connection from a tab. When
61
- * it happens, all methods on the {@link baseConnection} would never resolve. To avoid livelocks in this scenario, we
62
- * throw on all outstanding promises and forbid new calls.
63
- */
64
- markRemoteClosed() {
65
- // Can non-null assert here because this function is only supposed to be called when remoteCanCloseUnexpectedly was
66
- // set.
67
- this.notifyRemoteClosed!.abort();
68
- }
69
-
70
- markHold(): Promise<string> {
71
- return this.withRemote(() => this.baseConnection.markHold());
72
- }
73
-
74
- releaseHold(holdId: string): Promise<void> {
75
- return this.withRemote(() => this.baseConnection.releaseHold(holdId));
76
- }
77
-
78
- isAutoCommit(): Promise<boolean> {
79
- return this.withRemote(() => this.baseConnection.isAutoCommit());
80
- }
81
-
82
- private withRemote<T>(workerPromise: () => Promise<T>, fireActionOnAbort = false): Promise<T> {
83
- const controller = this.notifyRemoteClosed;
84
- if (controller) {
85
- return new Promise((resolve, reject) => {
86
- if (controller.signal.aborted) {
87
- reject(new ConnectionClosedError('Called operation on closed remote'));
88
- if (!fireActionOnAbort) {
89
- // Don't run the operation if we're going to reject
90
- // We might want to fire-and-forget the operation in some cases (like a close operation)
91
- return;
92
- }
93
- }
94
-
95
- function handleAbort() {
96
- reject(new ConnectionClosedError('Remote peer closed with request in flight'));
97
- }
98
-
99
- function completePromise(action: () => void) {
100
- controller!.signal.removeEventListener('abort', handleAbort);
101
- action();
102
- }
103
-
104
- controller.signal.addEventListener('abort', handleAbort);
105
-
106
- workerPromise()
107
- .then((data) => completePromise(() => resolve(data)))
108
- .catch((e) => completePromise(() => reject(e)));
109
- });
110
- } else {
111
- // Can't close, so just return the inner worker promise unguarded.
112
- return workerPromise();
113
- }
114
- }
115
-
116
- /**
117
- * Get a MessagePort which can be used to share the internals of this connection.
118
- */
119
- async shareConnection(): Promise<SharedConnectionWorker> {
120
- const { identifier, remote } = this.options;
121
- /**
122
- * Hold a navigator lock in order to avoid features such as Chrome's frozen tabs,
123
- * or Edge's sleeping tabs from pausing the thread for this connection.
124
- * This promise resolves once a lock is obtained.
125
- * This lock will be held as long as this connection is open.
126
- * The `shareConnection` method should not be called on multiple tabs concurrently.
127
- */
128
- await new Promise<void>((resolve, reject) =>
129
- navigator.locks
130
- .request(
131
- `shared-connection-${this.options.identifier}-${Date.now()}-${Math.round(Math.random() * 10000)}`,
132
- {
133
- signal: this.lockAbortController.signal
134
- },
135
- async () => {
136
- resolve();
137
-
138
- // Free the lock when the connection is already closed.
139
- if (this.lockAbortController.signal.aborted) {
140
- return;
141
- }
142
-
143
- // Hold the lock while the shared connection is in use.
144
- await new Promise<void>((releaseLock) => {
145
- this.lockAbortController.signal.addEventListener('abort', () => {
146
- releaseLock();
147
- });
148
- });
149
- }
150
- )
151
- // We aren't concerned with abort errors here
152
- .catch((ex) => {
153
- if (ex.name == 'AbortError') {
154
- resolve();
155
- } else {
156
- reject(ex);
157
- }
158
- })
159
- );
160
-
161
- const newPort = await remote[Comlink.createEndpoint]();
162
- return { port: newPort, identifier };
163
- }
164
-
165
- /**
166
- * Registers a table change notification callback with the base database.
167
- * This can be extended by custom implementations in order to handle proxy events.
168
- */
169
- async registerOnTableChange(callback: OnTableChangeCallback) {
170
- return this.baseConnection.registerOnTableChange(Comlink.proxy(callback));
171
- }
172
-
173
- async close(): Promise<void> {
174
- // Abort any pending lock requests.
175
- this.lockAbortController.abort();
176
- try {
177
- // fire and forget the close operation
178
- await this.withRemote(() => this.baseConnection.close(), true);
179
- } finally {
180
- this.options.remote[Comlink.releaseProxy]();
181
- this.options.onClose?.();
182
- this.iterateListeners((l) => l.closing?.());
183
- }
184
- }
185
-
186
- execute(sql: string, params?: any[]): Promise<ProxiedQueryResult> {
187
- return this.withRemote(() => this.baseConnection.execute(sql, params));
188
- }
189
-
190
- executeRaw(sql: string, params?: any[]): Promise<any[][]> {
191
- return this.withRemote(() => this.baseConnection.executeRaw(sql, params));
192
- }
193
-
194
- executeBatch(sql: string, params?: any[]): Promise<ProxiedQueryResult> {
195
- return this.withRemote(() => this.baseConnection.executeBatch(sql, params));
196
- }
197
-
198
- getConfig(): Promise<ResolvedWebSQLOpenOptions> {
199
- return this.withRemote(() => this.baseConnection.getConfig());
200
- }
201
- }
@@ -1,23 +0,0 @@
1
- import { LockedAsyncDatabaseAdapter } from '../LockedAsyncDatabaseAdapter.js';
2
- import { WebDBAdapterConfiguration } from '../WebDBAdapter.js';
3
- import { WASQLiteVFS } from './WASQLiteConnection.js';
4
- import { ResolvedWASQLiteOpenFactoryOptions } from './WASQLiteOpenFactory.js';
5
-
6
- /**
7
- * @internal
8
- * An intermediary implementation of WASQLiteDBAdapter, which takes the same
9
- * constructor arguments as {@link LockedAsyncDatabaseAdapter}, but provides some
10
- * basic WA-SQLite specific functionality.
11
- * This base class is used to avoid requiring overloading the constructor of {@link WASQLiteDBAdapter}
12
- */
13
- export class InternalWASQLiteDBAdapter extends LockedAsyncDatabaseAdapter {
14
- getConfiguration(): WebDBAdapterConfiguration {
15
- // This is valid since we only handle WASQLite connections
16
- const baseConfig = super.getConfiguration() as unknown as ResolvedWASQLiteOpenFactoryOptions;
17
- return {
18
- ...super.getConfiguration(),
19
- requiresPersistentTriggers:
20
- baseConfig.vfs == WASQLiteVFS.OPFSCoopSyncVFS || baseConfig.vfs == WASQLiteVFS.AccessHandlePoolVFS
21
- };
22
- }
23
- }