@powersync/common 1.20.1 → 1.21.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/dist/bundle.mjs +3 -3
- package/lib/client/AbstractPowerSyncDatabase.d.ts +3 -1
- package/lib/client/AbstractPowerSyncDatabase.js +22 -14
- package/lib/client/runOnSchemaChange.d.ts +2 -0
- package/lib/client/runOnSchemaChange.js +23 -0
- package/lib/db/DBAdapter.d.ts +4 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +1 -1
|
@@ -76,6 +76,7 @@ export interface WatchOnChangeHandler {
|
|
|
76
76
|
}
|
|
77
77
|
export interface PowerSyncDBListener extends StreamingSyncImplementationListener {
|
|
78
78
|
initialized: () => void;
|
|
79
|
+
schemaChanged: (schema: Schema) => void;
|
|
79
80
|
}
|
|
80
81
|
export interface PowerSyncCloseOptions {
|
|
81
82
|
/**
|
|
@@ -92,6 +93,7 @@ export declare const DEFAULT_POWERSYNC_DB_OPTIONS: {
|
|
|
92
93
|
logger: Logger.ILogger;
|
|
93
94
|
crudUploadThrottleMs: number;
|
|
94
95
|
};
|
|
96
|
+
export declare const DEFAULT_CRUD_BATCH_LIMIT = 100;
|
|
95
97
|
/**
|
|
96
98
|
* Requesting nested or recursive locks can block the application in some circumstances.
|
|
97
99
|
* This default lock timeout will act as a failsafe to throw an error if a lock cannot
|
|
@@ -232,7 +234,7 @@ export declare abstract class AbstractPowerSyncDatabase extends BaseObserver<Pow
|
|
|
232
234
|
* data by transaction. One batch may contain data from multiple transactions,
|
|
233
235
|
* and a single transaction may be split over multiple batches.
|
|
234
236
|
*/
|
|
235
|
-
getCrudBatch(limit
|
|
237
|
+
getCrudBatch(limit?: number): Promise<CrudBatch | null>;
|
|
236
238
|
/**
|
|
237
239
|
* Get the next recorded transaction to upload.
|
|
238
240
|
*
|
|
@@ -14,6 +14,7 @@ import { CrudBatch } from './sync/bucket/CrudBatch.js';
|
|
|
14
14
|
import { CrudEntry } from './sync/bucket/CrudEntry.js';
|
|
15
15
|
import { CrudTransaction } from './sync/bucket/CrudTransaction.js';
|
|
16
16
|
import { DEFAULT_CRUD_UPLOAD_THROTTLE_MS } from './sync/stream/AbstractStreamingSyncImplementation.js';
|
|
17
|
+
import { runOnSchemaChange } from './runOnSchemaChange.js';
|
|
17
18
|
const POWERSYNC_TABLE_MATCH = /(^ps_data__|^ps_data_local__)/;
|
|
18
19
|
const DEFAULT_DISCONNECT_CLEAR_OPTIONS = {
|
|
19
20
|
clearLocal: true
|
|
@@ -27,6 +28,7 @@ export const DEFAULT_POWERSYNC_DB_OPTIONS = {
|
|
|
27
28
|
logger: Logger.get('PowerSyncDatabase'),
|
|
28
29
|
crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
|
|
29
30
|
};
|
|
31
|
+
export const DEFAULT_CRUD_BATCH_LIMIT = 100;
|
|
30
32
|
/**
|
|
31
33
|
* Requesting nested or recursive locks can block the application in some circumstances.
|
|
32
34
|
* This default lock timeout will act as a failsafe to throw an error if a lock cannot
|
|
@@ -210,6 +212,8 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
210
212
|
}
|
|
211
213
|
this._schema = schema;
|
|
212
214
|
await this.database.execute('SELECT powersync_replace_schema(?)', [JSON.stringify(this.schema.toJSON())]);
|
|
215
|
+
await this.database.refreshSchema();
|
|
216
|
+
this.iterateListeners(async (cb) => cb.schemaChanged?.(schema));
|
|
213
217
|
}
|
|
214
218
|
/**
|
|
215
219
|
* Wait for initialization to complete.
|
|
@@ -326,7 +330,7 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
326
330
|
* data by transaction. One batch may contain data from multiple transactions,
|
|
327
331
|
* and a single transaction may be split over multiple batches.
|
|
328
332
|
*/
|
|
329
|
-
async getCrudBatch(limit) {
|
|
333
|
+
async getCrudBatch(limit = DEFAULT_CRUD_BATCH_LIMIT) {
|
|
330
334
|
const result = await this.getAll(`SELECT id, tx_id, data FROM ${PSInternalTable.CRUD} ORDER BY id ASC LIMIT ?`, [limit + 1]);
|
|
331
335
|
const all = result.map((row) => CrudEntry.fromRow(row)) ?? [];
|
|
332
336
|
let haveMore = false;
|
|
@@ -502,7 +506,7 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
502
506
|
if (!onResult) {
|
|
503
507
|
throw new Error('onResult is required');
|
|
504
508
|
}
|
|
505
|
-
|
|
509
|
+
const watchQuery = async (abortSignal) => {
|
|
506
510
|
try {
|
|
507
511
|
const resolvedTables = await this.resolveTables(sql, parameters, options);
|
|
508
512
|
// Fetch initial data
|
|
@@ -521,13 +525,16 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
521
525
|
onError
|
|
522
526
|
}, {
|
|
523
527
|
...(options ?? {}),
|
|
524
|
-
tables: resolvedTables
|
|
528
|
+
tables: resolvedTables,
|
|
529
|
+
// Override the abort signal since we intercept it
|
|
530
|
+
signal: abortSignal
|
|
525
531
|
});
|
|
526
532
|
}
|
|
527
533
|
catch (error) {
|
|
528
534
|
onError?.(error);
|
|
529
535
|
}
|
|
530
|
-
}
|
|
536
|
+
};
|
|
537
|
+
runOnSchemaChange(watchQuery, this, options);
|
|
531
538
|
}
|
|
532
539
|
/**
|
|
533
540
|
* Execute a read query every time the source tables are modified.
|
|
@@ -536,17 +543,18 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
536
543
|
*/
|
|
537
544
|
watchWithAsyncGenerator(sql, parameters, options) {
|
|
538
545
|
return new EventIterator((eventOptions) => {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
tables: resolvedTables
|
|
546
|
-
})) {
|
|
547
|
-
eventOptions.push(await this.executeReadOnly(sql, parameters));
|
|
546
|
+
const handler = {
|
|
547
|
+
onResult: (result) => {
|
|
548
|
+
eventOptions.push(result);
|
|
549
|
+
},
|
|
550
|
+
onError: (error) => {
|
|
551
|
+
eventOptions.fail(error);
|
|
548
552
|
}
|
|
549
|
-
}
|
|
553
|
+
};
|
|
554
|
+
this.watchWithCallback(sql, parameters, handler, options);
|
|
555
|
+
options?.signal?.addEventListener('abort', () => {
|
|
556
|
+
eventOptions.stop();
|
|
557
|
+
});
|
|
550
558
|
});
|
|
551
559
|
}
|
|
552
560
|
async resolveTables(sql, parameters, options) {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function runOnSchemaChange(callback, db, options) {
|
|
2
|
+
const triggerWatchedQuery = () => {
|
|
3
|
+
const abortController = new AbortController();
|
|
4
|
+
let disposeSchemaListener = null;
|
|
5
|
+
const stopWatching = () => {
|
|
6
|
+
abortController.abort('Abort triggered');
|
|
7
|
+
disposeSchemaListener?.();
|
|
8
|
+
disposeSchemaListener = null;
|
|
9
|
+
// Stop listening to upstream abort for this watch
|
|
10
|
+
options?.signal?.removeEventListener('abort', stopWatching);
|
|
11
|
+
};
|
|
12
|
+
options?.signal?.addEventListener('abort', stopWatching);
|
|
13
|
+
disposeSchemaListener = db.registerListener({
|
|
14
|
+
schemaChanged: async () => {
|
|
15
|
+
stopWatching();
|
|
16
|
+
// Re trigger the watched query (recursively), setTimeout ensures that we don't modify the list of listeners while iterating through them
|
|
17
|
+
setTimeout(() => triggerWatchedQuery(), 0);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
callback(abortController.signal);
|
|
21
|
+
};
|
|
22
|
+
triggerWatchedQuery();
|
|
23
|
+
}
|
package/lib/db/DBAdapter.d.ts
CHANGED
|
@@ -90,6 +90,10 @@ export interface DBAdapter extends BaseObserverInterface<DBAdapterListener>, DBG
|
|
|
90
90
|
readTransaction: <T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions) => Promise<T>;
|
|
91
91
|
writeLock: <T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions) => Promise<T>;
|
|
92
92
|
writeTransaction: <T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions) => Promise<T>;
|
|
93
|
+
/**
|
|
94
|
+
* This method refreshes the schema information across all connections. This is for advanced use cases, and should generally not be needed.
|
|
95
|
+
*/
|
|
96
|
+
refreshSchema: () => Promise<void>;
|
|
93
97
|
}
|
|
94
98
|
export declare function isBatchedUpdateNotification(update: BatchedUpdateNotification | UpdateNotification): update is BatchedUpdateNotification;
|
|
95
99
|
export declare function extractTableUpdates(update: BatchedUpdateNotification | UpdateNotification): string[];
|
package/lib/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './client/SQLOpenFactory.js';
|
|
|
4
4
|
export * from './client/connection/PowerSyncBackendConnector.js';
|
|
5
5
|
export * from './client/connection/PowerSyncCredentials.js';
|
|
6
6
|
export * from './client/sync/bucket/BucketStorageAdapter.js';
|
|
7
|
+
export { runOnSchemaChange } from './client/runOnSchemaChange.js';
|
|
7
8
|
export { UpdateType, CrudEntry, OpId } from './client/sync/bucket/CrudEntry.js';
|
|
8
9
|
export * from './client/sync/bucket/SqliteBucketStorage.js';
|
|
9
10
|
export * from './client/sync/bucket/CrudBatch.js';
|
package/lib/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export * from './client/SQLOpenFactory.js';
|
|
|
4
4
|
export * from './client/connection/PowerSyncBackendConnector.js';
|
|
5
5
|
export * from './client/connection/PowerSyncCredentials.js';
|
|
6
6
|
export * from './client/sync/bucket/BucketStorageAdapter.js';
|
|
7
|
+
export { runOnSchemaChange } from './client/runOnSchemaChange.js';
|
|
7
8
|
export { UpdateType, CrudEntry } from './client/sync/bucket/CrudEntry.js';
|
|
8
9
|
export * from './client/sync/bucket/SqliteBucketStorage.js';
|
|
9
10
|
export * from './client/sync/bucket/CrudBatch.js';
|