@powersync/web 1.38.2 → 1.38.3
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/worker/SharedSyncImplementation.umd.js +548 -345
- package/dist/worker/SharedSyncImplementation.umd.js.map +1 -1
- package/dist/worker/WASQLiteDB.umd.js +548 -345
- package/dist/worker/WASQLiteDB.umd.js.map +1 -1
- package/lib/package.json +2 -2
- package/lib/src/attachments/IndexDBFileSystemAdapter.js +1 -0
- package/lib/src/attachments/IndexDBFileSystemAdapter.js.map +1 -0
- package/lib/src/db/NavigatorTriggerClaimManager.js +1 -0
- package/lib/src/db/NavigatorTriggerClaimManager.js.map +1 -0
- package/lib/src/db/PowerSyncDatabase.js +1 -0
- package/lib/src/db/PowerSyncDatabase.js.map +1 -0
- package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js +1 -0
- package/lib/src/db/adapters/AbstractWebPowerSyncDatabaseOpenFactory.js.map +1 -0
- package/lib/src/db/adapters/AsyncWebAdapter.js +1 -0
- package/lib/src/db/adapters/AsyncWebAdapter.js.map +1 -0
- package/lib/src/db/adapters/SSRDBAdapter.js +1 -0
- package/lib/src/db/adapters/SSRDBAdapter.js.map +1 -0
- package/lib/src/db/adapters/WebDBAdapter.js +1 -0
- package/lib/src/db/adapters/WebDBAdapter.js.map +1 -0
- package/lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js +1 -0
- package/lib/src/db/adapters/wa-sqlite/ConcurrentConnection.js.map +1 -0
- package/lib/src/db/adapters/wa-sqlite/DatabaseClient.js +1 -0
- package/lib/src/db/adapters/wa-sqlite/DatabaseClient.js.map +1 -0
- package/lib/src/db/adapters/wa-sqlite/DatabaseServer.js +1 -0
- package/lib/src/db/adapters/wa-sqlite/DatabaseServer.js.map +1 -0
- package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js +1 -0
- package/lib/src/db/adapters/wa-sqlite/RawSqliteConnection.js.map +1 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js +1 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLiteOpenFactory.js.map +1 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.js +1 -0
- package/lib/src/db/adapters/wa-sqlite/WASQLitePowerSyncDatabaseOpenFactory.js.map +1 -0
- package/lib/src/db/adapters/wa-sqlite/vfs.js +1 -0
- package/lib/src/db/adapters/wa-sqlite/vfs.js.map +1 -0
- package/lib/src/db/adapters/web-sql-flags.js +1 -0
- package/lib/src/db/adapters/web-sql-flags.js.map +1 -0
- package/lib/src/db/sync/SSRWebStreamingSyncImplementation.js +1 -0
- package/lib/src/db/sync/SSRWebStreamingSyncImplementation.js.map +1 -0
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js +1 -0
- package/lib/src/db/sync/SharedWebStreamingSyncImplementation.js.map +1 -0
- package/lib/src/db/sync/WebRemote.js +1 -0
- package/lib/src/db/sync/WebRemote.js.map +1 -0
- package/lib/src/db/sync/WebStreamingSyncImplementation.js +1 -0
- package/lib/src/db/sync/WebStreamingSyncImplementation.js.map +1 -0
- package/lib/src/db/sync/userAgent.js +1 -0
- package/lib/src/db/sync/userAgent.js.map +1 -0
- package/lib/src/index.js +1 -0
- package/lib/src/index.js.map +1 -0
- package/lib/src/shared/navigator.js +1 -0
- package/lib/src/shared/navigator.js.map +1 -0
- package/lib/src/shared/tab_close_signal.js +1 -0
- package/lib/src/shared/tab_close_signal.js.map +1 -0
- package/lib/src/worker/db/MultiDatabaseServer.js +1 -0
- package/lib/src/worker/db/MultiDatabaseServer.js.map +1 -0
- package/lib/src/worker/db/WASQLiteDB.worker.js +1 -0
- package/lib/src/worker/db/WASQLiteDB.worker.js.map +1 -0
- package/lib/src/worker/db/open-worker-database.js +1 -0
- package/lib/src/worker/db/open-worker-database.js.map +1 -0
- package/lib/src/worker/sync/AbstractSharedSyncClientProvider.js +1 -0
- package/lib/src/worker/sync/AbstractSharedSyncClientProvider.js.map +1 -0
- package/lib/src/worker/sync/BroadcastLogger.js +1 -0
- package/lib/src/worker/sync/BroadcastLogger.js.map +1 -0
- package/lib/src/worker/sync/SharedSyncImplementation.js +1 -0
- package/lib/src/worker/sync/SharedSyncImplementation.js.map +1 -0
- package/lib/src/worker/sync/SharedSyncImplementation.worker.js +1 -0
- package/lib/src/worker/sync/SharedSyncImplementation.worker.js.map +1 -0
- package/lib/src/worker/sync/WorkerClient.js +1 -0
- package/lib/src/worker/sync/WorkerClient.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -1733,7 +1733,10 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
1733
1733
|
/* harmony export */ sanitizeUUID: () => (/* binding */ sanitizeUUID),
|
|
1734
1734
|
/* harmony export */ timeoutSignal: () => (/* binding */ timeoutSignal)
|
|
1735
1735
|
/* harmony export */ });
|
|
1736
|
-
|
|
1736
|
+
/**
|
|
1737
|
+
* @see https://www.sqlite.org/lang_expr.html#castexpr
|
|
1738
|
+
* @public
|
|
1739
|
+
*/
|
|
1737
1740
|
var ColumnType;
|
|
1738
1741
|
(function (ColumnType) {
|
|
1739
1742
|
ColumnType["TEXT"] = "TEXT";
|
|
@@ -1749,14 +1752,24 @@ const integer = {
|
|
|
1749
1752
|
const real = {
|
|
1750
1753
|
type: ColumnType.REAL
|
|
1751
1754
|
};
|
|
1752
|
-
|
|
1753
|
-
|
|
1755
|
+
/**
|
|
1756
|
+
* powersync-sqlite-core limits the number of column per table to 1999, due to internal SQLite limits.
|
|
1757
|
+
* In earlier versions this was limited to 63.
|
|
1758
|
+
*
|
|
1759
|
+
* @internal
|
|
1760
|
+
*/
|
|
1754
1761
|
const MAX_AMOUNT_OF_COLUMNS = 1999;
|
|
1762
|
+
/**
|
|
1763
|
+
* @public
|
|
1764
|
+
*/
|
|
1755
1765
|
const column = {
|
|
1756
1766
|
text,
|
|
1757
1767
|
integer,
|
|
1758
1768
|
real
|
|
1759
1769
|
};
|
|
1770
|
+
/**
|
|
1771
|
+
* @public
|
|
1772
|
+
*/
|
|
1760
1773
|
class Column {
|
|
1761
1774
|
options;
|
|
1762
1775
|
constructor(options) {
|
|
@@ -1776,9 +1789,15 @@ class Column {
|
|
|
1776
1789
|
}
|
|
1777
1790
|
}
|
|
1778
1791
|
|
|
1792
|
+
/**
|
|
1793
|
+
* @internal
|
|
1794
|
+
*/
|
|
1779
1795
|
const DEFAULT_INDEX_COLUMN_OPTIONS = {
|
|
1780
1796
|
ascending: true
|
|
1781
1797
|
};
|
|
1798
|
+
/**
|
|
1799
|
+
* @public
|
|
1800
|
+
*/
|
|
1782
1801
|
class IndexedColumn {
|
|
1783
1802
|
options;
|
|
1784
1803
|
static createAscending(column) {
|
|
@@ -1805,9 +1824,15 @@ class IndexedColumn {
|
|
|
1805
1824
|
}
|
|
1806
1825
|
}
|
|
1807
1826
|
|
|
1827
|
+
/**
|
|
1828
|
+
* @internal
|
|
1829
|
+
*/
|
|
1808
1830
|
const DEFAULT_INDEX_OPTIONS = {
|
|
1809
1831
|
columns: []
|
|
1810
1832
|
};
|
|
1833
|
+
/**
|
|
1834
|
+
* @public
|
|
1835
|
+
*/
|
|
1811
1836
|
class Index {
|
|
1812
1837
|
options;
|
|
1813
1838
|
static createAscending(options, columnNames) {
|
|
@@ -1849,6 +1874,9 @@ function encodeTableOptions(options) {
|
|
|
1849
1874
|
};
|
|
1850
1875
|
}
|
|
1851
1876
|
|
|
1877
|
+
/**
|
|
1878
|
+
* @internal
|
|
1879
|
+
*/
|
|
1852
1880
|
const DEFAULT_TABLE_OPTIONS = {
|
|
1853
1881
|
indexes: [],
|
|
1854
1882
|
insertOnly: false,
|
|
@@ -1857,7 +1885,13 @@ const DEFAULT_TABLE_OPTIONS = {
|
|
|
1857
1885
|
trackMetadata: false,
|
|
1858
1886
|
ignoreEmptyUpdates: false
|
|
1859
1887
|
};
|
|
1888
|
+
/**
|
|
1889
|
+
* @internal
|
|
1890
|
+
*/
|
|
1860
1891
|
const InvalidSQLCharacters = /["'%,.#\s[\]]/;
|
|
1892
|
+
/**
|
|
1893
|
+
* @public
|
|
1894
|
+
*/
|
|
1861
1895
|
class Table {
|
|
1862
1896
|
options;
|
|
1863
1897
|
_mappedColumns;
|
|
@@ -2048,6 +2082,11 @@ class Table {
|
|
|
2048
2082
|
}
|
|
2049
2083
|
}
|
|
2050
2084
|
|
|
2085
|
+
/**
|
|
2086
|
+
* The default name of the local table storing attachment data.
|
|
2087
|
+
*
|
|
2088
|
+
* @alpha
|
|
2089
|
+
*/
|
|
2051
2090
|
const ATTACHMENT_TABLE = 'attachments';
|
|
2052
2091
|
/**
|
|
2053
2092
|
* Maps a database row to an AttachmentRecord.
|
|
@@ -2055,7 +2094,7 @@ const ATTACHMENT_TABLE = 'attachments';
|
|
|
2055
2094
|
* @param row - The database row object
|
|
2056
2095
|
* @returns The corresponding AttachmentRecord
|
|
2057
2096
|
*
|
|
2058
|
-
* @
|
|
2097
|
+
* @alpha
|
|
2059
2098
|
*/
|
|
2060
2099
|
function attachmentFromSql(row) {
|
|
2061
2100
|
return {
|
|
@@ -2073,7 +2112,7 @@ function attachmentFromSql(row) {
|
|
|
2073
2112
|
/**
|
|
2074
2113
|
* AttachmentState represents the current synchronization state of an attachment.
|
|
2075
2114
|
*
|
|
2076
|
-
* @
|
|
2115
|
+
* @alpha
|
|
2077
2116
|
*/
|
|
2078
2117
|
var AttachmentState;
|
|
2079
2118
|
(function (AttachmentState) {
|
|
@@ -2086,7 +2125,7 @@ var AttachmentState;
|
|
|
2086
2125
|
/**
|
|
2087
2126
|
* AttachmentTable defines the schema for the attachment queue table.
|
|
2088
2127
|
*
|
|
2089
|
-
* @
|
|
2128
|
+
* @alpha
|
|
2090
2129
|
*/
|
|
2091
2130
|
class AttachmentTable extends Table {
|
|
2092
2131
|
constructor(options) {
|
|
@@ -2114,7 +2153,8 @@ class AttachmentTable extends Table {
|
|
|
2114
2153
|
* Provides methods to query, insert, update, and delete attachment records with
|
|
2115
2154
|
* proper transaction management through PowerSync.
|
|
2116
2155
|
*
|
|
2117
|
-
* @
|
|
2156
|
+
* @experimental
|
|
2157
|
+
* @alpha
|
|
2118
2158
|
*/
|
|
2119
2159
|
class AttachmentContext {
|
|
2120
2160
|
/** PowerSync database instance for executing queries */
|
|
@@ -2336,6 +2376,9 @@ class AttachmentContext {
|
|
|
2336
2376
|
}
|
|
2337
2377
|
}
|
|
2338
2378
|
|
|
2379
|
+
/**
|
|
2380
|
+
* @public
|
|
2381
|
+
*/
|
|
2339
2382
|
var WatchedQueryListenerEvent;
|
|
2340
2383
|
(function (WatchedQueryListenerEvent) {
|
|
2341
2384
|
WatchedQueryListenerEvent["ON_DATA"] = "onData";
|
|
@@ -2344,176 +2387,18 @@ var WatchedQueryListenerEvent;
|
|
|
2344
2387
|
WatchedQueryListenerEvent["SETTINGS_WILL_UPDATE"] = "settingsWillUpdate";
|
|
2345
2388
|
WatchedQueryListenerEvent["CLOSED"] = "closed";
|
|
2346
2389
|
})(WatchedQueryListenerEvent || (WatchedQueryListenerEvent = {}));
|
|
2390
|
+
/**
|
|
2391
|
+
* @internal
|
|
2392
|
+
*/
|
|
2347
2393
|
const DEFAULT_WATCH_THROTTLE_MS = 30;
|
|
2394
|
+
/**
|
|
2395
|
+
* @internal
|
|
2396
|
+
*/
|
|
2348
2397
|
const DEFAULT_WATCH_QUERY_OPTIONS = {
|
|
2349
2398
|
throttleMs: DEFAULT_WATCH_THROTTLE_MS,
|
|
2350
2399
|
reportFetching: true
|
|
2351
2400
|
};
|
|
2352
2401
|
|
|
2353
|
-
/**
|
|
2354
|
-
* Orchestrates attachment synchronization between local and remote storage.
|
|
2355
|
-
* Handles uploads, downloads, deletions, and state transitions.
|
|
2356
|
-
*
|
|
2357
|
-
* @internal
|
|
2358
|
-
*/
|
|
2359
|
-
class SyncingService {
|
|
2360
|
-
attachmentService;
|
|
2361
|
-
localStorage;
|
|
2362
|
-
remoteStorage;
|
|
2363
|
-
logger;
|
|
2364
|
-
errorHandler;
|
|
2365
|
-
constructor(attachmentService, localStorage, remoteStorage, logger, errorHandler) {
|
|
2366
|
-
this.attachmentService = attachmentService;
|
|
2367
|
-
this.localStorage = localStorage;
|
|
2368
|
-
this.remoteStorage = remoteStorage;
|
|
2369
|
-
this.logger = logger;
|
|
2370
|
-
this.errorHandler = errorHandler;
|
|
2371
|
-
}
|
|
2372
|
-
/**
|
|
2373
|
-
* Processes attachments based on their state (upload, download, or delete).
|
|
2374
|
-
* All updates are saved in a single batch after processing.
|
|
2375
|
-
*
|
|
2376
|
-
* @param attachments - Array of attachment records to process
|
|
2377
|
-
* @param context - Attachment context for database operations
|
|
2378
|
-
* @returns Promise that resolves when all attachments have been processed and saved
|
|
2379
|
-
*/
|
|
2380
|
-
async processAttachments(attachments, context) {
|
|
2381
|
-
const updatedAttachments = [];
|
|
2382
|
-
for (const attachment of attachments) {
|
|
2383
|
-
switch (attachment.state) {
|
|
2384
|
-
case AttachmentState.QUEUED_UPLOAD:
|
|
2385
|
-
const uploaded = await this.uploadAttachment(attachment);
|
|
2386
|
-
updatedAttachments.push(uploaded);
|
|
2387
|
-
break;
|
|
2388
|
-
case AttachmentState.QUEUED_DOWNLOAD:
|
|
2389
|
-
const downloaded = await this.downloadAttachment(attachment);
|
|
2390
|
-
updatedAttachments.push(downloaded);
|
|
2391
|
-
break;
|
|
2392
|
-
case AttachmentState.QUEUED_DELETE:
|
|
2393
|
-
const deleted = await this.deleteAttachment(attachment, context);
|
|
2394
|
-
updatedAttachments.push(deleted);
|
|
2395
|
-
break;
|
|
2396
|
-
}
|
|
2397
|
-
}
|
|
2398
|
-
await context.saveAttachments(updatedAttachments);
|
|
2399
|
-
}
|
|
2400
|
-
/**
|
|
2401
|
-
* Uploads an attachment from local storage to remote storage.
|
|
2402
|
-
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
2403
|
-
*
|
|
2404
|
-
* @param attachment - The attachment record to upload
|
|
2405
|
-
* @returns Updated attachment record with new state
|
|
2406
|
-
* @throws Error if the attachment has no localUri
|
|
2407
|
-
*/
|
|
2408
|
-
async uploadAttachment(attachment) {
|
|
2409
|
-
this.logger.info(`Uploading attachment ${attachment.filename}`);
|
|
2410
|
-
try {
|
|
2411
|
-
if (attachment.localUri == null) {
|
|
2412
|
-
throw new Error(`No localUri for attachment ${attachment.id}`);
|
|
2413
|
-
}
|
|
2414
|
-
const fileBlob = await this.localStorage.readFile(attachment.localUri);
|
|
2415
|
-
await this.remoteStorage.uploadFile(fileBlob, attachment);
|
|
2416
|
-
return {
|
|
2417
|
-
...attachment,
|
|
2418
|
-
state: AttachmentState.SYNCED,
|
|
2419
|
-
hasSynced: true
|
|
2420
|
-
};
|
|
2421
|
-
}
|
|
2422
|
-
catch (error) {
|
|
2423
|
-
const shouldRetry = (await this.errorHandler?.onUploadError(attachment, error)) ?? true;
|
|
2424
|
-
if (!shouldRetry) {
|
|
2425
|
-
return {
|
|
2426
|
-
...attachment,
|
|
2427
|
-
state: AttachmentState.ARCHIVED
|
|
2428
|
-
};
|
|
2429
|
-
}
|
|
2430
|
-
return attachment;
|
|
2431
|
-
}
|
|
2432
|
-
}
|
|
2433
|
-
/**
|
|
2434
|
-
* Downloads an attachment from remote storage to local storage.
|
|
2435
|
-
* Retrieves the file, converts to base64, and saves locally.
|
|
2436
|
-
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
2437
|
-
*
|
|
2438
|
-
* @param attachment - The attachment record to download
|
|
2439
|
-
* @returns Updated attachment record with local URI and new state
|
|
2440
|
-
*/
|
|
2441
|
-
async downloadAttachment(attachment) {
|
|
2442
|
-
this.logger.info(`Downloading attachment ${attachment.filename}`);
|
|
2443
|
-
try {
|
|
2444
|
-
const fileData = await this.remoteStorage.downloadFile(attachment);
|
|
2445
|
-
const localUri = this.localStorage.getLocalUri(attachment.filename);
|
|
2446
|
-
await this.localStorage.saveFile(localUri, fileData);
|
|
2447
|
-
return {
|
|
2448
|
-
...attachment,
|
|
2449
|
-
state: AttachmentState.SYNCED,
|
|
2450
|
-
localUri: localUri,
|
|
2451
|
-
hasSynced: true
|
|
2452
|
-
};
|
|
2453
|
-
}
|
|
2454
|
-
catch (error) {
|
|
2455
|
-
const shouldRetry = (await this.errorHandler?.onDownloadError(attachment, error)) ?? true;
|
|
2456
|
-
if (!shouldRetry) {
|
|
2457
|
-
return {
|
|
2458
|
-
...attachment,
|
|
2459
|
-
state: AttachmentState.ARCHIVED
|
|
2460
|
-
};
|
|
2461
|
-
}
|
|
2462
|
-
return attachment;
|
|
2463
|
-
}
|
|
2464
|
-
}
|
|
2465
|
-
/**
|
|
2466
|
-
* Deletes an attachment from both remote and local storage.
|
|
2467
|
-
* Removes the remote file, local file (if exists), and the attachment record.
|
|
2468
|
-
* On failure, defers to error handler or archives.
|
|
2469
|
-
*
|
|
2470
|
-
* @param attachment - The attachment record to delete
|
|
2471
|
-
* @param context - Attachment context for database operations
|
|
2472
|
-
* @returns Updated attachment record
|
|
2473
|
-
*/
|
|
2474
|
-
async deleteAttachment(attachment, context) {
|
|
2475
|
-
try {
|
|
2476
|
-
await this.remoteStorage.deleteFile(attachment);
|
|
2477
|
-
if (attachment.localUri) {
|
|
2478
|
-
await this.localStorage.deleteFile(attachment.localUri);
|
|
2479
|
-
}
|
|
2480
|
-
await context.deleteAttachment(attachment.id);
|
|
2481
|
-
return {
|
|
2482
|
-
...attachment,
|
|
2483
|
-
state: AttachmentState.ARCHIVED
|
|
2484
|
-
};
|
|
2485
|
-
}
|
|
2486
|
-
catch (error) {
|
|
2487
|
-
const shouldRetry = (await this.errorHandler?.onDeleteError(attachment, error)) ?? true;
|
|
2488
|
-
if (!shouldRetry) {
|
|
2489
|
-
return {
|
|
2490
|
-
...attachment,
|
|
2491
|
-
state: AttachmentState.ARCHIVED
|
|
2492
|
-
};
|
|
2493
|
-
}
|
|
2494
|
-
return attachment;
|
|
2495
|
-
}
|
|
2496
|
-
}
|
|
2497
|
-
/**
|
|
2498
|
-
* Performs cleanup of archived attachments by removing their local files and records.
|
|
2499
|
-
* Errors during local file deletion are logged but do not prevent record deletion.
|
|
2500
|
-
*/
|
|
2501
|
-
async deleteArchivedAttachments(context) {
|
|
2502
|
-
return await context.deleteArchivedAttachments(async (archivedAttachments) => {
|
|
2503
|
-
for (const attachment of archivedAttachments) {
|
|
2504
|
-
if (attachment.localUri) {
|
|
2505
|
-
try {
|
|
2506
|
-
await this.localStorage.deleteFile(attachment.localUri);
|
|
2507
|
-
}
|
|
2508
|
-
catch (error) {
|
|
2509
|
-
this.logger.error('Error deleting local file for archived attachment', error);
|
|
2510
|
-
}
|
|
2511
|
-
}
|
|
2512
|
-
}
|
|
2513
|
-
});
|
|
2514
|
-
}
|
|
2515
|
-
}
|
|
2516
|
-
|
|
2517
2402
|
/**
|
|
2518
2403
|
* A simple fixed-capacity queue implementation.
|
|
2519
2404
|
*
|
|
@@ -2670,93 +2555,260 @@ class Semaphore {
|
|
|
2670
2555
|
return { release, item: items[0] };
|
|
2671
2556
|
}
|
|
2672
2557
|
/**
|
|
2673
|
-
* Requests access to all items from the pool.
|
|
2558
|
+
* Requests access to all items from the pool.
|
|
2559
|
+
*
|
|
2560
|
+
* The returned `release` callback must be invoked to return items into the pool.
|
|
2561
|
+
*/
|
|
2562
|
+
requestAll(abort) {
|
|
2563
|
+
return this.requestPermits(this.size, abort);
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
/**
|
|
2567
|
+
* An asynchronous mutex implementation.
|
|
2568
|
+
*
|
|
2569
|
+
* @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
|
|
2570
|
+
*/
|
|
2571
|
+
class Mutex {
|
|
2572
|
+
inner = new Semaphore([null]);
|
|
2573
|
+
async acquire(abort) {
|
|
2574
|
+
const { release } = await this.inner.requestOne(abort);
|
|
2575
|
+
return release;
|
|
2576
|
+
}
|
|
2577
|
+
async runExclusive(fn, abort) {
|
|
2578
|
+
const returnMutex = await this.acquire(abort);
|
|
2579
|
+
try {
|
|
2580
|
+
return await fn();
|
|
2581
|
+
}
|
|
2582
|
+
finally {
|
|
2583
|
+
returnMutex();
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
/**
|
|
2588
|
+
* @internal
|
|
2589
|
+
*/
|
|
2590
|
+
function timeoutSignal(timeout) {
|
|
2591
|
+
if (timeout == null)
|
|
2592
|
+
return;
|
|
2593
|
+
if ('timeout' in AbortSignal)
|
|
2594
|
+
return AbortSignal.timeout(timeout);
|
|
2595
|
+
const controller = new AbortController();
|
|
2596
|
+
setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
|
|
2597
|
+
return controller.signal;
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
/**
|
|
2601
|
+
* Service for querying and watching attachment records in the database.
|
|
2602
|
+
*
|
|
2603
|
+
* @internal
|
|
2604
|
+
*/
|
|
2605
|
+
class AttachmentService {
|
|
2606
|
+
db;
|
|
2607
|
+
logger;
|
|
2608
|
+
tableName;
|
|
2609
|
+
mutex = new Mutex();
|
|
2610
|
+
context;
|
|
2611
|
+
constructor(db, logger, tableName = 'attachments', archivedCacheLimit = 100) {
|
|
2612
|
+
this.db = db;
|
|
2613
|
+
this.logger = logger;
|
|
2614
|
+
this.tableName = tableName;
|
|
2615
|
+
this.context = new AttachmentContext(db, tableName, logger, archivedCacheLimit);
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Creates a differential watch query for active attachments requiring synchronization.
|
|
2619
|
+
* @returns Watch query that emits changes for queued uploads, downloads, and deletes
|
|
2620
|
+
*/
|
|
2621
|
+
watchActiveAttachments({ throttleMs } = {}) {
|
|
2622
|
+
this.logger.info('Watching active attachments...');
|
|
2623
|
+
const watch = this.db
|
|
2624
|
+
.query({
|
|
2625
|
+
sql: /* sql */ `
|
|
2626
|
+
SELECT
|
|
2627
|
+
*
|
|
2628
|
+
FROM
|
|
2629
|
+
${this.tableName}
|
|
2630
|
+
WHERE
|
|
2631
|
+
state = ?
|
|
2632
|
+
OR state = ?
|
|
2633
|
+
OR state = ?
|
|
2634
|
+
ORDER BY
|
|
2635
|
+
timestamp ASC
|
|
2636
|
+
`,
|
|
2637
|
+
parameters: [AttachmentState.QUEUED_UPLOAD, AttachmentState.QUEUED_DOWNLOAD, AttachmentState.QUEUED_DELETE]
|
|
2638
|
+
})
|
|
2639
|
+
.differentialWatch({ throttleMs });
|
|
2640
|
+
return watch;
|
|
2641
|
+
}
|
|
2642
|
+
/**
|
|
2643
|
+
* Executes a callback with exclusive access to the attachment context.
|
|
2644
|
+
*/
|
|
2645
|
+
async withContext(callback) {
|
|
2646
|
+
return this.mutex.runExclusive(async () => {
|
|
2647
|
+
return callback(this.context);
|
|
2648
|
+
});
|
|
2649
|
+
}
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2652
|
+
/**
|
|
2653
|
+
* Orchestrates attachment synchronization between local and remote storage.
|
|
2654
|
+
* Handles uploads, downloads, deletions, and state transitions.
|
|
2655
|
+
*
|
|
2656
|
+
* @internal
|
|
2657
|
+
*/
|
|
2658
|
+
class SyncingService {
|
|
2659
|
+
attachmentService;
|
|
2660
|
+
localStorage;
|
|
2661
|
+
remoteStorage;
|
|
2662
|
+
logger;
|
|
2663
|
+
errorHandler;
|
|
2664
|
+
constructor(attachmentService, localStorage, remoteStorage, logger, errorHandler) {
|
|
2665
|
+
this.attachmentService = attachmentService;
|
|
2666
|
+
this.localStorage = localStorage;
|
|
2667
|
+
this.remoteStorage = remoteStorage;
|
|
2668
|
+
this.logger = logger;
|
|
2669
|
+
this.errorHandler = errorHandler;
|
|
2670
|
+
}
|
|
2671
|
+
/**
|
|
2672
|
+
* Processes attachments based on their state (upload, download, or delete).
|
|
2673
|
+
* All updates are saved in a single batch after processing.
|
|
2674
|
+
*
|
|
2675
|
+
* @param attachments - Array of attachment records to process
|
|
2676
|
+
* @param context - Attachment context for database operations
|
|
2677
|
+
* @returns Promise that resolves when all attachments have been processed and saved
|
|
2678
|
+
*/
|
|
2679
|
+
async processAttachments(attachments, context) {
|
|
2680
|
+
const updatedAttachments = [];
|
|
2681
|
+
for (const attachment of attachments) {
|
|
2682
|
+
switch (attachment.state) {
|
|
2683
|
+
case AttachmentState.QUEUED_UPLOAD:
|
|
2684
|
+
const uploaded = await this.uploadAttachment(attachment);
|
|
2685
|
+
updatedAttachments.push(uploaded);
|
|
2686
|
+
break;
|
|
2687
|
+
case AttachmentState.QUEUED_DOWNLOAD:
|
|
2688
|
+
const downloaded = await this.downloadAttachment(attachment);
|
|
2689
|
+
updatedAttachments.push(downloaded);
|
|
2690
|
+
break;
|
|
2691
|
+
case AttachmentState.QUEUED_DELETE:
|
|
2692
|
+
const deleted = await this.deleteAttachment(attachment, context);
|
|
2693
|
+
updatedAttachments.push(deleted);
|
|
2694
|
+
break;
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
await context.saveAttachments(updatedAttachments);
|
|
2698
|
+
}
|
|
2699
|
+
/**
|
|
2700
|
+
* Uploads an attachment from local storage to remote storage.
|
|
2701
|
+
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
2702
|
+
*
|
|
2703
|
+
* @param attachment - The attachment record to upload
|
|
2704
|
+
* @returns Updated attachment record with new state
|
|
2705
|
+
* @throws Error if the attachment has no localUri
|
|
2706
|
+
*/
|
|
2707
|
+
async uploadAttachment(attachment) {
|
|
2708
|
+
this.logger.info(`Uploading attachment ${attachment.filename}`);
|
|
2709
|
+
try {
|
|
2710
|
+
if (attachment.localUri == null) {
|
|
2711
|
+
throw new Error(`No localUri for attachment ${attachment.id}`);
|
|
2712
|
+
}
|
|
2713
|
+
const fileBlob = await this.localStorage.readFile(attachment.localUri);
|
|
2714
|
+
await this.remoteStorage.uploadFile(fileBlob, attachment);
|
|
2715
|
+
return {
|
|
2716
|
+
...attachment,
|
|
2717
|
+
state: AttachmentState.SYNCED,
|
|
2718
|
+
hasSynced: true
|
|
2719
|
+
};
|
|
2720
|
+
}
|
|
2721
|
+
catch (error) {
|
|
2722
|
+
const shouldRetry = (await this.errorHandler?.onUploadError(attachment, error)) ?? true;
|
|
2723
|
+
if (!shouldRetry) {
|
|
2724
|
+
return {
|
|
2725
|
+
...attachment,
|
|
2726
|
+
state: AttachmentState.ARCHIVED
|
|
2727
|
+
};
|
|
2728
|
+
}
|
|
2729
|
+
return attachment;
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
/**
|
|
2733
|
+
* Downloads an attachment from remote storage to local storage.
|
|
2734
|
+
* Retrieves the file, converts to base64, and saves locally.
|
|
2735
|
+
* On success, marks as SYNCED. On failure, defers to error handler or archives.
|
|
2736
|
+
*
|
|
2737
|
+
* @param attachment - The attachment record to download
|
|
2738
|
+
* @returns Updated attachment record with local URI and new state
|
|
2739
|
+
*/
|
|
2740
|
+
async downloadAttachment(attachment) {
|
|
2741
|
+
this.logger.info(`Downloading attachment ${attachment.filename}`);
|
|
2742
|
+
try {
|
|
2743
|
+
const fileData = await this.remoteStorage.downloadFile(attachment);
|
|
2744
|
+
const localUri = this.localStorage.getLocalUri(attachment.filename);
|
|
2745
|
+
await this.localStorage.saveFile(localUri, fileData);
|
|
2746
|
+
return {
|
|
2747
|
+
...attachment,
|
|
2748
|
+
state: AttachmentState.SYNCED,
|
|
2749
|
+
localUri: localUri,
|
|
2750
|
+
hasSynced: true
|
|
2751
|
+
};
|
|
2752
|
+
}
|
|
2753
|
+
catch (error) {
|
|
2754
|
+
const shouldRetry = (await this.errorHandler?.onDownloadError(attachment, error)) ?? true;
|
|
2755
|
+
if (!shouldRetry) {
|
|
2756
|
+
return {
|
|
2757
|
+
...attachment,
|
|
2758
|
+
state: AttachmentState.ARCHIVED
|
|
2759
|
+
};
|
|
2760
|
+
}
|
|
2761
|
+
return attachment;
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
/**
|
|
2765
|
+
* Deletes an attachment from both remote and local storage.
|
|
2766
|
+
* Removes the remote file, local file (if exists), and the attachment record.
|
|
2767
|
+
* On failure, defers to error handler or archives.
|
|
2674
2768
|
*
|
|
2675
|
-
*
|
|
2769
|
+
* @param attachment - The attachment record to delete
|
|
2770
|
+
* @param context - Attachment context for database operations
|
|
2771
|
+
* @returns Updated attachment record
|
|
2676
2772
|
*/
|
|
2677
|
-
|
|
2678
|
-
return this.requestPermits(this.size, abort);
|
|
2679
|
-
}
|
|
2680
|
-
}
|
|
2681
|
-
/**
|
|
2682
|
-
* An asynchronous mutex implementation.
|
|
2683
|
-
*
|
|
2684
|
-
* @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
|
|
2685
|
-
*/
|
|
2686
|
-
class Mutex {
|
|
2687
|
-
inner = new Semaphore([null]);
|
|
2688
|
-
async acquire(abort) {
|
|
2689
|
-
const { release } = await this.inner.requestOne(abort);
|
|
2690
|
-
return release;
|
|
2691
|
-
}
|
|
2692
|
-
async runExclusive(fn, abort) {
|
|
2693
|
-
const returnMutex = await this.acquire(abort);
|
|
2773
|
+
async deleteAttachment(attachment, context) {
|
|
2694
2774
|
try {
|
|
2695
|
-
|
|
2775
|
+
await this.remoteStorage.deleteFile(attachment);
|
|
2776
|
+
if (attachment.localUri) {
|
|
2777
|
+
await this.localStorage.deleteFile(attachment.localUri);
|
|
2778
|
+
}
|
|
2779
|
+
await context.deleteAttachment(attachment.id);
|
|
2780
|
+
return {
|
|
2781
|
+
...attachment,
|
|
2782
|
+
state: AttachmentState.ARCHIVED
|
|
2783
|
+
};
|
|
2696
2784
|
}
|
|
2697
|
-
|
|
2698
|
-
|
|
2785
|
+
catch (error) {
|
|
2786
|
+
const shouldRetry = (await this.errorHandler?.onDeleteError(attachment, error)) ?? true;
|
|
2787
|
+
if (!shouldRetry) {
|
|
2788
|
+
return {
|
|
2789
|
+
...attachment,
|
|
2790
|
+
state: AttachmentState.ARCHIVED
|
|
2791
|
+
};
|
|
2792
|
+
}
|
|
2793
|
+
return attachment;
|
|
2699
2794
|
}
|
|
2700
2795
|
}
|
|
2701
|
-
}
|
|
2702
|
-
function timeoutSignal(timeout) {
|
|
2703
|
-
if (timeout == null)
|
|
2704
|
-
return;
|
|
2705
|
-
if ('timeout' in AbortSignal)
|
|
2706
|
-
return AbortSignal.timeout(timeout);
|
|
2707
|
-
const controller = new AbortController();
|
|
2708
|
-
setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
|
|
2709
|
-
return controller.signal;
|
|
2710
|
-
}
|
|
2711
|
-
|
|
2712
|
-
/**
|
|
2713
|
-
* Service for querying and watching attachment records in the database.
|
|
2714
|
-
*
|
|
2715
|
-
* @internal
|
|
2716
|
-
*/
|
|
2717
|
-
class AttachmentService {
|
|
2718
|
-
db;
|
|
2719
|
-
logger;
|
|
2720
|
-
tableName;
|
|
2721
|
-
mutex = new Mutex();
|
|
2722
|
-
context;
|
|
2723
|
-
constructor(db, logger, tableName = 'attachments', archivedCacheLimit = 100) {
|
|
2724
|
-
this.db = db;
|
|
2725
|
-
this.logger = logger;
|
|
2726
|
-
this.tableName = tableName;
|
|
2727
|
-
this.context = new AttachmentContext(db, tableName, logger, archivedCacheLimit);
|
|
2728
|
-
}
|
|
2729
|
-
/**
|
|
2730
|
-
* Creates a differential watch query for active attachments requiring synchronization.
|
|
2731
|
-
* @returns Watch query that emits changes for queued uploads, downloads, and deletes
|
|
2732
|
-
*/
|
|
2733
|
-
watchActiveAttachments({ throttleMs } = {}) {
|
|
2734
|
-
this.logger.info('Watching active attachments...');
|
|
2735
|
-
const watch = this.db
|
|
2736
|
-
.query({
|
|
2737
|
-
sql: /* sql */ `
|
|
2738
|
-
SELECT
|
|
2739
|
-
*
|
|
2740
|
-
FROM
|
|
2741
|
-
${this.tableName}
|
|
2742
|
-
WHERE
|
|
2743
|
-
state = ?
|
|
2744
|
-
OR state = ?
|
|
2745
|
-
OR state = ?
|
|
2746
|
-
ORDER BY
|
|
2747
|
-
timestamp ASC
|
|
2748
|
-
`,
|
|
2749
|
-
parameters: [AttachmentState.QUEUED_UPLOAD, AttachmentState.QUEUED_DOWNLOAD, AttachmentState.QUEUED_DELETE]
|
|
2750
|
-
})
|
|
2751
|
-
.differentialWatch({ throttleMs });
|
|
2752
|
-
return watch;
|
|
2753
|
-
}
|
|
2754
2796
|
/**
|
|
2755
|
-
*
|
|
2797
|
+
* Performs cleanup of archived attachments by removing their local files and records.
|
|
2798
|
+
* Errors during local file deletion are logged but do not prevent record deletion.
|
|
2756
2799
|
*/
|
|
2757
|
-
async
|
|
2758
|
-
return
|
|
2759
|
-
|
|
2800
|
+
async deleteArchivedAttachments(context) {
|
|
2801
|
+
return await context.deleteArchivedAttachments(async (archivedAttachments) => {
|
|
2802
|
+
for (const attachment of archivedAttachments) {
|
|
2803
|
+
if (attachment.localUri) {
|
|
2804
|
+
try {
|
|
2805
|
+
await this.localStorage.deleteFile(attachment.localUri);
|
|
2806
|
+
}
|
|
2807
|
+
catch (error) {
|
|
2808
|
+
this.logger.error('Error deleting local file for archived attachment', error);
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2760
2812
|
});
|
|
2761
2813
|
}
|
|
2762
2814
|
}
|
|
@@ -2817,16 +2869,6 @@ class AttachmentQueue {
|
|
|
2817
2869
|
* Creates a new AttachmentQueue instance.
|
|
2818
2870
|
*
|
|
2819
2871
|
* @param options - Configuration options
|
|
2820
|
-
* @param options.db - PowerSync database instance
|
|
2821
|
-
* @param options.remoteStorage - Remote storage adapter for upload/download operations
|
|
2822
|
-
* @param options.localStorage - Local storage adapter for file persistence
|
|
2823
|
-
* @param options.watchAttachments - Callback for monitoring attachment changes in your data model
|
|
2824
|
-
* @param options.tableName - Name of the table to store attachment records. Default: 'ps_attachment_queue'
|
|
2825
|
-
* @param options.logger - Logger instance. Defaults to db.logger
|
|
2826
|
-
* @param options.syncIntervalMs - Periodic polling interval in milliseconds for retrying failed uploads/downloads. Default: 30000
|
|
2827
|
-
* @param options.syncThrottleDuration - Throttle duration in milliseconds for the reactive watch query that detects attachment changes. Prevents rapid-fire syncs during bulk changes. Default: 30
|
|
2828
|
-
* @param options.downloadAttachments - Whether to automatically download remote attachments. Default: true
|
|
2829
|
-
* @param options.archivedCacheLimit - Maximum archived attachments before cleanup. Default: 100
|
|
2830
2872
|
*/
|
|
2831
2873
|
constructor({ db, localStorage, remoteStorage, watchAttachments, logger, tableName = ATTACHMENT_TABLE, syncIntervalMs = 30 * 1000, syncThrottleDuration = DEFAULT_WATCH_THROTTLE_MS, downloadAttachments = true, archivedCacheLimit = 100, errorHandler }) {
|
|
2832
2874
|
this.db = db;
|
|
@@ -2915,6 +2957,7 @@ class AttachmentQueue {
|
|
|
2915
2957
|
state: AttachmentState.QUEUED_DOWNLOAD,
|
|
2916
2958
|
hasSynced: false,
|
|
2917
2959
|
metaData: watchedAttachment.metaData,
|
|
2960
|
+
mediaType: watchedAttachment.mediaType,
|
|
2918
2961
|
timestamp: new Date().getTime()
|
|
2919
2962
|
});
|
|
2920
2963
|
continue;
|
|
@@ -3002,17 +3045,24 @@ class AttachmentQueue {
|
|
|
3002
3045
|
this.statusListenerDispose = undefined;
|
|
3003
3046
|
}
|
|
3004
3047
|
}
|
|
3048
|
+
/**
|
|
3049
|
+
* Provides an {@link AttachmentContext} to a callback.
|
|
3050
|
+
*
|
|
3051
|
+
* The callback runs while the attachment queue mutex is held. Do not call
|
|
3052
|
+
* other {@link AttachmentQueue} methods from within the callback, as they may
|
|
3053
|
+
* attempt to acquire the same mutex and block indefinitely.
|
|
3054
|
+
*/
|
|
3055
|
+
withAttachmentContext(callback) {
|
|
3056
|
+
/**
|
|
3057
|
+
* AttachmentService is internal and private in this class.
|
|
3058
|
+
* We only need to expose its locking and context functionality for extending classes.
|
|
3059
|
+
*/
|
|
3060
|
+
return this.attachmentService.withContext(callback);
|
|
3061
|
+
}
|
|
3005
3062
|
/**
|
|
3006
3063
|
* Saves a file to local storage and queues it for upload to remote storage.
|
|
3007
3064
|
*
|
|
3008
3065
|
* @param options - File save options
|
|
3009
|
-
* @param options.data - The file data as ArrayBuffer, Blob, or base64 string
|
|
3010
|
-
* @param options.fileExtension - File extension (e.g., 'jpg', 'pdf')
|
|
3011
|
-
* @param options.mediaType - MIME type of the file (e.g., 'image/jpeg')
|
|
3012
|
-
* @param options.metaData - Optional metadata to associate with the attachment
|
|
3013
|
-
* @param options.id - Optional custom ID. If not provided, a UUID will be generated
|
|
3014
|
-
* @param options.updateHook - Optional callback to execute additional database operations
|
|
3015
|
-
* within the same transaction as the attachment creation
|
|
3016
3066
|
* @returns Promise resolving to the created attachment record
|
|
3017
3067
|
*/
|
|
3018
3068
|
async saveFile({ data, fileExtension, mediaType, metaData, id, updateHook }) {
|
|
@@ -3125,6 +3175,9 @@ class AttachmentQueue {
|
|
|
3125
3175
|
}
|
|
3126
3176
|
}
|
|
3127
3177
|
|
|
3178
|
+
/**
|
|
3179
|
+
* @alpha
|
|
3180
|
+
*/
|
|
3128
3181
|
var EncodingType;
|
|
3129
3182
|
(function (EncodingType) {
|
|
3130
3183
|
EncodingType["UTF8"] = "utf8";
|
|
@@ -3588,7 +3641,9 @@ var Logger = /*@__PURE__*/getDefaultExportFromCjs(loggerExports);
|
|
|
3588
3641
|
* different SQLite DB implementations.
|
|
3589
3642
|
*/
|
|
3590
3643
|
/**
|
|
3591
|
-
* Implements {@link DBGetUtils} on a {@link
|
|
3644
|
+
* Implements {@link DBGetUtils} on a {@link SqlExecutor}.
|
|
3645
|
+
*
|
|
3646
|
+
* @internal
|
|
3592
3647
|
*/
|
|
3593
3648
|
function DBGetUtilsDefaultMixin(Base) {
|
|
3594
3649
|
return class extends Base {
|
|
@@ -3632,6 +3687,8 @@ function DBGetUtilsDefaultMixin(Base) {
|
|
|
3632
3687
|
}
|
|
3633
3688
|
/**
|
|
3634
3689
|
* Update table operation numbers from SQLite
|
|
3690
|
+
*
|
|
3691
|
+
* @public
|
|
3635
3692
|
*/
|
|
3636
3693
|
var RowUpdateType;
|
|
3637
3694
|
(function (RowUpdateType) {
|
|
@@ -3640,8 +3697,10 @@ var RowUpdateType;
|
|
|
3640
3697
|
RowUpdateType[RowUpdateType["SQLITE_UPDATE"] = 23] = "SQLITE_UPDATE";
|
|
3641
3698
|
})(RowUpdateType || (RowUpdateType = {}));
|
|
3642
3699
|
/**
|
|
3643
|
-
* A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool
|
|
3644
|
-
* {@link ConnectionPool
|
|
3700
|
+
* A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool#readLock} and
|
|
3701
|
+
* {@link ConnectionPool#writeLock}.
|
|
3702
|
+
*
|
|
3703
|
+
* @internal
|
|
3645
3704
|
*/
|
|
3646
3705
|
function DBAdapterDefaultMixin(Base) {
|
|
3647
3706
|
return class extends Base {
|
|
@@ -3729,9 +3788,15 @@ class TransactionImplementation extends DBGetUtilsDefaultMixin(BaseTransaction)
|
|
|
3729
3788
|
}
|
|
3730
3789
|
}
|
|
3731
3790
|
}
|
|
3791
|
+
/**
|
|
3792
|
+
* @internal
|
|
3793
|
+
*/
|
|
3732
3794
|
function isBatchedUpdateNotification(update) {
|
|
3733
3795
|
return 'tables' in update;
|
|
3734
3796
|
}
|
|
3797
|
+
/**
|
|
3798
|
+
* @internal
|
|
3799
|
+
*/
|
|
3735
3800
|
function extractTableUpdates(update) {
|
|
3736
3801
|
return isBatchedUpdateNotification(update) ? update.tables : [update.table];
|
|
3737
3802
|
}
|
|
@@ -3759,6 +3824,8 @@ const FULL_SYNC_PRIORITY = 2147483647;
|
|
|
3759
3824
|
*
|
|
3760
3825
|
* Also note that data is downloaded in bulk, which means that individual counters are unlikely
|
|
3761
3826
|
* to be updated one-by-one.
|
|
3827
|
+
*
|
|
3828
|
+
* @public
|
|
3762
3829
|
*/
|
|
3763
3830
|
class SyncProgress {
|
|
3764
3831
|
internal;
|
|
@@ -3797,6 +3864,9 @@ class SyncProgress {
|
|
|
3797
3864
|
}
|
|
3798
3865
|
}
|
|
3799
3866
|
|
|
3867
|
+
/**
|
|
3868
|
+
* @public
|
|
3869
|
+
*/
|
|
3800
3870
|
class SyncStatus {
|
|
3801
3871
|
options;
|
|
3802
3872
|
constructor(options) {
|
|
@@ -3807,6 +3877,8 @@ class SyncStatus {
|
|
|
3807
3877
|
* implementation).
|
|
3808
3878
|
*
|
|
3809
3879
|
* This information is only available after a connection has been requested.
|
|
3880
|
+
*
|
|
3881
|
+
* @deprecated This always returns the Rust client (the only option).
|
|
3810
3882
|
*/
|
|
3811
3883
|
get clientImplementation() {
|
|
3812
3884
|
return this.options.clientImplementation;
|
|
@@ -3814,7 +3886,7 @@ class SyncStatus {
|
|
|
3814
3886
|
/**
|
|
3815
3887
|
* Indicates if the client is currently connected to the PowerSync service.
|
|
3816
3888
|
*
|
|
3817
|
-
* @returns
|
|
3889
|
+
* @returns True if connected, false otherwise. Defaults to false if not specified.
|
|
3818
3890
|
*/
|
|
3819
3891
|
get connected() {
|
|
3820
3892
|
return this.options.connected ?? false;
|
|
@@ -3822,7 +3894,7 @@ class SyncStatus {
|
|
|
3822
3894
|
/**
|
|
3823
3895
|
* Indicates if the client is in the process of establishing a connection to the PowerSync service.
|
|
3824
3896
|
*
|
|
3825
|
-
* @returns
|
|
3897
|
+
* @returns True if connecting, false otherwise. Defaults to false if not specified.
|
|
3826
3898
|
*/
|
|
3827
3899
|
get connecting() {
|
|
3828
3900
|
return this.options.connecting ?? false;
|
|
@@ -3831,7 +3903,7 @@ class SyncStatus {
|
|
|
3831
3903
|
* Time that a last sync has fully completed, if any.
|
|
3832
3904
|
* This timestamp is reset to null after a restart of the PowerSync service.
|
|
3833
3905
|
*
|
|
3834
|
-
* @returns
|
|
3906
|
+
* @returns The timestamp of the last successful sync, or undefined if no sync has completed.
|
|
3835
3907
|
*/
|
|
3836
3908
|
get lastSyncedAt() {
|
|
3837
3909
|
return this.options.lastSyncedAt;
|
|
@@ -3839,7 +3911,7 @@ class SyncStatus {
|
|
|
3839
3911
|
/**
|
|
3840
3912
|
* Indicates whether there has been at least one full sync completed since initialization.
|
|
3841
3913
|
*
|
|
3842
|
-
* @returns
|
|
3914
|
+
* @returns True if at least one sync has completed, false if no sync has completed,
|
|
3843
3915
|
* or undefined when the state is still being loaded from the database.
|
|
3844
3916
|
*/
|
|
3845
3917
|
get hasSynced() {
|
|
@@ -3848,10 +3920,10 @@ class SyncStatus {
|
|
|
3848
3920
|
/**
|
|
3849
3921
|
* Provides the current data flow status regarding uploads and downloads.
|
|
3850
3922
|
*
|
|
3851
|
-
* @returns
|
|
3923
|
+
* @returns An object containing:
|
|
3852
3924
|
* - downloading: True if actively downloading changes (only when connected is also true)
|
|
3853
3925
|
* - uploading: True if actively uploading changes
|
|
3854
|
-
* Defaults to {downloading: false, uploading: false} if not specified.
|
|
3926
|
+
* Defaults to `{downloading: false, uploading: false}` if not specified.
|
|
3855
3927
|
*/
|
|
3856
3928
|
get dataFlowStatus() {
|
|
3857
3929
|
return (this.options.dataFlow ?? {
|
|
@@ -3876,7 +3948,7 @@ class SyncStatus {
|
|
|
3876
3948
|
return this.options.dataFlow?.internalStreamSubscriptions?.map((core) => new SyncStreamStatusView(this, core));
|
|
3877
3949
|
}
|
|
3878
3950
|
/**
|
|
3879
|
-
* If the `stream` appears in {@link syncStreams}, returns the current status for that stream.
|
|
3951
|
+
* If the `stream` appears in {@link SyncStatus.syncStreams}, returns the current status for that stream.
|
|
3880
3952
|
*/
|
|
3881
3953
|
forStream(stream) {
|
|
3882
3954
|
const asJson = JSON.stringify(stream.parameters);
|
|
@@ -3886,7 +3958,7 @@ class SyncStatus {
|
|
|
3886
3958
|
/**
|
|
3887
3959
|
* Provides sync status information for all bucket priorities, sorted by priority (highest first).
|
|
3888
3960
|
*
|
|
3889
|
-
* @returns
|
|
3961
|
+
* @returns An array of status entries for different sync priority levels,
|
|
3890
3962
|
* sorted with highest priorities (lower numbers) first.
|
|
3891
3963
|
*/
|
|
3892
3964
|
get priorityStatusEntries() {
|
|
@@ -3921,8 +3993,8 @@ class SyncStatus {
|
|
|
3921
3993
|
* For example, if PowerSync just finished synchronizing buckets in priority level 3, calling this method
|
|
3922
3994
|
* with a priority of 1 may return information for priority level 3.
|
|
3923
3995
|
*
|
|
3924
|
-
* @param
|
|
3925
|
-
* @returns
|
|
3996
|
+
* @param priority - The bucket priority for which the status should be reported
|
|
3997
|
+
* @returns Status information for the requested priority level or the next higher level with available status
|
|
3926
3998
|
*/
|
|
3927
3999
|
statusForPriority(priority) {
|
|
3928
4000
|
// priorityStatusEntries are sorted by ascending priorities (so higher numbers to lower numbers).
|
|
@@ -3943,8 +4015,8 @@ class SyncStatus {
|
|
|
3943
4015
|
* Compares this SyncStatus instance with another to determine if they are equal.
|
|
3944
4016
|
* Equality is determined by comparing the serialized JSON representation of both instances.
|
|
3945
4017
|
*
|
|
3946
|
-
* @param
|
|
3947
|
-
* @returns
|
|
4018
|
+
* @param status - The SyncStatus instance to compare against
|
|
4019
|
+
* @returns True if the instances are considered equal, false otherwise
|
|
3948
4020
|
*/
|
|
3949
4021
|
isEqual(status) {
|
|
3950
4022
|
/**
|
|
@@ -3967,7 +4039,7 @@ class SyncStatus {
|
|
|
3967
4039
|
* Creates a human-readable string representation of the current sync status.
|
|
3968
4040
|
* Includes information about connection state, sync completion, and data flow.
|
|
3969
4041
|
*
|
|
3970
|
-
* @returns
|
|
4042
|
+
* @returns A string representation of the sync status
|
|
3971
4043
|
*/
|
|
3972
4044
|
getMessage() {
|
|
3973
4045
|
const dataFlow = this.dataFlowStatus;
|
|
@@ -3976,7 +4048,7 @@ class SyncStatus {
|
|
|
3976
4048
|
/**
|
|
3977
4049
|
* Serializes the SyncStatus instance to a plain object.
|
|
3978
4050
|
*
|
|
3979
|
-
* @returns
|
|
4051
|
+
* @returns A plain object representation of the sync status
|
|
3980
4052
|
*/
|
|
3981
4053
|
toJSON() {
|
|
3982
4054
|
return {
|
|
@@ -4042,6 +4114,9 @@ class SyncStreamStatusView {
|
|
|
4042
4114
|
}
|
|
4043
4115
|
}
|
|
4044
4116
|
|
|
4117
|
+
/**
|
|
4118
|
+
* @public
|
|
4119
|
+
*/
|
|
4045
4120
|
class UploadQueueStats {
|
|
4046
4121
|
count;
|
|
4047
4122
|
size;
|
|
@@ -4067,6 +4142,9 @@ class UploadQueueStats {
|
|
|
4067
4142
|
}
|
|
4068
4143
|
}
|
|
4069
4144
|
|
|
4145
|
+
/**
|
|
4146
|
+
* @internal
|
|
4147
|
+
*/
|
|
4070
4148
|
class BaseObserver {
|
|
4071
4149
|
listeners = new Set();
|
|
4072
4150
|
constructor() { }
|
|
@@ -4094,6 +4172,9 @@ class BaseObserver {
|
|
|
4094
4172
|
}
|
|
4095
4173
|
}
|
|
4096
4174
|
|
|
4175
|
+
/**
|
|
4176
|
+
* @internal
|
|
4177
|
+
*/
|
|
4097
4178
|
class ControlledExecutor {
|
|
4098
4179
|
task;
|
|
4099
4180
|
/**
|
|
@@ -4361,7 +4442,7 @@ class ConnectionManager extends BaseObserver {
|
|
|
4361
4442
|
/**
|
|
4362
4443
|
* Close the sync connection.
|
|
4363
4444
|
*
|
|
4364
|
-
* Use {@link connect} to connect again.
|
|
4445
|
+
* Use {@link ConnectionManager.connect} to connect again.
|
|
4365
4446
|
*/
|
|
4366
4447
|
async disconnect() {
|
|
4367
4448
|
// This will help abort pending connects
|
|
@@ -4501,6 +4582,8 @@ const _finalizer = 'FinalizationRegistry' in globalThis
|
|
|
4501
4582
|
/**
|
|
4502
4583
|
* An efficient comparator for {@link WatchedQuery} created with {@link Query#watch}. This has the ability to determine if a query
|
|
4503
4584
|
* result has changes without necessarily processing all items in the result.
|
|
4585
|
+
*
|
|
4586
|
+
* @public
|
|
4504
4587
|
*/
|
|
4505
4588
|
class ArrayComparator {
|
|
4506
4589
|
options;
|
|
@@ -4528,6 +4611,8 @@ class ArrayComparator {
|
|
|
4528
4611
|
}
|
|
4529
4612
|
/**
|
|
4530
4613
|
* Watched query comparator that always reports changed result sets.
|
|
4614
|
+
*
|
|
4615
|
+
* @public
|
|
4531
4616
|
*/
|
|
4532
4617
|
const FalsyComparator = {
|
|
4533
4618
|
checkEquality: () => false // Default comparator that always returns false
|
|
@@ -4735,6 +4820,8 @@ class AbstractQueryProcessor extends MetaBaseObserver {
|
|
|
4735
4820
|
/**
|
|
4736
4821
|
* An empty differential result set.
|
|
4737
4822
|
* This is used as the initial state for differential incrementally watched queries.
|
|
4823
|
+
*
|
|
4824
|
+
* @internal
|
|
4738
4825
|
*/
|
|
4739
4826
|
const EMPTY_DIFFERENTIAL = {
|
|
4740
4827
|
added: [],
|
|
@@ -4747,6 +4834,8 @@ const EMPTY_DIFFERENTIAL = {
|
|
|
4747
4834
|
* Default implementation of the {@link DifferentialWatchedQueryComparator} for watched queries.
|
|
4748
4835
|
* It keys items by their `id` property if available, alternatively it uses JSON stringification
|
|
4749
4836
|
* of the entire item for the key and comparison.
|
|
4837
|
+
*
|
|
4838
|
+
* @internal
|
|
4750
4839
|
*/
|
|
4751
4840
|
const DEFAULT_ROW_COMPARATOR = {
|
|
4752
4841
|
keyBy: (item) => {
|
|
@@ -5027,6 +5116,8 @@ class CustomQuery {
|
|
|
5027
5116
|
|
|
5028
5117
|
/**
|
|
5029
5118
|
* Tests if the input is a {@link SQLOpenOptions}
|
|
5119
|
+
*
|
|
5120
|
+
* @internal
|
|
5030
5121
|
*/
|
|
5031
5122
|
const isSQLOpenOptions = (test) => {
|
|
5032
5123
|
// typeof null is `object`, but you cannot use the `in` operator on `null.
|
|
@@ -5034,17 +5125,24 @@ const isSQLOpenOptions = (test) => {
|
|
|
5034
5125
|
};
|
|
5035
5126
|
/**
|
|
5036
5127
|
* Tests if input is a {@link SQLOpenFactory}
|
|
5128
|
+
*
|
|
5129
|
+
* @internal
|
|
5037
5130
|
*/
|
|
5038
5131
|
const isSQLOpenFactory = (test) => {
|
|
5039
5132
|
return typeof test?.openDB == 'function';
|
|
5040
5133
|
};
|
|
5041
5134
|
/**
|
|
5042
5135
|
* Tests if input is a {@link DBAdapter}
|
|
5136
|
+
*
|
|
5137
|
+
* @internal
|
|
5043
5138
|
*/
|
|
5044
5139
|
const isDBAdapter = (test) => {
|
|
5045
5140
|
return typeof test?.writeTransaction == 'function';
|
|
5046
5141
|
};
|
|
5047
5142
|
|
|
5143
|
+
/**
|
|
5144
|
+
* @internal
|
|
5145
|
+
*/
|
|
5048
5146
|
var PSInternalTable;
|
|
5049
5147
|
(function (PSInternalTable) {
|
|
5050
5148
|
PSInternalTable["DATA"] = "ps_data";
|
|
@@ -5053,6 +5151,9 @@ var PSInternalTable;
|
|
|
5053
5151
|
PSInternalTable["OPLOG"] = "ps_oplog";
|
|
5054
5152
|
PSInternalTable["UNTYPED"] = "ps_untyped";
|
|
5055
5153
|
})(PSInternalTable || (PSInternalTable = {}));
|
|
5154
|
+
/**
|
|
5155
|
+
* @internal
|
|
5156
|
+
*/
|
|
5056
5157
|
var PowerSyncControlCommand;
|
|
5057
5158
|
(function (PowerSyncControlCommand) {
|
|
5058
5159
|
PowerSyncControlCommand["PROCESS_TEXT_LINE"] = "line_text";
|
|
@@ -5070,6 +5171,8 @@ var PowerSyncControlCommand;
|
|
|
5070
5171
|
|
|
5071
5172
|
/**
|
|
5072
5173
|
* A batch of client-side changes.
|
|
5174
|
+
*
|
|
5175
|
+
* @public
|
|
5073
5176
|
*/
|
|
5074
5177
|
class CrudBatch {
|
|
5075
5178
|
crud;
|
|
@@ -5096,6 +5199,8 @@ class CrudBatch {
|
|
|
5096
5199
|
|
|
5097
5200
|
/**
|
|
5098
5201
|
* Type of local change.
|
|
5202
|
+
*
|
|
5203
|
+
* @public
|
|
5099
5204
|
*/
|
|
5100
5205
|
var UpdateType;
|
|
5101
5206
|
(function (UpdateType) {
|
|
@@ -5108,6 +5213,8 @@ var UpdateType;
|
|
|
5108
5213
|
})(UpdateType || (UpdateType = {}));
|
|
5109
5214
|
/**
|
|
5110
5215
|
* A single client-side change.
|
|
5216
|
+
*
|
|
5217
|
+
* @public
|
|
5111
5218
|
*/
|
|
5112
5219
|
class CrudEntry {
|
|
5113
5220
|
/**
|
|
@@ -5204,6 +5311,9 @@ class CrudEntry {
|
|
|
5204
5311
|
}
|
|
5205
5312
|
}
|
|
5206
5313
|
|
|
5314
|
+
/**
|
|
5315
|
+
* @public
|
|
5316
|
+
*/
|
|
5207
5317
|
class CrudTransaction extends CrudBatch {
|
|
5208
5318
|
crud;
|
|
5209
5319
|
complete;
|
|
@@ -5232,6 +5342,8 @@ class CrudTransaction extends CrudBatch {
|
|
|
5232
5342
|
* Calls to Abortcontroller.abort(reason: any) will result in the
|
|
5233
5343
|
* `reason` being thrown. This is not necessarily an error,
|
|
5234
5344
|
* but extends error for better logging purposes.
|
|
5345
|
+
*
|
|
5346
|
+
* @internal
|
|
5235
5347
|
*/
|
|
5236
5348
|
class AbortOperation extends Error {
|
|
5237
5349
|
reason;
|
|
@@ -12402,7 +12514,7 @@ function requireDist () {
|
|
|
12402
12514
|
|
|
12403
12515
|
var distExports = requireDist();
|
|
12404
12516
|
|
|
12405
|
-
var version = "1.
|
|
12517
|
+
var version = "1.54.0";
|
|
12406
12518
|
var PACKAGE = {
|
|
12407
12519
|
version: version};
|
|
12408
12520
|
|
|
@@ -12532,7 +12644,8 @@ class WebsocketClientTransport {
|
|
|
12532
12644
|
removeListeners();
|
|
12533
12645
|
resolve(new WebsocketDuplexConnectionExports.WebsocketDuplexConnection(websocket, new distExports.Deserializer(), multiplexerDemultiplexerFactory));
|
|
12534
12646
|
};
|
|
12535
|
-
const errorListener = (
|
|
12647
|
+
const errorListener = (event) => {
|
|
12648
|
+
const ev = event;
|
|
12536
12649
|
removeListeners();
|
|
12537
12650
|
// We add a default error in that case.
|
|
12538
12651
|
if (ev.error != null) {
|
|
@@ -12775,7 +12888,13 @@ const SOCKET_TIMEOUT_MS = 30_000;
|
|
|
12775
12888
|
// If there is a backlog of messages (for example on slow connections), keepalive messages could be delayed
|
|
12776
12889
|
// significantly. Therefore this is longer than the socket timeout.
|
|
12777
12890
|
const KEEP_ALIVE_LIFETIME_MS = 90_000;
|
|
12891
|
+
/**
|
|
12892
|
+
* @internal
|
|
12893
|
+
*/
|
|
12778
12894
|
const DEFAULT_REMOTE_LOGGER = Logger.get('PowerSyncRemote');
|
|
12895
|
+
/**
|
|
12896
|
+
* @public
|
|
12897
|
+
*/
|
|
12779
12898
|
var FetchStrategy;
|
|
12780
12899
|
(function (FetchStrategy) {
|
|
12781
12900
|
/**
|
|
@@ -12794,12 +12913,17 @@ var FetchStrategy;
|
|
|
12794
12913
|
* The class wrapper is used to distinguish the fetchImplementation
|
|
12795
12914
|
* option in [AbstractRemoteOptions] from the general fetch method
|
|
12796
12915
|
* which is typeof "function"
|
|
12916
|
+
*
|
|
12917
|
+
* @internal
|
|
12797
12918
|
*/
|
|
12798
12919
|
class FetchImplementationProvider {
|
|
12799
12920
|
getFetch() {
|
|
12800
12921
|
throw new Error('Unspecified fetch implementation');
|
|
12801
12922
|
}
|
|
12802
12923
|
}
|
|
12924
|
+
/**
|
|
12925
|
+
* @internal
|
|
12926
|
+
*/
|
|
12803
12927
|
const DEFAULT_REMOTE_OPTIONS = {
|
|
12804
12928
|
socketUrlTransformer: (url) => url.replace(/^https?:\/\//, function (match) {
|
|
12805
12929
|
return match === 'https://' ? 'wss://' : 'ws://';
|
|
@@ -12807,6 +12931,9 @@ const DEFAULT_REMOTE_OPTIONS = {
|
|
|
12807
12931
|
fetchImplementation: new FetchImplementationProvider(),
|
|
12808
12932
|
fetchOptions: {}
|
|
12809
12933
|
};
|
|
12934
|
+
/**
|
|
12935
|
+
* @internal
|
|
12936
|
+
*/
|
|
12810
12937
|
class AbstractRemote {
|
|
12811
12938
|
connector;
|
|
12812
12939
|
logger;
|
|
@@ -13216,7 +13343,7 @@ class AbstractRemote {
|
|
|
13216
13343
|
* Posts a `/sync/stream` request.
|
|
13217
13344
|
*
|
|
13218
13345
|
* Depending on the `Content-Type` of the response, this returns strings for sync lines or encoded BSON documents as
|
|
13219
|
-
*
|
|
13346
|
+
* `Uint8Array`s.
|
|
13220
13347
|
*/
|
|
13221
13348
|
async fetchStream(options) {
|
|
13222
13349
|
const { isBson, stream } = await this.fetchStreamRaw(options);
|
|
@@ -13258,16 +13385,26 @@ function isInterruptingInstruction(instruction) {
|
|
|
13258
13385
|
return 'EstablishSyncStream' in instruction || 'CloseSyncStream' in instruction;
|
|
13259
13386
|
}
|
|
13260
13387
|
|
|
13388
|
+
/**
|
|
13389
|
+
* @internal
|
|
13390
|
+
*/
|
|
13261
13391
|
var LockType;
|
|
13262
13392
|
(function (LockType) {
|
|
13263
13393
|
LockType["CRUD"] = "crud";
|
|
13264
13394
|
LockType["SYNC"] = "sync";
|
|
13265
13395
|
})(LockType || (LockType = {}));
|
|
13396
|
+
/**
|
|
13397
|
+
* @public
|
|
13398
|
+
*/
|
|
13266
13399
|
var SyncStreamConnectionMethod;
|
|
13267
13400
|
(function (SyncStreamConnectionMethod) {
|
|
13268
13401
|
SyncStreamConnectionMethod["HTTP"] = "http";
|
|
13269
13402
|
SyncStreamConnectionMethod["WEB_SOCKET"] = "web-socket";
|
|
13270
13403
|
})(SyncStreamConnectionMethod || (SyncStreamConnectionMethod = {}));
|
|
13404
|
+
/**
|
|
13405
|
+
* @deprecated Deprecated since {@link SyncClientImplementation.RUST} is the only option.
|
|
13406
|
+
* @public
|
|
13407
|
+
*/
|
|
13271
13408
|
var SyncClientImplementation;
|
|
13272
13409
|
(function (SyncClientImplementation) {
|
|
13273
13410
|
/**
|
|
@@ -13279,8 +13416,8 @@ var SyncClientImplementation;
|
|
|
13279
13416
|
* ## Compatibility warning
|
|
13280
13417
|
*
|
|
13281
13418
|
* The Rust sync client stores sync data in a format that is slightly different than the one used
|
|
13282
|
-
* by the old JavaScript client. When adopting the {@link RUST} client on existing databases,
|
|
13283
|
-
* migrate the format automatically.
|
|
13419
|
+
* by the old JavaScript client. When adopting the {@link SyncClientImplementation.RUST} client on existing databases,
|
|
13420
|
+
* the PowerSync SDK will migrate the format automatically.
|
|
13284
13421
|
*
|
|
13285
13422
|
* SDK versions supporting both the JavaScript and the Rust client support both formats with the JavaScript client
|
|
13286
13423
|
* implementaiton. However, downgrading to an SDK version that only supports the JavaScript client would not be
|
|
@@ -13290,14 +13427,29 @@ var SyncClientImplementation;
|
|
|
13290
13427
|
})(SyncClientImplementation || (SyncClientImplementation = {}));
|
|
13291
13428
|
/**
|
|
13292
13429
|
* The default {@link SyncClientImplementation} to use, {@link SyncClientImplementation.RUST}.
|
|
13430
|
+
*
|
|
13431
|
+
* @deprecated Deprecated since {@link SyncClientImplementation.RUST} is the only option.
|
|
13432
|
+
* @public
|
|
13293
13433
|
*/
|
|
13294
13434
|
const DEFAULT_SYNC_CLIENT_IMPLEMENTATION = SyncClientImplementation.RUST;
|
|
13435
|
+
/**
|
|
13436
|
+
* @internal
|
|
13437
|
+
*/
|
|
13295
13438
|
const DEFAULT_CRUD_UPLOAD_THROTTLE_MS = 1000;
|
|
13439
|
+
/**
|
|
13440
|
+
* @internal
|
|
13441
|
+
*/
|
|
13296
13442
|
const DEFAULT_RETRY_DELAY_MS = 5000;
|
|
13443
|
+
/**
|
|
13444
|
+
* @internal
|
|
13445
|
+
*/
|
|
13297
13446
|
const DEFAULT_STREAMING_SYNC_OPTIONS = {
|
|
13298
13447
|
retryDelayMs: DEFAULT_RETRY_DELAY_MS,
|
|
13299
13448
|
crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
|
|
13300
13449
|
};
|
|
13450
|
+
/**
|
|
13451
|
+
* @internal
|
|
13452
|
+
*/
|
|
13301
13453
|
const DEFAULT_STREAM_CONNECTION_OPTIONS = {
|
|
13302
13454
|
appMetadata: {},
|
|
13303
13455
|
connectionMethod: SyncStreamConnectionMethod.WEB_SOCKET,
|
|
@@ -13307,6 +13459,9 @@ const DEFAULT_STREAM_CONNECTION_OPTIONS = {
|
|
|
13307
13459
|
serializedSchema: undefined,
|
|
13308
13460
|
includeDefaultStreams: true
|
|
13309
13461
|
};
|
|
13462
|
+
/**
|
|
13463
|
+
* @internal
|
|
13464
|
+
*/
|
|
13310
13465
|
class AbstractStreamingSyncImplementation extends BaseObserver {
|
|
13311
13466
|
options;
|
|
13312
13467
|
abortController;
|
|
@@ -13630,7 +13785,7 @@ The next upload iteration will be delayed.`);
|
|
|
13630
13785
|
this.handleActiveStreamsChange?.();
|
|
13631
13786
|
}
|
|
13632
13787
|
/**
|
|
13633
|
-
* Older versions of the JS SDK used to encode subkeys as JSON in
|
|
13788
|
+
* Older versions of the JS SDK used to encode subkeys as JSON in `OplogEntry.toJSON`.
|
|
13634
13789
|
* Because subkeys are always strings, this leads to quotes being added around them in `ps_oplog`.
|
|
13635
13790
|
* While this is not a problem as long as it's done consistently, it causes issues when a database
|
|
13636
13791
|
* created by the JS SDK is used with other SDKs, or (more likely) when the new Rust sync client
|
|
@@ -13640,7 +13795,7 @@ The next upload iteration will be delayed.`);
|
|
|
13640
13795
|
* migration is only triggered when necessary (for now). The function returns whether the new format
|
|
13641
13796
|
* should be used, so that the JS SDK is able to write to updated databases.
|
|
13642
13797
|
*
|
|
13643
|
-
* @param requireFixedKeyFormat Whether we require the new format or also support the old one.
|
|
13798
|
+
* @param requireFixedKeyFormat - Whether we require the new format or also support the old one.
|
|
13644
13799
|
* The Rust client requires the new subkey format.
|
|
13645
13800
|
* @returns Whether the database is now using the new, fixed subkey format.
|
|
13646
13801
|
*/
|
|
@@ -13947,7 +14102,8 @@ const MEMORY_TRIGGER_CLAIM_MANAGER = {
|
|
|
13947
14102
|
|
|
13948
14103
|
/**
|
|
13949
14104
|
* SQLite operations to track changes for with {@link TriggerManager}
|
|
13950
|
-
*
|
|
14105
|
+
*
|
|
14106
|
+
* @experimental @alpha
|
|
13951
14107
|
*/
|
|
13952
14108
|
var DiffTriggerOperation;
|
|
13953
14109
|
(function (DiffTriggerOperation) {
|
|
@@ -14009,8 +14165,8 @@ class TriggerManagerImpl {
|
|
|
14009
14165
|
get db() {
|
|
14010
14166
|
return this.options.db;
|
|
14011
14167
|
}
|
|
14012
|
-
async getUUID() {
|
|
14013
|
-
const { id: uuid } = await this.db.get(/* sql */ `
|
|
14168
|
+
async getUUID(ctx) {
|
|
14169
|
+
const { id: uuid } = await (ctx ?? this.db).get(/* sql */ `
|
|
14014
14170
|
SELECT
|
|
14015
14171
|
uuid () as id
|
|
14016
14172
|
`);
|
|
@@ -14123,7 +14279,7 @@ class TriggerManagerImpl {
|
|
|
14123
14279
|
const replicatedColumns = columns ?? sourceDefinition.columns.map((col) => col.name);
|
|
14124
14280
|
const internalSource = sourceDefinition.internalName;
|
|
14125
14281
|
const triggerIds = [];
|
|
14126
|
-
const id = await this.getUUID();
|
|
14282
|
+
const id = await this.getUUID(setupContext);
|
|
14127
14283
|
const releaseStorageClaim = useStorage ? await this.options.claimManager.obtainClaim(id) : null;
|
|
14128
14284
|
/**
|
|
14129
14285
|
* We default to replicating all columns if no columns array is provided.
|
|
@@ -14363,18 +14519,29 @@ const POWERSYNC_TABLE_MATCH = /(^ps_data__|^ps_data_local__)/;
|
|
|
14363
14519
|
const DEFAULT_DISCONNECT_CLEAR_OPTIONS = {
|
|
14364
14520
|
clearLocal: true
|
|
14365
14521
|
};
|
|
14522
|
+
/**
|
|
14523
|
+
* @internal
|
|
14524
|
+
*/
|
|
14366
14525
|
const DEFAULT_POWERSYNC_CLOSE_OPTIONS = {
|
|
14367
14526
|
disconnect: true
|
|
14368
14527
|
};
|
|
14528
|
+
/**
|
|
14529
|
+
* @internal
|
|
14530
|
+
*/
|
|
14369
14531
|
const DEFAULT_POWERSYNC_DB_OPTIONS = {
|
|
14370
14532
|
retryDelayMs: 5000,
|
|
14371
14533
|
crudUploadThrottleMs: DEFAULT_CRUD_UPLOAD_THROTTLE_MS
|
|
14372
14534
|
};
|
|
14535
|
+
/**
|
|
14536
|
+
* @internal
|
|
14537
|
+
*/
|
|
14373
14538
|
const DEFAULT_CRUD_BATCH_LIMIT = 100;
|
|
14374
14539
|
/**
|
|
14375
14540
|
* Requesting nested or recursive locks can block the application in some circumstances.
|
|
14376
14541
|
* This default lock timeout will act as a failsafe to throw an error if a lock cannot
|
|
14377
14542
|
* be obtained.
|
|
14543
|
+
*
|
|
14544
|
+
* @internal
|
|
14378
14545
|
*/
|
|
14379
14546
|
const DEFAULT_LOCK_TIMEOUT_MS = 120_000; // 2 mins
|
|
14380
14547
|
/**
|
|
@@ -14384,6 +14551,9 @@ const DEFAULT_LOCK_TIMEOUT_MS = 120_000; // 2 mins
|
|
|
14384
14551
|
const isPowerSyncDatabaseOptionsWithSettings = (test) => {
|
|
14385
14552
|
return typeof test == 'object' && isSQLOpenOptions(test.database);
|
|
14386
14553
|
};
|
|
14554
|
+
/**
|
|
14555
|
+
* @public
|
|
14556
|
+
*/
|
|
14387
14557
|
class AbstractPowerSyncDatabase extends BaseObserver {
|
|
14388
14558
|
options;
|
|
14389
14559
|
/**
|
|
@@ -14541,7 +14711,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
14541
14711
|
/**
|
|
14542
14712
|
* Wait for the first sync operation to complete.
|
|
14543
14713
|
*
|
|
14544
|
-
* @param request Either an abort signal (after which the promise will complete regardless of
|
|
14714
|
+
* @param request - Either an abort signal (after which the promise will complete regardless of
|
|
14545
14715
|
* whether a full sync was completed) or an object providing an abort signal and a priority target.
|
|
14546
14716
|
* When a priority target is set, the promise may complete when all buckets with the given (or higher)
|
|
14547
14717
|
* priorities have been synchronized. This can be earlier than a complete sync.
|
|
@@ -14696,7 +14866,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
14696
14866
|
/**
|
|
14697
14867
|
* Close the sync connection.
|
|
14698
14868
|
*
|
|
14699
|
-
* Use {@link connect} to connect again.
|
|
14869
|
+
* Use {@link AbstractPowerSyncDatabase.connect} to connect again.
|
|
14700
14870
|
*/
|
|
14701
14871
|
async disconnect() {
|
|
14702
14872
|
return this.connectionManager.disconnect();
|
|
@@ -14723,8 +14893,8 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
14723
14893
|
/**
|
|
14724
14894
|
* Create a sync stream to query its status or to subscribe to it.
|
|
14725
14895
|
*
|
|
14726
|
-
* @param name The name of the stream to subscribe to.
|
|
14727
|
-
* @param params Optional parameters for the stream subscription.
|
|
14896
|
+
* @param name - The name of the stream to subscribe to.
|
|
14897
|
+
* @param params - Optional parameters for the stream subscription.
|
|
14728
14898
|
* @returns A {@link SyncStream} instance that can be subscribed to.
|
|
14729
14899
|
* @experimental Sync streams are currently in alpha.
|
|
14730
14900
|
*/
|
|
@@ -14782,14 +14952,14 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
14782
14952
|
* Once the data have been successfully uploaded, call {@link CrudBatch.complete} before
|
|
14783
14953
|
* requesting the next batch.
|
|
14784
14954
|
*
|
|
14785
|
-
* Use
|
|
14955
|
+
* Use the `limit` parameter to specify the maximum number of updates to return in a single
|
|
14786
14956
|
* batch.
|
|
14787
14957
|
*
|
|
14788
14958
|
* This method does include transaction ids in the result, but does not group
|
|
14789
14959
|
* data by transaction. One batch may contain data from multiple transactions,
|
|
14790
14960
|
* and a single transaction may be split over multiple batches.
|
|
14791
14961
|
*
|
|
14792
|
-
* @param limit Maximum number of CRUD entries to include in the batch
|
|
14962
|
+
* @param limit - Maximum number of CRUD entries to include in the batch
|
|
14793
14963
|
* @returns A batch of CRUD operations to upload, or null if there are none
|
|
14794
14964
|
*/
|
|
14795
14965
|
async getCrudBatch(limit = DEFAULT_CRUD_BATCH_LIMIT) {
|
|
@@ -14816,7 +14986,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
14816
14986
|
* Once the data have been successfully uploaded, call {@link CrudTransaction.complete} before
|
|
14817
14987
|
* requesting the next transaction.
|
|
14818
14988
|
*
|
|
14819
|
-
* Unlike {@link getCrudBatch}, this only returns data from a single transaction at a time.
|
|
14989
|
+
* Unlike {@link AbstractPowerSyncDatabase.getCrudBatch}, this only returns data from a single transaction at a time.
|
|
14820
14990
|
* All data for the transaction is loaded into memory.
|
|
14821
14991
|
*
|
|
14822
14992
|
* @returns A transaction of CRUD operations to upload, or null if there are none
|
|
@@ -14831,7 +15001,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
14831
15001
|
* This is typically used from the {@link PowerSyncBackendConnector.uploadData} callback. Each entry emitted by the
|
|
14832
15002
|
* returned iterator is a full transaction containing all local writes made while that transaction was active.
|
|
14833
15003
|
*
|
|
14834
|
-
* Unlike {@link getNextCrudTransaction}, which always returns the oldest transaction that hasn't been
|
|
15004
|
+
* Unlike {@link AbstractPowerSyncDatabase.getNextCrudTransaction}, which always returns the oldest transaction that hasn't been
|
|
14835
15005
|
* {@link CrudTransaction.complete}d yet, this iterator can be used to receive multiple transactions. Calling
|
|
14836
15006
|
* {@link CrudTransaction.complete} will mark that and all prior transactions emitted by the iterator as completed.
|
|
14837
15007
|
*
|
|
@@ -14925,8 +15095,8 @@ SELECT * FROM crud_entries;
|
|
|
14925
15095
|
* the returned result's `rowsAffected` may be `0` for successful `UPDATE` and `DELETE` statements.
|
|
14926
15096
|
* Use a `RETURNING` clause and inspect `result.rows` when you need to confirm which rows changed.
|
|
14927
15097
|
*
|
|
14928
|
-
* @param sql The SQL query to execute
|
|
14929
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
15098
|
+
* @param sql - The SQL query to execute
|
|
15099
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
14930
15100
|
* @returns The query result as an object with structured key-value pairs
|
|
14931
15101
|
*/
|
|
14932
15102
|
async execute(sql, parameters) {
|
|
@@ -14936,8 +15106,8 @@ SELECT * FROM crud_entries;
|
|
|
14936
15106
|
* Execute a SQL write (INSERT/UPDATE/DELETE) query directly on the database without any PowerSync processing.
|
|
14937
15107
|
* This bypasses certain PowerSync abstractions and is useful for accessing the raw database results.
|
|
14938
15108
|
*
|
|
14939
|
-
* @param sql The SQL query to execute
|
|
14940
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
15109
|
+
* @param sql - The SQL query to execute
|
|
15110
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
14941
15111
|
* @returns The raw query result from the underlying database as a nested array of raw values, where each row is
|
|
14942
15112
|
* represented as an array of column values without field names.
|
|
14943
15113
|
*/
|
|
@@ -14950,8 +15120,8 @@ SELECT * FROM crud_entries;
|
|
|
14950
15120
|
* and optionally return results.
|
|
14951
15121
|
* This is faster than executing separately with each parameter set.
|
|
14952
15122
|
*
|
|
14953
|
-
* @param sql The SQL query to execute
|
|
14954
|
-
* @param parameters Optional 2D array of parameter sets, where each inner array is a set of parameters for one execution
|
|
15123
|
+
* @param sql - The SQL query to execute
|
|
15124
|
+
* @param parameters - Optional 2D array of parameter sets, where each inner array is a set of parameters for one execution
|
|
14955
15125
|
* @returns The query result
|
|
14956
15126
|
*/
|
|
14957
15127
|
async executeBatch(sql, parameters) {
|
|
@@ -14961,8 +15131,8 @@ SELECT * FROM crud_entries;
|
|
|
14961
15131
|
/**
|
|
14962
15132
|
* Execute a read-only query and return results.
|
|
14963
15133
|
*
|
|
14964
|
-
* @param sql The SQL query to execute
|
|
14965
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
15134
|
+
* @param sql - The SQL query to execute
|
|
15135
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
14966
15136
|
* @returns An array of results
|
|
14967
15137
|
*/
|
|
14968
15138
|
async getAll(sql, parameters) {
|
|
@@ -14972,8 +15142,8 @@ SELECT * FROM crud_entries;
|
|
|
14972
15142
|
/**
|
|
14973
15143
|
* Execute a read-only query and return the first result, or null if the ResultSet is empty.
|
|
14974
15144
|
*
|
|
14975
|
-
* @param sql The SQL query to execute
|
|
14976
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
15145
|
+
* @param sql - The SQL query to execute
|
|
15146
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
14977
15147
|
* @returns The first result if found, or null if no results are returned
|
|
14978
15148
|
*/
|
|
14979
15149
|
async getOptional(sql, parameters) {
|
|
@@ -14983,8 +15153,8 @@ SELECT * FROM crud_entries;
|
|
|
14983
15153
|
/**
|
|
14984
15154
|
* Execute a read-only query and return the first result, error if the ResultSet is empty.
|
|
14985
15155
|
*
|
|
14986
|
-
* @param sql The SQL query to execute
|
|
14987
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
15156
|
+
* @param sql - The SQL query to execute
|
|
15157
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
14988
15158
|
* @returns The first result matching the query
|
|
14989
15159
|
* @throws Error if no rows are returned
|
|
14990
15160
|
*/
|
|
@@ -14994,7 +15164,7 @@ SELECT * FROM crud_entries;
|
|
|
14994
15164
|
}
|
|
14995
15165
|
/**
|
|
14996
15166
|
* Takes a read lock, without starting a transaction.
|
|
14997
|
-
* In most cases, {@link readTransaction} should be used instead.
|
|
15167
|
+
* In most cases, {@link AbstractPowerSyncDatabase.readTransaction} should be used instead.
|
|
14998
15168
|
*/
|
|
14999
15169
|
async readLock(callback) {
|
|
15000
15170
|
await this.waitForReady();
|
|
@@ -15002,7 +15172,7 @@ SELECT * FROM crud_entries;
|
|
|
15002
15172
|
}
|
|
15003
15173
|
/**
|
|
15004
15174
|
* Takes a global lock, without starting a transaction.
|
|
15005
|
-
* In most cases, {@link writeTransaction} should be used instead.
|
|
15175
|
+
* In most cases, {@link AbstractPowerSyncDatabase.writeTransaction} should be used instead.
|
|
15006
15176
|
*/
|
|
15007
15177
|
async writeLock(callback) {
|
|
15008
15178
|
await this.waitForReady();
|
|
@@ -15013,8 +15183,8 @@ SELECT * FROM crud_entries;
|
|
|
15013
15183
|
* Read transactions can run concurrently to a write transaction.
|
|
15014
15184
|
* Changes from any write transaction are not visible to read transactions started before it.
|
|
15015
15185
|
*
|
|
15016
|
-
* @param callback Function to execute within the transaction
|
|
15017
|
-
* @param lockTimeout Time in milliseconds to wait for a lock before throwing an error
|
|
15186
|
+
* @param callback - Function to execute within the transaction
|
|
15187
|
+
* @param lockTimeout - Time in milliseconds to wait for a lock before throwing an error
|
|
15018
15188
|
* @returns The result of the callback
|
|
15019
15189
|
* @throws Error if the lock cannot be obtained within the timeout period
|
|
15020
15190
|
*/
|
|
@@ -15031,8 +15201,8 @@ SELECT * FROM crud_entries;
|
|
|
15031
15201
|
* This takes a global lock - only one write transaction can execute against the database at a time.
|
|
15032
15202
|
* Statements within the transaction must be done on the provided {@link Transaction} interface.
|
|
15033
15203
|
*
|
|
15034
|
-
* @param callback Function to execute within the transaction
|
|
15035
|
-
* @param lockTimeout Time in milliseconds to wait for a lock before throwing an error
|
|
15204
|
+
* @param callback - Function to execute within the transaction
|
|
15205
|
+
* @param lockTimeout - Time in milliseconds to wait for a lock before throwing an error
|
|
15036
15206
|
* @returns The result of the callback
|
|
15037
15207
|
* @throws Error if the lock cannot be obtained within the timeout period
|
|
15038
15208
|
*/
|
|
@@ -15109,15 +15279,15 @@ SELECT * FROM crud_entries;
|
|
|
15109
15279
|
}
|
|
15110
15280
|
/**
|
|
15111
15281
|
* Execute a read query every time the source tables are modified.
|
|
15112
|
-
* Use {@link
|
|
15282
|
+
* Use {@link SQLOnChangeOptions.throttleMs} to specify the minimum interval between queries.
|
|
15113
15283
|
* Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
|
|
15114
15284
|
*
|
|
15115
15285
|
* Note that the `onChange` callback member of the handler is required.
|
|
15116
15286
|
*
|
|
15117
|
-
* @param sql The SQL query to execute
|
|
15118
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
15119
|
-
* @param handler Callbacks for handling results and errors
|
|
15120
|
-
* @param options Options for configuring watch behavior
|
|
15287
|
+
* @param sql - The SQL query to execute
|
|
15288
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
15289
|
+
* @param handler - Callbacks for handling results and errors
|
|
15290
|
+
* @param options - Options for configuring watch behavior
|
|
15121
15291
|
*/
|
|
15122
15292
|
watchWithCallback(sql, parameters, handler, options) {
|
|
15123
15293
|
const { onResult, onError = (e) => this.logger.error(e) } = handler ?? {};
|
|
@@ -15130,7 +15300,7 @@ SELECT * FROM crud_entries;
|
|
|
15130
15300
|
const watchedQuery = new OnChangeQueryProcessor({
|
|
15131
15301
|
db: this,
|
|
15132
15302
|
comparator,
|
|
15133
|
-
placeholderData: null,
|
|
15303
|
+
placeholderData: null, // FIXME
|
|
15134
15304
|
watchOptions: {
|
|
15135
15305
|
query: {
|
|
15136
15306
|
compile: () => ({
|
|
@@ -15163,12 +15333,12 @@ SELECT * FROM crud_entries;
|
|
|
15163
15333
|
}
|
|
15164
15334
|
/**
|
|
15165
15335
|
* Execute a read query every time the source tables are modified.
|
|
15166
|
-
* Use {@link
|
|
15336
|
+
* Use {@link SQLOnChangeOptions.throttleMs} to specify the minimum interval between queries.
|
|
15167
15337
|
* Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
|
|
15168
15338
|
*
|
|
15169
|
-
* @param sql The SQL query to execute
|
|
15170
|
-
* @param parameters Optional array of parameters to bind to the query
|
|
15171
|
-
* @param options Options for configuring watch behavior
|
|
15339
|
+
* @param sql - The SQL query to execute
|
|
15340
|
+
* @param parameters - Optional array of parameters to bind to the query
|
|
15341
|
+
* @param options - Options for configuring watch behavior
|
|
15172
15342
|
* @returns An AsyncIterable that yields QueryResults whenever the data changes
|
|
15173
15343
|
*/
|
|
15174
15344
|
watchWithAsyncGenerator(sql, parameters, options) {
|
|
@@ -15192,9 +15362,9 @@ SELECT * FROM crud_entries;
|
|
|
15192
15362
|
* If tables are specified in the options, those are used directly.
|
|
15193
15363
|
* Otherwise, analyzes the query using EXPLAIN to determine which tables are accessed.
|
|
15194
15364
|
*
|
|
15195
|
-
* @param sql The SQL query to analyze
|
|
15196
|
-
* @param parameters Optional parameters for the SQL query
|
|
15197
|
-
* @param options Optional watch options that may contain explicit table list
|
|
15365
|
+
* @param sql - The SQL query to analyze
|
|
15366
|
+
* @param parameters - Optional parameters for the SQL query
|
|
15367
|
+
* @param options - Optional watch options that may contain explicit table list
|
|
15198
15368
|
* @returns Array of table names that the query depends on
|
|
15199
15369
|
*/
|
|
15200
15370
|
async resolveTables(sql, parameters, options) {
|
|
@@ -15223,13 +15393,13 @@ SELECT * FROM crud_entries;
|
|
|
15223
15393
|
/**
|
|
15224
15394
|
* Invoke the provided callback on any changes to any of the specified tables.
|
|
15225
15395
|
*
|
|
15226
|
-
* This is preferred over {@link watchWithCallback} when multiple queries need to be performed
|
|
15396
|
+
* This is preferred over {@link AbstractPowerSyncDatabase.watchWithCallback} when multiple queries need to be performed
|
|
15227
15397
|
* together when data is changed.
|
|
15228
15398
|
*
|
|
15229
15399
|
* Note that the `onChange` callback member of the handler is required.
|
|
15230
15400
|
*
|
|
15231
|
-
* @param handler Callbacks for handling change events and errors
|
|
15232
|
-
* @param options Options for configuring watch behavior
|
|
15401
|
+
* @param handler - Callbacks for handling change events and errors
|
|
15402
|
+
* @param options - Options for configuring watch behavior
|
|
15233
15403
|
* @returns A dispose function to stop watching for changes
|
|
15234
15404
|
*/
|
|
15235
15405
|
onChangeWithCallback(handler, options) {
|
|
@@ -15272,12 +15442,12 @@ SELECT * FROM crud_entries;
|
|
|
15272
15442
|
/**
|
|
15273
15443
|
* Create a Stream of changes to any of the specified tables.
|
|
15274
15444
|
*
|
|
15275
|
-
* This is preferred over {@link watchWithAsyncGenerator} when multiple queries need to be
|
|
15276
|
-
* together when data is changed.
|
|
15445
|
+
* This is preferred over {@link AbstractPowerSyncDatabase.watchWithAsyncGenerator} when multiple queries need to be
|
|
15446
|
+
* performed together when data is changed.
|
|
15277
15447
|
*
|
|
15278
15448
|
* Note: do not declare this as `async *onChange` as it will not work in React Native.
|
|
15279
15449
|
*
|
|
15280
|
-
* @param options Options for configuring watch behavior
|
|
15450
|
+
* @param options - Options for configuring watch behavior
|
|
15281
15451
|
* @returns An AsyncIterable that yields change events whenever the specified tables change
|
|
15282
15452
|
*/
|
|
15283
15453
|
onChangeWithAsyncGenerator(options) {
|
|
@@ -15315,15 +15485,15 @@ SELECT * FROM crud_entries;
|
|
|
15315
15485
|
changedTables.add(table);
|
|
15316
15486
|
}
|
|
15317
15487
|
}
|
|
15318
|
-
/**
|
|
15319
|
-
* @ignore
|
|
15320
|
-
*/
|
|
15321
15488
|
async executeReadOnly(sql, params) {
|
|
15322
15489
|
await this.waitForReady();
|
|
15323
15490
|
return this.database.readLock((tx) => tx.execute(sql, params));
|
|
15324
15491
|
}
|
|
15325
15492
|
}
|
|
15326
15493
|
|
|
15494
|
+
/**
|
|
15495
|
+
* @internal
|
|
15496
|
+
*/
|
|
15327
15497
|
class AbstractPowerSyncDatabaseOpenFactory {
|
|
15328
15498
|
options;
|
|
15329
15499
|
constructor(options) {
|
|
@@ -15348,6 +15518,9 @@ class AbstractPowerSyncDatabaseOpenFactory {
|
|
|
15348
15518
|
}
|
|
15349
15519
|
}
|
|
15350
15520
|
|
|
15521
|
+
/**
|
|
15522
|
+
* @internal
|
|
15523
|
+
*/
|
|
15351
15524
|
function runOnSchemaChange(callback, db, options) {
|
|
15352
15525
|
const triggerWatchedQuery = () => {
|
|
15353
15526
|
const abortController = new AbortController();
|
|
@@ -15372,6 +15545,9 @@ function runOnSchemaChange(callback, db, options) {
|
|
|
15372
15545
|
triggerWatchedQuery();
|
|
15373
15546
|
}
|
|
15374
15547
|
|
|
15548
|
+
/**
|
|
15549
|
+
* @public
|
|
15550
|
+
*/
|
|
15375
15551
|
function compilableQueryWatch(db, query, handler, options) {
|
|
15376
15552
|
const { onResult, onError = (e) => { } } = handler ?? {};
|
|
15377
15553
|
if (!onResult) {
|
|
@@ -15409,8 +15585,14 @@ function compilableQueryWatch(db, query, handler, options) {
|
|
|
15409
15585
|
runOnSchemaChange(watchQuery, db, options);
|
|
15410
15586
|
}
|
|
15411
15587
|
|
|
15588
|
+
/**
|
|
15589
|
+
* @internal
|
|
15590
|
+
*/
|
|
15412
15591
|
const MAX_OP_ID = '9223372036854775807';
|
|
15413
15592
|
|
|
15593
|
+
/**
|
|
15594
|
+
* @internal
|
|
15595
|
+
*/
|
|
15414
15596
|
class SqliteBucketStorage extends BaseObserver {
|
|
15415
15597
|
db;
|
|
15416
15598
|
logger;
|
|
@@ -15571,6 +15753,8 @@ class SqliteBucketStorage extends BaseObserver {
|
|
|
15571
15753
|
* Thrown when an underlying database connection is closed.
|
|
15572
15754
|
* This is particularly relevant when worker connections are marked as closed while
|
|
15573
15755
|
* operations are still in progress.
|
|
15756
|
+
*
|
|
15757
|
+
* @internal
|
|
15574
15758
|
*/
|
|
15575
15759
|
class ConnectionClosedError extends Error {
|
|
15576
15760
|
static NAME = 'ConnectionClosedError';
|
|
@@ -15590,6 +15774,8 @@ class ConnectionClosedError extends Error {
|
|
|
15590
15774
|
|
|
15591
15775
|
/**
|
|
15592
15776
|
* A schema is a collection of tables. It is used to define the structure of a database.
|
|
15777
|
+
*
|
|
15778
|
+
* @public
|
|
15593
15779
|
*/
|
|
15594
15780
|
class Schema {
|
|
15595
15781
|
/*
|
|
@@ -15626,7 +15812,7 @@ class Schema {
|
|
|
15626
15812
|
* Since raw tables are not backed by JSON, running complex queries on them may be more efficient. Further, they allow
|
|
15627
15813
|
* using client-side table and column constraints.
|
|
15628
15814
|
*
|
|
15629
|
-
* @param tables An object of (table name, raw table definition) entries.
|
|
15815
|
+
* @param tables - An object of (table name, raw table definition) entries.
|
|
15630
15816
|
*/
|
|
15631
15817
|
withRawTables(tables) {
|
|
15632
15818
|
for (const [name, rawTableDefinition] of Object.entries(tables)) {
|
|
@@ -15672,6 +15858,8 @@ class Schema {
|
|
|
15672
15858
|
Generate a new table from the columns and indexes
|
|
15673
15859
|
@deprecated You should use {@link Table} instead as it now allows TableV2 syntax.
|
|
15674
15860
|
This will be removed in the next major release.
|
|
15861
|
+
|
|
15862
|
+
@public
|
|
15675
15863
|
*/
|
|
15676
15864
|
class TableV2 extends Table {
|
|
15677
15865
|
}
|
|
@@ -15682,6 +15870,8 @@ function sanitizeString(input) {
|
|
|
15682
15870
|
/**
|
|
15683
15871
|
* Helper function for sanitizing UUID input strings.
|
|
15684
15872
|
* Typically used with {@link sanitizeSQL}.
|
|
15873
|
+
*
|
|
15874
|
+
* @alpha
|
|
15685
15875
|
*/
|
|
15686
15876
|
function sanitizeUUID(uuid) {
|
|
15687
15877
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
@@ -15718,6 +15908,8 @@ function sanitizeUUID(uuid) {
|
|
|
15718
15908
|
* // Incorrect:
|
|
15719
15909
|
* sanitizeSQL`New.id = '${myID}'` // Produces double quotes: New.id = ''O''Reilly''
|
|
15720
15910
|
* ```
|
|
15911
|
+
*
|
|
15912
|
+
* @alpha
|
|
15721
15913
|
*/
|
|
15722
15914
|
function sanitizeSQL(strings, ...values) {
|
|
15723
15915
|
let result = '';
|
|
@@ -15747,6 +15939,8 @@ function sanitizeSQL(strings, ...values) {
|
|
|
15747
15939
|
|
|
15748
15940
|
/**
|
|
15749
15941
|
* Performs a {@link AbstractPowerSyncDatabase.getAll} operation for a watched query.
|
|
15942
|
+
*
|
|
15943
|
+
* @public
|
|
15750
15944
|
*/
|
|
15751
15945
|
class GetAllQuery {
|
|
15752
15946
|
options;
|
|
@@ -15771,6 +15965,9 @@ class GetAllQuery {
|
|
|
15771
15965
|
}
|
|
15772
15966
|
|
|
15773
15967
|
const TypedLogger = Logger;
|
|
15968
|
+
/**
|
|
15969
|
+
* @public
|
|
15970
|
+
*/
|
|
15774
15971
|
const LogLevel = {
|
|
15775
15972
|
TRACE: TypedLogger.TRACE,
|
|
15776
15973
|
DEBUG: TypedLogger.DEBUG,
|
|
@@ -15787,6 +15984,7 @@ const LogLevel = {
|
|
|
15787
15984
|
* across all loggers created with `createLogger`. Adjusting settings on this
|
|
15788
15985
|
* base logger affects all loggers derived from it unless explicitly overridden.
|
|
15789
15986
|
*
|
|
15987
|
+
* @public
|
|
15790
15988
|
*/
|
|
15791
15989
|
function createBaseLogger() {
|
|
15792
15990
|
return Logger;
|
|
@@ -15797,6 +15995,8 @@ function createBaseLogger() {
|
|
|
15797
15995
|
* Named loggers allow specific modules or areas of your application to have
|
|
15798
15996
|
* their own logging levels and behaviors. These loggers inherit configuration
|
|
15799
15997
|
* from the base logger by default but can override settings independently.
|
|
15998
|
+
*
|
|
15999
|
+
* @public
|
|
15800
16000
|
*/
|
|
15801
16001
|
function createLogger(name, options = {}) {
|
|
15802
16002
|
const logger = Logger.get(name);
|
|
@@ -15806,6 +16006,9 @@ function createLogger(name, options = {}) {
|
|
|
15806
16006
|
return logger;
|
|
15807
16007
|
}
|
|
15808
16008
|
|
|
16009
|
+
/**
|
|
16010
|
+
* @internal
|
|
16011
|
+
*/
|
|
15809
16012
|
const parseQuery = (query, parameters) => {
|
|
15810
16013
|
let sqlStatement;
|
|
15811
16014
|
if (typeof query == 'string') {
|