@powersync/web 0.6.1 → 0.8.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.
package/README.md CHANGED
@@ -56,6 +56,14 @@ if (typeof self.Buffer == 'undefined') {
56
56
  }
57
57
  ```
58
58
 
59
+ ## Webpack
60
+
61
+ See the [example Webpack config](https://github.com/powersync-ja/powersync-js/blob/main/demos/example-webpack/webpack.config.js) for details on polyfills and requirements.
62
+
63
+ ## Vite
64
+
65
+ See the [example Vite config](https://github.com/powersync-ja/powersync-js/blob/main/demos/example-vite/vite.config.ts) for details on polyfills and requirements.
66
+
59
67
  # Getting Started
60
68
 
61
69
  Our [full SDK reference](https://docs.powersync.com/client-sdk-references/js-web) contains everything you need to know to get started implementing PowerSync in your project.
@@ -1,10 +1,11 @@
1
- import { AbstractPowerSyncDatabase, AbstractStreamingSyncImplementation, PowerSyncBackendConnector, BucketStorageAdapter, PowerSyncDatabaseOptions, PowerSyncCloseOptions, PowerSyncConnectionOptions } from '@powersync/common';
1
+ import { type AbstractStreamingSyncImplementation, type PowerSyncBackendConnector, type BucketStorageAdapter, type PowerSyncDatabaseOptions, type PowerSyncCloseOptions, type PowerSyncConnectionOptions, AbstractPowerSyncDatabase } from '@powersync/common';
2
2
  import { Mutex } from 'async-mutex';
3
3
  export interface WebPowerSyncFlags {
4
4
  /**
5
5
  * Enables multi tab support
6
6
  */
7
7
  enableMultiTabs?: boolean;
8
+ useWebWorker?: boolean;
8
9
  /**
9
10
  * Open in SSR placeholder mode. DB operations and Sync operations will be a No-op
10
11
  */
@@ -8,11 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { AbstractPowerSyncDatabase, SqliteBucketStorage, DEFAULT_POWERSYNC_CLOSE_OPTIONS } from '@powersync/common';
11
+ import { Mutex } from 'async-mutex';
11
12
  import { WebRemote } from './sync/WebRemote';
12
13
  import { SharedWebStreamingSyncImplementation } from './sync/SharedWebStreamingSyncImplementation';
13
14
  import { SSRStreamingSyncImplementation } from './sync/SSRWebStreamingSyncImplementation';
14
15
  import { WebStreamingSyncImplementation } from './sync/WebStreamingSyncImplementation';
15
- import { Mutex } from 'async-mutex';
16
16
  export class PowerSyncDatabase extends AbstractPowerSyncDatabase {
17
17
  constructor(options) {
18
18
  super(options);
@@ -76,8 +76,8 @@ export class PowerSyncDatabase extends AbstractPowerSyncDatabase {
76
76
  case flags === null || flags === void 0 ? void 0 : flags.enableMultiTabs:
77
77
  if (!(flags === null || flags === void 0 ? void 0 : flags.broadcastLogs)) {
78
78
  const warning = `
