@powersync/common 0.0.0-dev-20250715080712 → 0.0.0-dev-20250715111940

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 (30) hide show
  1. package/dist/bundle.cjs +5 -5
  2. package/dist/bundle.mjs +3 -3
  3. package/lib/client/AbstractPowerSyncDatabase.d.ts +5 -56
  4. package/lib/client/AbstractPowerSyncDatabase.js +29 -95
  5. package/lib/client/sync/bucket/BucketStorageAdapter.d.ts +2 -2
  6. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.d.ts +2 -3
  7. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js +3 -14
  8. package/lib/index.d.ts +1 -7
  9. package/lib/index.js +1 -7
  10. package/lib/utils/BaseObserver.d.ts +4 -3
  11. package/lib/utils/BaseObserver.js +0 -3
  12. package/package.json +1 -1
  13. package/lib/client/CustomQuery.d.ts +0 -25
  14. package/lib/client/CustomQuery.js +0 -41
  15. package/lib/client/Query.d.ts +0 -79
  16. package/lib/client/Query.js +0 -1
  17. package/lib/client/watched/GetAllQuery.d.ts +0 -32
  18. package/lib/client/watched/GetAllQuery.js +0 -24
  19. package/lib/client/watched/WatchedQuery.d.ts +0 -93
  20. package/lib/client/watched/WatchedQuery.js +0 -12
  21. package/lib/client/watched/processors/AbstractQueryProcessor.d.ts +0 -67
  22. package/lib/client/watched/processors/AbstractQueryProcessor.js +0 -136
  23. package/lib/client/watched/processors/DifferentialQueryProcessor.d.ts +0 -129
  24. package/lib/client/watched/processors/DifferentialQueryProcessor.js +0 -175
  25. package/lib/client/watched/processors/OnChangeQueryProcessor.d.ts +0 -27
  26. package/lib/client/watched/processors/OnChangeQueryProcessor.js +0 -74
  27. package/lib/client/watched/processors/comparators.d.ts +0 -24
  28. package/lib/client/watched/processors/comparators.js +0 -33
  29. package/lib/utils/MetaBaseObserver.d.ts +0 -29
  30. package/lib/utils/MetaBaseObserver.js +0 -50
@@ -6,15 +6,12 @@ import { UploadQueueStats } from '../db/crud/UploadQueueStatus.js';
6
6
  import { Schema } from '../db/schema/Schema.js';
7
7
  import { BaseObserver } from '../utils/BaseObserver.js';
8
8
  import { ConnectionManager } from './ConnectionManager.js';
9
- import { ArrayQueryDefinition, Query } from './Query.js';
10
9
  import { SQLOpenFactory, SQLOpenOptions } from './SQLOpenFactory.js';
11
10
  import { PowerSyncBackendConnector } from './connection/PowerSyncBackendConnector.js';
12
11
  import { BucketStorageAdapter } from './sync/bucket/BucketStorageAdapter.js';
13
12
  import { CrudBatch } from './sync/bucket/CrudBatch.js';
14
13
  import { CrudTransaction } from './sync/bucket/CrudTransaction.js';
15
14
  import { StreamingSyncImplementation, StreamingSyncImplementationListener, type AdditionalConnectionOptions, type PowerSyncConnectionOptions, type RequiredAdditionalConnectionOptions } from './sync/stream/AbstractStreamingSyncImplementation.js';
16
- import { WatchCompatibleQuery } from './watched/WatchedQuery.js';
17
- import { WatchedQueryComparator } from './watched/processors/comparators.js';
18
15
  export interface DisconnectAndClearOptions {
19
16
  /** When set to false, data in local-only tables is preserved. */
20
17
  clearLocal?: boolean;
@@ -47,7 +44,7 @@ export interface PowerSyncDatabaseOptionsWithOpenFactory extends BasePowerSyncDa
47
44
  export interface PowerSyncDatabaseOptionsWithSettings extends BasePowerSyncDatabaseOptions {
48
45
  database: SQLOpenOptions;
49
46
  }
50
- export interface SQLOnChangeOptions {
47
+ export interface SQLWatchOptions {
51
48
  signal?: AbortSignal;
52
49
  tables?: string[];
53
50
  /** The minimum interval between queries. */
@@ -59,17 +56,6 @@ export interface SQLOnChangeOptions {
59
56
  * by not removing PowerSync table name prefixes
60
57
  */
61
58
  rawTableNames?: boolean;
62
- /**
63
- * Emits an empty result set immediately
64
- */
65
- triggerImmediate?: boolean;
66
- }
67
- export interface SQLWatchOptions extends SQLOnChangeOptions {
68
- /**
69
- * Optional comparator which will be used to compare the results of the query.
70
- * The watched query will only yield results if the comparator returns false.
71
- */
72
- comparator?: WatchedQueryComparator<QueryResult>;
73
59
  }
74
60
  export interface WatchOnChangeEvent {
75
61
  changedTables: string[];
@@ -85,8 +71,6 @@ export interface WatchOnChangeHandler {
85
71
  export interface PowerSyncDBListener extends StreamingSyncImplementationListener {
86
72
  initialized: () => void;
87
73
  schemaChanged: (schema: Schema) => void;
88
- closing: () => Promise<void> | void;
89
- closed: () => Promise<void> | void;
90
74
  }
91
75
  export interface PowerSyncCloseOptions {
92
76
  /**
@@ -97,6 +81,7 @@ export interface PowerSyncCloseOptions {
97
81
  disconnect?: boolean;
98
82
  }
99
83
  export declare const DEFAULT_POWERSYNC_CLOSE_OPTIONS: PowerSyncCloseOptions;
84
+ export declare const DEFAULT_WATCH_THROTTLE_MS = 30;
100
85
  export declare const DEFAULT_POWERSYNC_DB_OPTIONS: {
101
86
  retryDelayMs: number;
102
87
  logger: Logger.ILogger;
@@ -405,42 +390,6 @@ export declare abstract class AbstractPowerSyncDatabase extends BaseObserver<Pow
405
390
  * ```
406
391
  */
407
392
  watch(sql: string, parameters?: any[], handler?: WatchHandler, options?: SQLWatchOptions): void;
408
- /**
409
- * Allows defining a query which can be used to build a {@link WatchedQuery}.
410
- * The defined query will be executed with {@link AbstractPowerSyncDatabase#getAll}.
411
- * An optional mapper function can be provided to transform the results.
412
- *
413
- * @example
414
- * ```javascript
415
- * const watchedTodos = powersync.query({
416
- * sql: `SELECT photo_id as id FROM todos WHERE photo_id IS NOT NULL`,
417
- * parameters: [],
418
- * mapper: (row) => ({
419
- * ...row,
420
- * created_at: new Date(row.created_at as string)
421
- * })
422
- * })
423
- * .watch()
424
- * // OR use .differentialWatch() for fine-grained watches.
425
- * ```
426
- */
427
- query<RowType>(query: ArrayQueryDefinition<RowType>): Query<RowType>;
428
- /**
429
- * Allows building a {@link WatchedQuery} using an existing {@link WatchCompatibleQuery}.
430
- * The watched query will use the provided {@link WatchCompatibleQuery.execute} method to query results.
431
- *
432
- * @example
433
- * ```javascript
434
- *
435
- * // Potentially a query from an ORM like Drizzle
436
- * const query = db.select().from(lists);
437
- *
438
- * const watchedTodos = powersync.customQuery(query)
439
- * .watch()
440
- * // OR use .differentialWatch() for fine-grained watches.
441
- * ```
442
- */
443
- customQuery<RowType>(query: WatchCompatibleQuery<RowType[]>): Query<RowType>;
444
393
  /**
445
394
  * Execute a read query every time the source tables are modified.
446
395
  * Use {@link SQLWatchOptions.throttleMs} to specify the minimum interval between queries.
@@ -489,7 +438,7 @@ export declare abstract class AbstractPowerSyncDatabase extends BaseObserver<Pow
489
438
  * }
490
439
  * ```
491
440
  */
492
- onChange(options?: SQLOnChangeOptions): AsyncIterable<WatchOnChangeEvent>;
441
+ onChange(options?: SQLWatchOptions): AsyncIterable<WatchOnChangeEvent>;
493
442
  /**
494
443
  * See {@link onChangeWithCallback}.
495
444
  *
@@ -504,7 +453,7 @@ export declare abstract class AbstractPowerSyncDatabase extends BaseObserver<Pow
504
453
  * }
505
454
  * ```
506
455
  */
507
- onChange(handler?: WatchOnChangeHandler, options?: SQLOnChangeOptions): () => void;
456
+ onChange(handler?: WatchOnChangeHandler, options?: SQLWatchOptions): () => void;
508
457
  /**
509
458
  * Invoke the provided callback on any changes to any of the specified tables.
510
459
  *
@@ -517,7 +466,7 @@ export declare abstract class AbstractPowerSyncDatabase extends BaseObserver<Pow
517
466
  * @param options Options for configuring watch behavior
518
467
  * @returns A dispose function to stop watching for changes
519
468
  */
520
- onChangeWithCallback(handler?: WatchOnChangeHandler, options?: SQLOnChangeOptions): () => void;
469
+ onChangeWithCallback(handler?: WatchOnChangeHandler, options?: SQLWatchOptions): () => void;
521
470
  /**
522
471
  * Create a Stream of changes to any of the specified tables.
523
472
  *
@@ -9,15 +9,13 @@ import { BaseObserver } from '../utils/BaseObserver.js';
9
9
  import { ControlledExecutor } from '../utils/ControlledExecutor.js';
10
10
  import { throttleTrailing } from '../utils/async.js';
11
11
  import { ConnectionManager } from './ConnectionManager.js';
12
- import { CustomQuery } from './CustomQuery.js';
13
12
  import { isDBAdapter, isSQLOpenFactory, isSQLOpenOptions } from './SQLOpenFactory.js';
13
+ import { runOnSchemaChange } from './runOnSchemaChange.js';
14
14
  import { PSInternalTable } from './sync/bucket/BucketStorageAdapter.js';
15
15
  import { CrudBatch } from './sync/bucket/CrudBatch.js';
16
16
  import { CrudEntry } from './sync/bucket/CrudEntry.js';
17
17
  import { CrudTransaction } from './sync/bucket/CrudTransaction.js';
18
18
  import { DEFAULT_CRUD_UPLOAD_THROTTLE_MS, DEFAULT_RETRY_DELAY_MS } from './sync/stream/AbstractStreamingSyncImplementation.js';
19
- import { DEFAULT_WATCH_THROTTLE_MS } from './watched/WatchedQuery.js';
20
- import { OnChangeQueryProcessor } from './watched/processors/OnChangeQueryProcessor.js';
21
19
  const POWERSYNC_TABLE_MATCH = /(^ps_data__|^ps_data_local__)/;
22
20
  const DEFAULT_DISCONNECT_CLEAR_OPTIONS = {
23
21
  clearLocal: true
@@ -25,6 +23,7 @@ const DEFAULT_DISCONNECT_CLEAR_OPTIONS = {
25
23
  export const DEFAULT_POWERSYNC_CLOSE_OPTIONS = {
26
24
  disconnect: true
27
25
  };
26
+ export const DEFAULT_WATCH_THROTTLE_MS = 30;
28
27
  export const DEFAULT_POWERSYNC_DB_OPTIONS = {
29
28
  retryDelayMs: 5000,
30
29
  logger: Logger.get('PowerSyncDatabase'),
@@ -344,7 +343,6 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
344
343
  if (this.closed) {
345
344
  return;
346
345
  }
347
- await this.iterateAsyncListeners(async (cb) => cb.closing?.());
348
346
  const { disconnect } = options;
349
347
  if (disconnect) {
350
348
  await this.disconnect();
@@ -352,7 +350,6 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
352
350
  await this.connectionManager.close();
353
351
  await this.database.close();
354
352
  this.closed = true;
355
- await this.iterateAsyncListeners(async (cb) => cb.closed?.());
356
353
  }
357
354
  /**
358
355
  * Get upload queue size estimate and count.
@@ -599,60 +596,6 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
599
596
  const options = handlerOrOptions;
600
597
  return this.watchWithAsyncGenerator(sql, parameters, options);
601
598
  }
602
- /**
603
- * Allows defining a query which can be used to build a {@link WatchedQuery}.
604
- * The defined query will be executed with {@link AbstractPowerSyncDatabase#getAll}.
605
- * An optional mapper function can be provided to transform the results.
606
- *
607
- * @example
608
- * ```javascript
609
- * const watchedTodos = powersync.query({
610
- * sql: `SELECT photo_id as id FROM todos WHERE photo_id IS NOT NULL`,
611
- * parameters: [],
612
- * mapper: (row) => ({
613
- * ...row,
614
- * created_at: new Date(row.created_at as string)
615
- * })
616
- * })
617
- * .watch()
618
- * // OR use .differentialWatch() for fine-grained watches.
619
- * ```
620
- */
621
- query(query) {
622
- const { sql, parameters = [], mapper } = query;
623
- const compatibleQuery = {
624
- compile: () => ({
625
- sql,
626
- parameters
627
- }),
628
- execute: async ({ sql, parameters }) => {
629
- const result = await this.getAll(sql, parameters);
630
- return mapper ? result.map(mapper) : result;
631
- }
632
- };
633
- return this.customQuery(compatibleQuery);
634
- }
635
- /**
636
- * Allows building a {@link WatchedQuery} using an existing {@link WatchCompatibleQuery}.
637
- * The watched query will use the provided {@link WatchCompatibleQuery.execute} method to query results.
638
- *
639
- * @example
640
- * ```javascript
641
- *
642
- * // Potentially a query from an ORM like Drizzle
643
- * const query = db.select().from(lists);
644
- *
645
- * const watchedTodos = powersync.customQuery(query)
646
- * .watch()
647
- * // OR use .differentialWatch() for fine-grained watches.
648
- * ```
649
- */
650
- customQuery(query) {
651
- return new CustomQuery({
652
- db: this,
653
- query
654
- });
655
- }
656
599
  /**
657
600
  * Execute a read query every time the source tables are modified.
658
601
  * Use {@link SQLWatchOptions.throttleMs} to specify the minimum interval between queries.
@@ -670,41 +613,35 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
670
613
  if (!onResult) {
671
614
  throw new Error('onResult is required');
672
615
  }
673
- const { comparator } = options ?? {};
674
- // This API yields a QueryResult type.
675
- // This is not a standard Array result, which makes it incompatible with the .query API.
676
- const watchedQuery = new OnChangeQueryProcessor({
677
- db: this,
678
- comparator,
679
- placeholderData: null,
680
- watchOptions: {
681
- query: {
682
- compile: () => ({
683
- sql: sql,
684
- parameters: parameters ?? []
685
- }),
686
- execute: () => this.executeReadOnly(sql, parameters)
687
- },
688
- reportFetching: false,
689
- throttleMs: options?.throttleMs ?? DEFAULT_WATCH_THROTTLE_MS
616
+ const watchQuery = async (abortSignal) => {
617
+ try {
618
+ const resolvedTables = await this.resolveTables(sql, parameters, options);
619
+ // Fetch initial data
620
+ const result = await this.executeReadOnly(sql, parameters);
621
+ onResult(result);
622
+ this.onChangeWithCallback({
623
+ onChange: async () => {
624
+ try {
625
+ const result = await this.executeReadOnly(sql, parameters);
626
+ onResult(result);
627
+ }
628
+ catch (error) {
629
+ onError?.(error);
630
+ }
631
+ },
632
+ onError
633
+ }, {
634
+ ...(options ?? {}),
635
+ tables: resolvedTables,
636
+ // Override the abort signal since we intercept it
637
+ signal: abortSignal
638
+ });
690
639
  }
691
- });
692
- const dispose = watchedQuery.registerListener({
693
- onData: (data) => {
694
- if (!data) {
695
- // This should not happen. We only use null for the initial data.
696
- return;
697
- }
698
- onResult(data);
699
- },
700
- onError: (error) => {
701
- onError(error);
640
+ catch (error) {
641
+ onError?.(error);
702
642
  }
703
- });
704
- options?.signal?.addEventListener('abort', () => {
705
- dispose();
706
- watchedQuery.close();
707
- });
643
+ };
644
+ runOnSchemaChange(watchQuery, this, options);
708
645
  }
709
646
  /**
710
647
  * Execute a read query every time the source tables are modified.
@@ -794,9 +731,6 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
794
731
  return;
795
732
  executor.schedule({ changedTables: intersection });
796
733
  }), throttleMs);
797
- if (options?.triggerImmediate) {
798
- executor.schedule({ changedTables: [] });
799
- }
800
734
  const dispose = this.database.registerListener({
801
735
  tablesUpdated: async (update) => {
802
736
  try {
@@ -1,4 +1,4 @@
1
- import { BaseListener, BaseObserverInterface, Disposable } from '../../../utils/BaseObserver.js';
1
+ import { BaseListener, BaseObserver, Disposable } from '../../../utils/BaseObserver.js';
2
2
  import { CrudBatch } from './CrudBatch.js';
3
3
  import { CrudEntry, OpId } from './CrudEntry.js';
4
4
  import { SyncDataBatch } from './SyncDataBatch.js';
@@ -62,7 +62,7 @@ export declare enum PowerSyncControlCommand {
62
62
  export interface BucketStorageListener extends BaseListener {
63
63
  crudUpdate: () => void;
64
64
  }
65
- export interface BucketStorageAdapter extends BaseObserverInterface<BucketStorageListener>, Disposable {
65
+ export interface BucketStorageAdapter extends BaseObserver<BucketStorageListener>, Disposable {
66
66
  init(): Promise<void>;
67
67
  saveSyncData(batch: SyncDataBatch, fixedKeyFormat?: boolean): Promise<void>;
68
68
  removeBuckets(buckets: string[]): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import Logger, { ILogger } from 'js-logger';
2
2
  import { SyncStatus, SyncStatusOptions } from '../../../db/crud/SyncStatus.js';
3
- import { BaseListener, BaseObserver, BaseObserverInterface, Disposable } from '../../../utils/BaseObserver.js';
3
+ import { BaseListener, BaseObserver, Disposable } from '../../../utils/BaseObserver.js';
4
4
  import { BucketStorageAdapter } from '../bucket/BucketStorageAdapter.js';
5
5
  import { AbstractRemote, FetchStrategy } from './AbstractRemote.js';
6
6
  import { StreamingSyncRequestParameterType } from './streaming-sync-types.js';
@@ -136,7 +136,7 @@ export interface AdditionalConnectionOptions {
136
136
  }
137
137
  /** @internal */
138
138
  export type RequiredAdditionalConnectionOptions = Required<AdditionalConnectionOptions>;
139
- export interface StreamingSyncImplementation extends BaseObserverInterface<StreamingSyncImplementationListener>, Disposable {
139
+ export interface StreamingSyncImplementation extends BaseObserver<StreamingSyncImplementationListener>, Disposable {
140
140
  /**
141
141
  * Connects to the sync service
142
142
  */
@@ -169,7 +169,6 @@ export declare abstract class AbstractStreamingSyncImplementation extends BaseOb
169
169
  protected _lastSyncedAt: Date | null;
170
170
  protected options: AbstractStreamingSyncImplementationOptions;
171
171
  protected abortController: AbortController | null;
172
- protected uploadAbortController: AbortController | null;
173
172
  protected crudUpdateListener?: () => void;
174
173
  protected streamingSyncPromise?: Promise<void>;
175
174
  private isUploadingCrud;
@@ -1,6 +1,6 @@
1
1
  import Logger from 'js-logger';
2
- import { FULL_SYNC_PRIORITY } from '../../../db/crud/SyncProgress.js';
3
2
  import { SyncStatus } from '../../../db/crud/SyncStatus.js';
3
+ import { FULL_SYNC_PRIORITY } from '../../../db/crud/SyncProgress.js';
4
4
  import { AbortOperation } from '../../../utils/AbortOperation.js';
5
5
  import { BaseObserver } from '../../../utils/BaseObserver.js';
6
6
  import { throttleLeadingTrailing } from '../../../utils/async.js';
@@ -84,9 +84,6 @@ export class AbstractStreamingSyncImplementation extends BaseObserver {
84
84
  _lastSyncedAt;
85
85
  options;
86
86
  abortController;
87
- // In rare cases, mostly for tests, uploads can be triggered without being properly connected.
88
- // This allows ensuring that all upload processes can be aborted.
89
- uploadAbortController;
90
87
  crudUpdateListener;
91
88
  streamingSyncPromise;
92
89
  isUploadingCrud = false;
@@ -163,10 +160,8 @@ export class AbstractStreamingSyncImplementation extends BaseObserver {
163
160
  return this.options.logger;
164
161
  }
165
162
  async dispose() {
166
- super.dispose();
167
163
  this.crudUpdateListener?.();
168
164
  this.crudUpdateListener = undefined;
169
- this.uploadAbortController?.abort();
170
165
  }
171
166
  async hasCompletedSync() {
172
167
  return this.options.adapter.hasCompletedSync();
@@ -185,12 +180,7 @@ export class AbstractStreamingSyncImplementation extends BaseObserver {
185
180
  * Keep track of the first item in the CRUD queue for the last `uploadCrud` iteration.
186
181
  */
187
182
  let checkedCrudItem;
188
- const controller = new AbortController();
189
- this.uploadAbortController = controller;
190
- this.abortController?.signal.addEventListener('abort', () => {
191
- controller.abort();
192
- }, { once: true });
193
- while (!controller.signal.aborted) {
183
+ while (true) {
194
184
  try {
195
185
  /**
196
186
  * This is the first item in the FIFO CRUD queue.
@@ -231,7 +221,7 @@ The next upload iteration will be delayed.`);
231
221
  uploadError: ex
232
222
  }
233
223
  });
234
- await this.delayRetry(controller.signal);
224
+ await this.delayRetry();
235
225
  if (!this.isConnected) {
236
226
  // Exit the upload loop if the sync stream is no longer connected
237
227
  break;
@@ -246,7 +236,6 @@ The next upload iteration will be delayed.`);
246
236
  });
247
237
  }
248
238
  }
249
- this.uploadAbortController = null;
250
239
  }
251
240
  });
252
241
  }
package/lib/index.d.ts CHANGED
@@ -29,15 +29,9 @@ export * from './db/schema/IndexedColumn.js';
29
29
  export * from './db/schema/Schema.js';
30
30
  export * from './db/schema/Table.js';
31
31
  export * from './db/schema/TableV2.js';
32
- export * from './client/Query.js';
33
- export * from './client/watched/GetAllQuery.js';
34
- export * from './client/watched/processors/AbstractQueryProcessor.js';
35
- export * from './client/watched/processors/comparators.js';
36
- export * from './client/watched/processors/DifferentialQueryProcessor.js';
37
- export * from './client/watched/processors/OnChangeQueryProcessor.js';
38
- export * from './client/watched/WatchedQuery.js';
39
32
  export * from './utils/AbortOperation.js';
40
33
  export * from './utils/BaseObserver.js';
34
+ export * from './utils/ControlledExecutor.js';
41
35
  export * from './utils/DataStream.js';
42
36
  export * from './utils/Logger.js';
43
37
  export * from './utils/parseQuery.js';
package/lib/index.js CHANGED
@@ -29,15 +29,9 @@ export * from './db/schema/IndexedColumn.js';
29
29
  export * from './db/schema/Schema.js';
30
30
  export * from './db/schema/Table.js';
31
31
  export * from './db/schema/TableV2.js';
32
- export * from './client/Query.js';
33
- export * from './client/watched/GetAllQuery.js';
34
- export * from './client/watched/processors/AbstractQueryProcessor.js';
35
- export * from './client/watched/processors/comparators.js';
36
- export * from './client/watched/processors/DifferentialQueryProcessor.js';
37
- export * from './client/watched/processors/OnChangeQueryProcessor.js';
38
- export * from './client/watched/WatchedQuery.js';
39
32
  export * from './utils/AbortOperation.js';
40
33
  export * from './utils/BaseObserver.js';
34
+ export * from './utils/ControlledExecutor.js';
41
35
  export * from './utils/DataStream.js';
42
36
  export * from './utils/Logger.js';
43
37
  export * from './utils/parseQuery.js';
@@ -1,14 +1,15 @@
1
1
  export interface Disposable {
2
- dispose: () => Promise<void> | void;
2
+ dispose: () => Promise<void>;
3
3
  }
4
- export type BaseListener = Record<string, ((...event: any) => any) | undefined>;
5
4
  export interface BaseObserverInterface<T extends BaseListener> {
6
5
  registerListener(listener: Partial<T>): () => void;
7
6
  }
7
+ export type BaseListener = {
8
+ [key: string]: ((...event: any) => any) | undefined;
9
+ };
8
10
  export declare class BaseObserver<T extends BaseListener = BaseListener> implements BaseObserverInterface<T> {
9
11
  protected listeners: Set<Partial<T>>;
10
12
  constructor();
11
- dispose(): void;
12
13
  /**
13
14
  * Register a listener for updates to the PowerSync client.
14
15
  */
@@ -1,9 +1,6 @@
1
1
  export class BaseObserver {
2
2
  listeners = new Set();
3
3
  constructor() { }
4
- dispose() {
5
- this.listeners.clear();
6
- }
7
4
  /**
8
5
  * Register a listener for updates to the PowerSync client.
9
6
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powersync/common",
3
- "version": "0.0.0-dev-20250715080712",
3
+ "version": "0.0.0-dev-20250715111940",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -1,25 +0,0 @@
1
- import { AbstractPowerSyncDatabase } from './AbstractPowerSyncDatabase.js';
2
- import { Query, StandardWatchedQueryOptions } from './Query.js';
3
- import { DifferentialQueryProcessor, DifferentialWatchedQueryOptions } from './watched/processors/DifferentialQueryProcessor.js';
4
- import { OnChangeQueryProcessor } from './watched/processors/OnChangeQueryProcessor.js';
5
- import { WatchCompatibleQuery, WatchedQueryOptions } from './watched/WatchedQuery.js';
6
- /**
7
- * @internal
8
- */
9
- export interface CustomQueryOptions<RowType> {
10
- db: AbstractPowerSyncDatabase;
11
- query: WatchCompatibleQuery<RowType[]>;
12
- }
13
- /**
14
- * @internal
15
- */
16
- export declare class CustomQuery<RowType> implements Query<RowType> {
17
- protected options: CustomQueryOptions<RowType>;
18
- constructor(options: CustomQueryOptions<RowType>);
19
- protected resolveOptions(options: WatchedQueryOptions): {
20
- reportFetching: boolean | undefined;
21
- throttleMs: number | undefined;
22
- };
23
- watch(watchOptions: StandardWatchedQueryOptions<RowType>): OnChangeQueryProcessor<RowType[]>;
24
- differentialWatch(differentialWatchOptions: DifferentialWatchedQueryOptions<RowType>): DifferentialQueryProcessor<RowType>;
25
- }
@@ -1,41 +0,0 @@
1
- import { FalsyComparator } from './watched/processors/comparators.js';
2
- import { DifferentialQueryProcessor } from './watched/processors/DifferentialQueryProcessor.js';
3
- import { OnChangeQueryProcessor } from './watched/processors/OnChangeQueryProcessor.js';
4
- import { DEFAULT_WATCH_QUERY_OPTIONS } from './watched/WatchedQuery.js';
5
- /**
6
- * @internal
7
- */
8
- export class CustomQuery {
9
- options;
10
- constructor(options) {
11
- this.options = options;
12
- }
13
- resolveOptions(options) {
14
- return {
15
- reportFetching: options?.reportFetching ?? DEFAULT_WATCH_QUERY_OPTIONS.reportFetching,
16
- throttleMs: options?.throttleMs ?? DEFAULT_WATCH_QUERY_OPTIONS.throttleMs
17
- };
18
- }
19
- watch(watchOptions) {
20
- return new OnChangeQueryProcessor({
21
- db: this.options.db,
22
- comparator: watchOptions?.comparator ?? FalsyComparator,
23
- placeholderData: watchOptions?.placeholderData ?? [],
24
- watchOptions: {
25
- ...this.resolveOptions(watchOptions),
26
- query: this.options.query
27
- }
28
- });
29
- }
30
- differentialWatch(differentialWatchOptions) {
31
- return new DifferentialQueryProcessor({
32
- db: this.options.db,
33
- differentiator: differentialWatchOptions?.differentiator,
34
- placeholderData: differentialWatchOptions?.placeholderData ?? [],
35
- watchOptions: {
36
- ...this.resolveOptions(differentialWatchOptions),
37
- query: this.options.query
38
- }
39
- });
40
- }
41
- }
@@ -1,79 +0,0 @@
1
- import { ArrayComparator } from './watched/processors/comparators.js';
2
- import { DifferentialWatchedQuery, DifferentialWatchedQueryOptions } from './watched/processors/DifferentialQueryProcessor.js';
3
- import { ComparisonWatchedQuery } from './watched/processors/OnChangeQueryProcessor.js';
4
- import { WatchedQueryOptions } from './watched/WatchedQuery.js';
5
- /**
6
- * Query parameters for {@link ArrayQueryDefinition#parameters}
7
- */
8
- export type QueryParam = string | number | boolean | null | undefined | bigint | Uint8Array;
9
- /**
10
- * Options for building a query with {@link AbstractPowerSyncDatabase#query}.
11
- * This query will be executed with {@link AbstractPowerSyncDatabase#getAll}.
12
- */
13
- export interface ArrayQueryDefinition<RowType = unknown> {
14
- sql: string;
15
- parameters?: ReadonlyArray<Readonly<QueryParam>>;
16
- /**
17
- * Maps the raw SQLite row to a custom typed object.
18
- * @example
19
- * ```javascript
20
- * mapper: (row) => ({
21
- * ...row,
22
- * created_at: new Date(row.created_at as string),
23
- * })
24
- * ```
25
- */
26
- mapper?: (row: Record<string, unknown>) => RowType;
27
- }
28
- /**
29
- * Options for {@link Query.watch}.
30
- */
31
- export interface StandardWatchedQueryOptions<RowType> extends WatchedQueryOptions {
32
- /**
33
- * Optional comparator which processes the items of an array of rows.
34
- * The comparator compares the result set rows by index using the {@link ArrayComparatorOptions#compareBy} function.
35
- * The comparator reports a changed result set as soon as a row does not match the previous result set.
36
- *
37
- * @example
38
- * ```javascript
39
- * comparator: new ArrayComparator({
40
- * compareBy: (item) => JSON.stringify(item)
41
- * })
42
- * ```
43
- */
44
- comparator?: ArrayComparator<RowType>;
45
- /**
46
- * The initial data state reported while the query is loading for the first time.
47
- * @default []
48
- */
49
- placeholderData?: RowType[];
50
- }
51
- export interface Query<RowType> {
52
- /**
53
- * Creates a {@link WatchedQuery} which watches and emits results of the linked query.
54
- *
55
- * By default the returned watched query will emit changes whenever a change to the underlying SQLite tables is made.
56
- * These changes might not be relevant to the query, but the query will emit a new result set.
57
- *
58
- * A {@link StandardWatchedQueryOptions#comparator} can be provided to limit the data emissions. The watched query will still
59
- * query the underlying DB on underlying table changes, but the result will only be emitted if the comparator detects a change in the results.
60
- *
61
- * The comparator in this method is optimized and returns early as soon as it detects a change. Each data emission will correlate to a change in the result set,
62
- * but note that the result set will not maintain internal object references to the previous result set. If internal object references are needed,
63
- * consider using {@link Query#differentialWatch} instead.
64
- */
65
- watch(options?: StandardWatchedQueryOptions<RowType>): ComparisonWatchedQuery<ReadonlyArray<Readonly<RowType>>>;
66
- /**
67
- * Creates a {@link WatchedQuery} which watches and emits results of the linked query.
68
- *
69
- * This query method watches for changes in the underlying SQLite tables and runs the query on each table change.
70
- * The difference between the current and previous result set is computed.
71
- * The watched query will not emit changes if the result set is identical to the previous result set.
72
- * If the result set is different, the watched query will emit the new result set and provide a detailed diff of the changes.
73
- *
74
- * The deep differentiation allows maintaining result set object references between result emissions.
75
- * The {@link DifferentialWatchedQuery#state} `data` array will contain the previous row references for unchanged rows.
76
- * A detailed diff of the changes can be accessed via {@link DifferentialWatchedQuery#state} `diff`.
77
- */
78
- differentialWatch(options?: DifferentialWatchedQueryOptions<RowType>): DifferentialWatchedQuery<RowType>;
79
- }
@@ -1 +0,0 @@
1
- export {};