79
- Multiple tabs are enabled, but broadcasting of logs is disabled.
80
- Logs for shared sync worker will only be available in the shared worker context
79
+ Multiple tabs are enabled, but broadcasting of logs is disabled.
80
+ Logs for shared sync worker will only be available in the shared worker context
81
81
  `;
82
82
  const logger = this.options.logger;
83
83
  logger ? logger.warn(warning) : console.warn(warning);
@@ -2,6 +2,7 @@ import { AbstractPowerSyncDatabaseOpenFactory } from '@powersync/common';
2
2
  import { PowerSyncDatabase } from '../../db/PowerSyncDatabase';
3
3
  import { SSRDBAdapter } from './SSRDBAdapter';
4
4
  export const DEFAULT_POWERSYNC_FLAGS = {
5
+ useWebWorker: true,
5
6
  /**
6
7
  * Multiple tabs are by default not supported on Android, iOS and Safari.
7
8
  * Other platforms will have multiple tabs enabled by default.
@@ -48,6 +49,9 @@ export class AbstractWebPowerSyncDatabaseOpenFactory extends AbstractPowerSyncDa
48
49
  if (typeof ((_b = this.options.flags) === null || _b === void 0 ? void 0 : _b.enableMultiTabs) != 'undefined') {
49
50
  flags.enableMultiTabs = this.options.flags.enableMultiTabs;
50
51
  }
52
+ if (flags.useWebWorker === false) {
53
+ flags.enableMultiTabs = false;
54
+ }
51
55
  return flags;
52
56
  }
53
57
  generateInstance(options) {
@@ -1,6 +1,7 @@
1
- import { BaseObserver, DBAdapter, DBAdapterListener, DBLockOptions, LockContext, PowerSyncOpenFactoryOptions, QueryResult, Transaction } from '@powersync/common';
1
+ import { type DBAdapter, type DBAdapterListener, type DBLockOptions, type LockContext, type PowerSyncOpenFactoryOptions, type QueryResult, type Transaction, BaseObserver } from '@powersync/common';
2
2
  export type WASQLiteFlags = {
3
3
  enableMultiTabs?: boolean;
4
+ useWebWorker?: boolean;
4
5
  };
5
6
  export interface WASQLiteDBAdapterOptions extends Omit<PowerSyncOpenFactoryOptions, 'schema'> {
6
7
  flags?: WASQLiteFlags;
@@ -18,7 +19,7 @@ export declare class WASQLiteDBAdapter extends BaseObserver<DBAdapterListener> i
18
19
  private initialized;
19
20
  private logger;
20
21
  private dbGetHelpers;
21
- private workerMethods;
22
+ private methods;
22
23
  constructor(options: WASQLiteDBAdapterOptions);
23
24
  get name(): string;
24
25
  protected get flags(): WASQLiteFlags;
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { BaseObserver } from '@powersync/common';
11
11
  import * as Comlink from 'comlink';
12
12
  import Logger from 'js-logger';
13
+ import { _openDB } from '../../../shared/open-db';
13
14
  import { getWorkerDatabaseOpener } from '../../../worker/db/open-worker-database';
14
15
  /**
15
16
  * Adapter for WA-SQLite
@@ -23,7 +24,7 @@ export class WASQLiteDBAdapter extends BaseObserver {
23
24
  */
24
25
  this._execute = (sql, bindings) => __awaiter(this, void 0, void 0, function* () {
25
26
  yield this.initialized;
26
- const result = yield this.workerMethods.execute(sql, bindings);
27
+ const result = yield this.methods.execute(sql, bindings);
27
28
  return Object.assign(Object.assign({}, result), { rows: Object.assign(Object.assign({}, result.rows), { item: (idx) => result.rows._array[idx] }) });
28
29
  });
29
30
  /**
@@ -31,12 +32,12 @@ export class WASQLiteDBAdapter extends BaseObserver {
31
32
  */
32
33
  this._executeBatch = (query, params) => __awaiter(this, void 0, void 0, function* () {
33
34
  yield this.initialized;
34
- const result = yield this.workerMethods.executeBatch(query, params);
35
+ const result = yield this.methods.executeBatch(query, params);
35
36
  return Object.assign(Object.assign({}, result), { rows: undefined });
36
37
  });
37
38
  this.logger = Logger.get('WASQLite');
38
39
  this.dbGetHelpers = null;
39
- this.workerMethods = null;
40
+ this.methods = null;
40
41
  this.initialized = this.init();
41
42
  this.dbGetHelpers = this.generateDBHelpers({ execute: this._execute.bind(this) });
42
43
  }
@@ -50,17 +51,24 @@ export class WASQLiteDBAdapter extends BaseObserver {
50
51
  getWorker() { }
51
52
  init() {
52
53
  return __awaiter(this, void 0, void 0, function* () {
53
- const { enableMultiTabs } = this.flags;
54
+ const { enableMultiTabs, useWebWorker } = this.flags;
54
55
  if (!enableMultiTabs) {
55
56
  this.logger.warn('Multiple tabs are not enabled in this browser');
56
57
  }
57
- const dbOpener = this.options.workerPort
58
- ? Comlink.wrap(this.options.workerPort)
59
- : getWorkerDatabaseOpener(this.options.dbFilename, enableMultiTabs);
60
- this.workerMethods = yield dbOpener(this.options.dbFilename);
61
- this.workerMethods.registerOnTableChange(Comlink.proxy((opType, tableName, rowId) => {
58
+ if (useWebWorker) {
59
+ const dbOpener = this.options.workerPort
60
+ ? Comlink.wrap(this.options.workerPort)
61
+ : getWorkerDatabaseOpener(this.options.dbFilename, enableMultiTabs);
62
+ this.methods = yield dbOpener(this.options.dbFilename);
63
+ this.methods.registerOnTableChange(Comlink.proxy((opType, tableName, rowId) => {
64
+ this.iterateListeners((cb) => { var _a; return (_a = cb.tablesUpdated) === null || _a === void 0 ? void 0 : _a.call(cb, { opType, table: tableName, rowId }); });
65
+ }));
66
+ return;
67
+ }
68
+ this.methods = yield _openDB(this.options.dbFilename, { useWebWorker: false });
69
+ this.methods.registerOnTableChange((opType, tableName, rowId) => {
62
70
  this.iterateListeners((cb) => { var _a; return (_a = cb.tablesUpdated) === null || _a === void 0 ? void 0 : _a.call(cb, { opType, table: tableName, rowId }); });
63
- }));
71
+ });
64
72
  });
65
73
  }
66
74
  execute(query, params) {
@@ -80,7 +88,7 @@ export class WASQLiteDBAdapter extends BaseObserver {
80
88
  */
81
89
  close() {
82
90
  var _a, _b;
83
- (_b = (_a = this.workerMethods) === null || _a === void 0 ? void 0 : _a.close) === null || _b === void 0 ? void 0 : _b.call(_a);
91
+ (_b = (_a = this.methods) === null || _a === void 0 ? void 0 : _a.close) === null || _b === void 0 ? void 0 : _b.call(_a);
84
92
  }
85
93
  getAll(sql, parameters) {
86
94
  return __awaiter(this, void 0, void 0, function* () {
@@ -1,3 +1,5 @@
1
- import { AbstractRemote } from '@powersync/common';
1
+ import { AbstractRemote, BSONImplementation } from '@powersync/common';
2
2
  export declare class WebRemote extends AbstractRemote {
3
+ private _bson;
4
+ getBSON(): Promise<BSONImplementation>;
3
5
  }
@@ -1,3 +1,25 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { AbstractRemote } from '@powersync/common';
2
11
  export class WebRemote extends AbstractRemote {
12
+ getBSON() {
13
+ return __awaiter(this, void 0, void 0, function* () {
14
+ if (this._bson) {
15
+ return this._bson;
16
+ }
17
+ /**
18
+ * Dynamic import to be used only when needed.
19
+ */
20
+ const { BSON } = yield import('bson');
21
+ this._bson = BSON;
22
+ return this._bson;
23
+ });
24
+ }
3
25
  }
@@ -0,0 +1,5 @@
1
+ import '@journeyapps/wa-sqlite';
2
+ import type { DBFunctionsInterface } from './types';
3
+ export declare function _openDB(dbFileName: string, options?: {
4
+ useWebWorker: boolean;
5
+ }): Promise<DBFunctionsInterface>;
@@ -18,8 +18,8 @@ import * as SQLite from '@journeyapps/wa-sqlite';
18
18
  import '@journeyapps/wa-sqlite';
19
19
  import * as Comlink from 'comlink';
20
20
  let nextId = 1;
21
- export function _openDB(dbFileName) {
22
- return __awaiter(this, void 0, void 0, function* () {
21
+ export function _openDB(dbFileName_1) {
22
+ return __awaiter(this, arguments, void 0, function* (dbFileName, options = { useWebWorker: true }) {
23
23
  const { default: moduleFactory } = yield import('@journeyapps/wa-sqlite/dist/wa-sqlite-async.mjs');
24
24
  const module = yield moduleFactory();
25
25
  const sqlite3 = SQLite.Factory(module);
@@ -34,13 +34,6 @@ export function _openDB(dbFileName) {
34
34
  sqlite3.register_table_onchange_hook(db, (opType, tableName, rowId) => {
35
35
  Array.from(listeners.values()).forEach((l) => l(opType, tableName, rowId));
36
36
  });
37
- const registerOnTableChange = (callback) => {
38
- const id = nextId++;
39
- listeners.set(id, callback);
40
- return Comlink.proxy(() => {
41
- listeners.delete(id);
42
- });
43
- };
44
37
  /**
45
38
  * This executes single SQL statements inside a requested lock.
46
39
  */
@@ -180,13 +173,35 @@ export function _openDB(dbFileName) {
180
173
  return result;
181
174
  }));
182
175
  });
176
+ if (options.useWebWorker) {
177
+ const registerOnTableChange = (callback) => {
178
+ const id = nextId++;
179
+ listeners.set(id, callback);
180
+ return Comlink.proxy(() => {
181
+ listeners.delete(id);
182
+ });
183
+ };
184
+ return {
185
+ execute: Comlink.proxy(execute),
186
+ executeBatch: Comlink.proxy(executeBatch),
187
+ registerOnTableChange: Comlink.proxy(registerOnTableChange),
188
+ close: Comlink.proxy(() => {
189
+ sqlite3.close(db);
190
+ })
191
+ };
192
+ }
193
+ const registerOnTableChange = (callback) => {
194
+ const id = nextId++;
195
+ listeners.set(id, callback);
196
+ return () => {
197
+ listeners.delete(id);
198
+ };
199
+ };
183
200
  return {
184
- execute: Comlink.proxy(execute),
185
- executeBatch: Comlink.proxy(executeBatch),
186
- registerOnTableChange: Comlink.proxy(registerOnTableChange),
187
- close: Comlink.proxy(() => {
188
- sqlite3.close(db);
189
- })
201
+ execute: execute,
202
+ executeBatch: executeBatch,
203
+ registerOnTableChange: registerOnTableChange,
204
+ close: () => sqlite3.close(db)
190
205
  };
191
206
  });
192
207
  }
@@ -1,20 +1,22 @@
1
- import '@journeyapps/wa-sqlite';
2
- import { QueryResult } from '@powersync/common';
1
+ import type { QueryResult } from '@powersync/common';
3
2
  export type WASQLExecuteResult = Omit<QueryResult, 'rows'> & {
4
3
  rows: {
5
4
  _array: any[];
6
5
  length: number;
7
6
  };
8
7
  };
9
- export type DBWorkerInterface = {
8
+ export type DBFunctionsInterface = {
10
9
  close?: () => void;
11
10
  execute: WASQLiteExecuteMethod;
12
11
  executeBatch: WASQLiteExecuteBatchMethod;
13
12
  registerOnTableChange: (callback: OnTableChangeCallback) => void;
14
13
  };
14
+ /**
15
+ * @deprecated use [DBFunctionsInterface instead]
16
+ */
17
+ export type DBWorkerInterface = DBFunctionsInterface;
15
18
  export type WASQLiteExecuteMethod = (sql: string, params?: any[]) => Promise<WASQLExecuteResult>;
16
19
  export type WASQLiteExecuteBatchMethod = (sql: string, params?: any[]) => Promise<WASQLExecuteResult>;
17
20
  export type OnTableChangeCallback = (opType: number, tableName: string, rowId: number) => void;
18
21
  export type OpenDB = (dbFileName: string) => DBWorkerInterface;
19
22
  export type SQLBatchTuple = [string] | [string, Array<any> | Array<Array<any>>];
20
- export declare function _openDB(dbFileName: string): Promise<DBWorkerInterface>;
@@ -0,0 +1 @@
1
+ export {};
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import '@journeyapps/wa-sqlite';
11
11
  import * as Comlink from 'comlink';
12
- import { _openDB } from './open-db';
12
+ import { _openDB } from '../../shared/open-db';
13
13
  const _self = self;
14
14
  const DBMap = new Map();
15
15
  const OPEN_DB_LOCK = 'open-wasqlite-db';
@@ -8,5 +8,5 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import * as Comlink from 'comlink';
11
- import { _openDB } from './open-db';
11
+ import { _openDB } from '../../shared/open-db';
12
12
  Comlink.expose((dbFileName) => __awaiter(void 0, void 0, void 0, function* () { return Comlink.proxy(yield _openDB(dbFileName)); }));
@@ -1,5 +1,5 @@
1
1
  import * as Comlink from 'comlink';
2
- import { OpenDB } from './open-db';
2
+ import type { OpenDB } from '../../shared/types';
3
3
  /**
4
4
  * Opens a shared or dedicated worker which exposes opening of database connections
5
5
  */
@@ -1,4 +1,4 @@
1
- import { PowerSyncCredentials, SyncStatusOptions } from '@powersync/common';
1
+ import type { PowerSyncCredentials, SyncStatusOptions } from '@powersync/common';
2
2
  /**
3
3
  * The client side port should provide these methods.
4
4
  */
@@ -1,4 +1,4 @@
1
- import { ILogLevel, ILogger } from 'js-logger';
1
+ import { type ILogLevel, type ILogger } from 'js-logger';
2
2
  import { type WrappedSyncPort } from './SharedSyncImplementation';
3
3
  /**
4
4
  * Broadcasts logs to all clients
@@ -77,7 +77,7 @@ export class BroadcastLogger {
77
77
  */
78
78
  iterateClients(callback) {
79
79
  return __awaiter(this, void 0, void 0, function* () {
80
- for (let client of this.clients) {
80
+ for (const client of this.clients) {
81
81
  try {
82
82
  yield callback(client);
83
83
  }
@@ -1,6 +1,6 @@
1
1
  import * as Comlink from 'comlink';
2
- import { ILogger } from 'js-logger';
3
- import { AbstractStreamingSyncImplementation, StreamingSyncImplementation, BaseObserver, LockOptions, StreamingSyncImplementationListener, SyncStatus, SyncStatusOptions, PowerSyncConnectionOptions } from '@powersync/common';
2
+ import { type ILogger } from 'js-logger';
3
+ import { type AbstractStreamingSyncImplementation, type StreamingSyncImplementation, type LockOptions, type StreamingSyncImplementationListener, type SyncStatusOptions, type PowerSyncConnectionOptions, BaseObserver, SyncStatus } from '@powersync/common';
4
4
  import { WebStreamingSyncImplementationOptions } from '../../db/sync/WebStreamingSyncImplementation';
5
5
  import { AbstractSharedSyncClientProvider } from './AbstractSharedSyncClientProvider';
6
6
  /**