@powersync/common 1.48.0 → 1.50.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.cjs +270 -46
- package/dist/bundle.cjs.map +1 -1
- package/dist/bundle.mjs +265 -44
- package/dist/bundle.mjs.map +1 -1
- package/dist/bundle.node.cjs +270 -45
- package/dist/bundle.node.cjs.map +1 -1
- package/dist/bundle.node.mjs +265 -43
- package/dist/bundle.node.mjs.map +1 -1
- package/dist/index.d.cts +108 -26
- package/lib/attachments/AttachmentQueue.d.ts +10 -4
- package/lib/attachments/AttachmentQueue.js +10 -4
- package/lib/attachments/AttachmentQueue.js.map +1 -1
- package/lib/attachments/AttachmentService.js +2 -3
- package/lib/attachments/AttachmentService.js.map +1 -1
- package/lib/attachments/SyncingService.d.ts +2 -1
- package/lib/attachments/SyncingService.js +4 -5
- package/lib/attachments/SyncingService.js.map +1 -1
- package/lib/client/AbstractPowerSyncDatabase.d.ts +5 -1
- package/lib/client/AbstractPowerSyncDatabase.js +6 -2
- package/lib/client/AbstractPowerSyncDatabase.js.map +1 -1
- package/lib/client/triggers/TriggerManager.d.ts +13 -1
- package/lib/client/triggers/TriggerManagerImpl.d.ts +2 -2
- package/lib/client/triggers/TriggerManagerImpl.js +19 -7
- package/lib/client/triggers/TriggerManagerImpl.js.map +1 -1
- package/lib/db/DBAdapter.d.ts +55 -9
- package/lib/db/DBAdapter.js +126 -0
- package/lib/db/DBAdapter.js.map +1 -1
- package/lib/utils/mutex.d.ts +18 -5
- package/lib/utils/mutex.js +97 -21
- package/lib/utils/mutex.js.map +1 -1
- package/package.json +1 -2
- package/src/attachments/AttachmentQueue.ts +10 -4
- package/src/attachments/AttachmentService.ts +2 -3
- package/src/attachments/README.md +6 -4
- package/src/attachments/SyncingService.ts +4 -5
- package/src/client/AbstractPowerSyncDatabase.ts +6 -2
- package/src/client/triggers/TriggerManager.ts +15 -2
- package/src/client/triggers/TriggerManagerImpl.ts +18 -6
- package/src/db/DBAdapter.ts +167 -9
- package/src/utils/mutex.ts +121 -26
package/dist/bundle.mjs
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { Mutex } from 'async-mutex';
|
|
2
|
-
|
|
3
1
|
// https://www.sqlite.org/lang_expr.html#castexpr
|
|
4
2
|
var ColumnType;
|
|
5
3
|
(function (ColumnType) {
|
|
@@ -657,7 +655,7 @@ class SyncingService {
|
|
|
657
655
|
updatedAttachments.push(downloaded);
|
|
658
656
|
break;
|
|
659
657
|
case AttachmentState.QUEUED_DELETE:
|
|
660
|
-
const deleted = await this.deleteAttachment(attachment);
|
|
658
|
+
const deleted = await this.deleteAttachment(attachment, context);
|
|
661
659
|
updatedAttachments.push(deleted);
|
|
662
660
|
break;
|
|
663
661
|
}
|
|
@@ -735,17 +733,16 @@ class SyncingService {
|
|
|
735
733
|
* On failure, defers to error handler or archives.
|
|
736
734
|
*
|
|
737
735
|
* @param attachment - The attachment record to delete
|
|
736
|
+
* @param context - Attachment context for database operations
|
|
738
737
|
* @returns Updated attachment record
|
|
739
738
|
*/
|
|
740
|
-
async deleteAttachment(attachment) {
|
|
739
|
+
async deleteAttachment(attachment, context) {
|
|
741
740
|
try {
|
|
742
741
|
await this.remoteStorage.deleteFile(attachment);
|
|
743
742
|
if (attachment.localUri) {
|
|
744
743
|
await this.localStorage.deleteFile(attachment.localUri);
|
|
745
744
|
}
|
|
746
|
-
await
|
|
747
|
-
await ctx.deleteAttachment(attachment.id);
|
|
748
|
-
});
|
|
745
|
+
await context.deleteAttachment(attachment.id);
|
|
749
746
|
return {
|
|
750
747
|
...attachment,
|
|
751
748
|
state: AttachmentState.ARCHIVED
|
|
@@ -783,32 +780,108 @@ class SyncingService {
|
|
|
783
780
|
}
|
|
784
781
|
|
|
785
782
|
/**
|
|
786
|
-
*
|
|
783
|
+
* An asynchronous mutex implementation.
|
|
784
|
+
*
|
|
785
|
+
* @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
|
|
787
786
|
*/
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
787
|
+
class Mutex {
|
|
788
|
+
inCriticalSection = false;
|
|
789
|
+
// Linked list of waiters. We don't expect the wait list to become particularly large, and this allows removing
|
|
790
|
+
// aborted waiters from the middle of the list efficiently.
|
|
791
|
+
firstWaiter;
|
|
792
|
+
lastWaiter;
|
|
793
|
+
addWaiter(onAcquire) {
|
|
794
|
+
const node = {
|
|
795
|
+
isActive: true,
|
|
796
|
+
onAcquire,
|
|
797
|
+
prev: this.lastWaiter
|
|
798
|
+
};
|
|
799
|
+
if (this.lastWaiter) {
|
|
800
|
+
this.lastWaiter.next = node;
|
|
801
|
+
this.lastWaiter = node;
|
|
802
|
+
}
|
|
803
|
+
else {
|
|
804
|
+
// First waiter
|
|
805
|
+
this.lastWaiter = this.firstWaiter = node;
|
|
806
|
+
}
|
|
807
|
+
return node;
|
|
808
|
+
}
|
|
809
|
+
deactivateWaiter(waiter) {
|
|
810
|
+
const { prev, next } = waiter;
|
|
811
|
+
waiter.isActive = false;
|
|
812
|
+
if (prev)
|
|
813
|
+
prev.next = next;
|
|
814
|
+
if (next)
|
|
815
|
+
next.prev = prev;
|
|
816
|
+
if (waiter == this.firstWaiter)
|
|
817
|
+
this.firstWaiter = next;
|
|
818
|
+
if (waiter == this.lastWaiter)
|
|
819
|
+
this.lastWaiter = prev;
|
|
820
|
+
}
|
|
821
|
+
acquire(abort) {
|
|
822
|
+
return new Promise((resolve, reject) => {
|
|
823
|
+
function rejectAborted() {
|
|
824
|
+
reject(abort?.reason ?? new Error('Mutex acquire aborted'));
|
|
806
825
|
}
|
|
807
|
-
|
|
808
|
-
|
|
826
|
+
if (abort?.aborted) {
|
|
827
|
+
return rejectAborted();
|
|
828
|
+
}
|
|
829
|
+
let holdsMutex = false;
|
|
830
|
+
const markCompleted = () => {
|
|
831
|
+
if (!holdsMutex)
|
|
832
|
+
return;
|
|
833
|
+
holdsMutex = false;
|
|
834
|
+
const waiter = this.firstWaiter;
|
|
835
|
+
if (waiter) {
|
|
836
|
+
this.deactivateWaiter(waiter);
|
|
837
|
+
// Still in critical section, but owned by next waiter now.
|
|
838
|
+
waiter.onAcquire();
|
|
839
|
+
}
|
|
840
|
+
else {
|
|
841
|
+
this.inCriticalSection = false;
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
if (!this.inCriticalSection) {
|
|
845
|
+
this.inCriticalSection = true;
|
|
846
|
+
holdsMutex = true;
|
|
847
|
+
return resolve(markCompleted);
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
let node;
|
|
851
|
+
const onAbort = () => {
|
|
852
|
+
abort?.removeEventListener('abort', onAbort);
|
|
853
|
+
if (node.isActive) {
|
|
854
|
+
this.deactivateWaiter(node);
|
|
855
|
+
rejectAborted();
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
node = this.addWaiter(() => {
|
|
859
|
+
abort?.removeEventListener('abort', onAbort);
|
|
860
|
+
holdsMutex = true;
|
|
861
|
+
resolve(markCompleted);
|
|
862
|
+
});
|
|
863
|
+
abort?.addEventListener('abort', onAbort);
|
|
809
864
|
}
|
|
810
865
|
});
|
|
811
|
-
}
|
|
866
|
+
}
|
|
867
|
+
async runExclusive(fn, abort) {
|
|
868
|
+
const returnMutex = await this.acquire(abort);
|
|
869
|
+
try {
|
|
870
|
+
return await fn();
|
|
871
|
+
}
|
|
872
|
+
finally {
|
|
873
|
+
returnMutex();
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
function timeoutSignal(timeout) {
|
|
878
|
+
if (timeout == null)
|
|
879
|
+
return;
|
|
880
|
+
if ('timeout' in AbortSignal)
|
|
881
|
+
return AbortSignal.timeout(timeout);
|
|
882
|
+
const controller = new AbortController();
|
|
883
|
+
setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
|
|
884
|
+
return controller.signal;
|
|
812
885
|
}
|
|
813
886
|
|
|
814
887
|
/**
|
|
@@ -857,7 +930,7 @@ class AttachmentService {
|
|
|
857
930
|
* Executes a callback with exclusive access to the attachment context.
|
|
858
931
|
*/
|
|
859
932
|
async withContext(callback) {
|
|
860
|
-
return
|
|
933
|
+
return this.mutex.runExclusive(async () => {
|
|
861
934
|
return callback(this.context);
|
|
862
935
|
});
|
|
863
936
|
}
|
|
@@ -893,9 +966,15 @@ class AttachmentQueue {
|
|
|
893
966
|
tableName;
|
|
894
967
|
/** Logger instance for diagnostic information */
|
|
895
968
|
logger;
|
|
896
|
-
/** Interval in milliseconds between periodic sync operations.
|
|
969
|
+
/** Interval in milliseconds between periodic sync operations. Acts as a polling timer to retry
|
|
970
|
+
* failed uploads/downloads, especially after the app goes offline. Default: 30000 (30 seconds) */
|
|
897
971
|
syncIntervalMs = 30 * 1000;
|
|
898
|
-
/**
|
|
972
|
+
/** Throttle duration in milliseconds for the reactive watch query on the attachments table.
|
|
973
|
+
* When attachment records change, a watch query detects the change and triggers a sync.
|
|
974
|
+
* This throttle prevents the sync from firing too rapidly when many changes happen in
|
|
975
|
+
* quick succession (e.g., bulk inserts). This is distinct from syncIntervalMs — it controls
|
|
976
|
+
* how quickly the queue reacts to changes, while syncIntervalMs controls how often it polls
|
|
977
|
+
* for retries. Default: 30 (from DEFAULT_WATCH_THROTTLE_MS) */
|
|
899
978
|
syncThrottleDuration;
|
|
900
979
|
/** Whether to automatically download remote attachments. Default: true */
|
|
901
980
|
downloadAttachments = true;
|
|
@@ -919,8 +998,8 @@ class AttachmentQueue {
|
|
|
919
998
|
* @param options.watchAttachments - Callback for monitoring attachment changes in your data model
|
|
920
999
|
* @param options.tableName - Name of the table to store attachment records. Default: 'ps_attachment_queue'
|
|
921
1000
|
* @param options.logger - Logger instance. Defaults to db.logger
|
|
922
|
-
* @param options.syncIntervalMs -
|
|
923
|
-
* @param options.syncThrottleDuration - Throttle duration for
|
|
1001
|
+
* @param options.syncIntervalMs - Periodic polling interval in milliseconds for retrying failed uploads/downloads. Default: 30000
|
|
1002
|
+
* @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
|
|
924
1003
|
* @param options.downloadAttachments - Whether to automatically download remote attachments. Default: true
|
|
925
1004
|
* @param options.archivedCacheLimit - Maximum archived attachments before cleanup. Default: 100
|
|
926
1005
|
*/
|
|
@@ -1681,6 +1760,49 @@ var Logger = /*@__PURE__*/getDefaultExportFromCjs(loggerExports);
|
|
|
1681
1760
|
* Set of generic interfaces to allow PowerSync compatibility with
|
|
1682
1761
|
* different SQLite DB implementations.
|
|
1683
1762
|
*/
|
|
1763
|
+
/**
|
|
1764
|
+
* Implements {@link DBGetUtils} on a {@link SqlRunner}.
|
|
1765
|
+
*/
|
|
1766
|
+
function DBGetUtilsDefaultMixin(Base) {
|
|
1767
|
+
return class extends Base {
|
|
1768
|
+
async getAll(sql, parameters) {
|
|
1769
|
+
const res = await this.execute(sql, parameters);
|
|
1770
|
+
return res.rows?._array ?? [];
|
|
1771
|
+
}
|
|
1772
|
+
async getOptional(sql, parameters) {
|
|
1773
|
+
const res = await this.execute(sql, parameters);
|
|
1774
|
+
return res.rows?.item(0) ?? null;
|
|
1775
|
+
}
|
|
1776
|
+
async get(sql, parameters) {
|
|
1777
|
+
const res = await this.execute(sql, parameters);
|
|
1778
|
+
const first = res.rows?.item(0);
|
|
1779
|
+
if (!first) {
|
|
1780
|
+
throw new Error('Result set is empty');
|
|
1781
|
+
}
|
|
1782
|
+
return first;
|
|
1783
|
+
}
|
|
1784
|
+
async executeBatch(query, params = []) {
|
|
1785
|
+
// If this context can run batch statements natively, use that.
|
|
1786
|
+
// @ts-ignore
|
|
1787
|
+
if (super.executeBatch) {
|
|
1788
|
+
// @ts-ignore
|
|
1789
|
+
return super.executeBatch(query, params);
|
|
1790
|
+
}
|
|
1791
|
+
// Emulate executeBatch by running statements individually.
|
|
1792
|
+
let lastInsertId;
|
|
1793
|
+
let rowsAffected = 0;
|
|
1794
|
+
for (const set of params) {
|
|
1795
|
+
const result = await this.execute(query, set);
|
|
1796
|
+
lastInsertId = result.insertId;
|
|
1797
|
+
rowsAffected += result.rowsAffected;
|
|
1798
|
+
}
|
|
1799
|
+
return {
|
|
1800
|
+
rowsAffected,
|
|
1801
|
+
insertId: lastInsertId
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
};
|
|
1805
|
+
}
|
|
1684
1806
|
/**
|
|
1685
1807
|
* Update table operation numbers from SQLite
|
|
1686
1808
|
*/
|
|
@@ -1690,6 +1812,89 @@ var RowUpdateType;
|
|
|
1690
1812
|
RowUpdateType[RowUpdateType["SQLITE_DELETE"] = 9] = "SQLITE_DELETE";
|
|
1691
1813
|
RowUpdateType[RowUpdateType["SQLITE_UPDATE"] = 23] = "SQLITE_UPDATE";
|
|
1692
1814
|
})(RowUpdateType || (RowUpdateType = {}));
|
|
1815
|
+
/**
|
|
1816
|
+
* A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool.readLock} and
|
|
1817
|
+
* {@link ConnectionPool.writeLock}.
|
|
1818
|
+
*/
|
|
1819
|
+
function DBAdapterDefaultMixin(Base) {
|
|
1820
|
+
return class extends Base {
|
|
1821
|
+
readTransaction(fn, options) {
|
|
1822
|
+
return this.readLock((ctx) => TransactionImplementation.runWith(ctx, fn), options);
|
|
1823
|
+
}
|
|
1824
|
+
writeTransaction(fn, options) {
|
|
1825
|
+
return this.writeLock((ctx) => TransactionImplementation.runWith(ctx, fn), options);
|
|
1826
|
+
}
|
|
1827
|
+
getAll(sql, parameters) {
|
|
1828
|
+
return this.readLock((ctx) => ctx.getAll(sql, parameters));
|
|
1829
|
+
}
|
|
1830
|
+
getOptional(sql, parameters) {
|
|
1831
|
+
return this.readLock((ctx) => ctx.getOptional(sql, parameters));
|
|
1832
|
+
}
|
|
1833
|
+
get(sql, parameters) {
|
|
1834
|
+
return this.readLock((ctx) => ctx.get(sql, parameters));
|
|
1835
|
+
}
|
|
1836
|
+
execute(query, params) {
|
|
1837
|
+
return this.writeLock((ctx) => ctx.execute(query, params));
|
|
1838
|
+
}
|
|
1839
|
+
executeRaw(query, params) {
|
|
1840
|
+
return this.writeLock((ctx) => ctx.executeRaw(query, params));
|
|
1841
|
+
}
|
|
1842
|
+
executeBatch(query, params) {
|
|
1843
|
+
return this.writeTransaction((tx) => tx.executeBatch(query, params));
|
|
1844
|
+
}
|
|
1845
|
+
};
|
|
1846
|
+
}
|
|
1847
|
+
class BaseTransaction {
|
|
1848
|
+
inner;
|
|
1849
|
+
finalized = false;
|
|
1850
|
+
constructor(inner) {
|
|
1851
|
+
this.inner = inner;
|
|
1852
|
+
}
|
|
1853
|
+
async commit() {
|
|
1854
|
+
if (this.finalized) {
|
|
1855
|
+
return { rowsAffected: 0 };
|
|
1856
|
+
}
|
|
1857
|
+
this.finalized = true;
|
|
1858
|
+
return this.inner.execute('COMMIT');
|
|
1859
|
+
}
|
|
1860
|
+
async rollback() {
|
|
1861
|
+
if (this.finalized) {
|
|
1862
|
+
return { rowsAffected: 0 };
|
|
1863
|
+
}
|
|
1864
|
+
this.finalized = true;
|
|
1865
|
+
return this.inner.execute('ROLLBACK');
|
|
1866
|
+
}
|
|
1867
|
+
execute(query, params) {
|
|
1868
|
+
return this.inner.execute(query, params);
|
|
1869
|
+
}
|
|
1870
|
+
executeRaw(query, params) {
|
|
1871
|
+
return this.inner.executeRaw(query, params);
|
|
1872
|
+
}
|
|
1873
|
+
executeBatch(query, params) {
|
|
1874
|
+
return this.inner.executeBatch(query, params);
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
class TransactionImplementation extends DBGetUtilsDefaultMixin(BaseTransaction) {
|
|
1878
|
+
static async runWith(ctx, fn) {
|
|
1879
|
+
let tx = new TransactionImplementation(ctx);
|
|
1880
|
+
try {
|
|
1881
|
+
await ctx.execute('BEGIN IMMEDIATE');
|
|
1882
|
+
const result = await fn(tx);
|
|
1883
|
+
await tx.commit();
|
|
1884
|
+
return result;
|
|
1885
|
+
}
|
|
1886
|
+
catch (ex) {
|
|
1887
|
+
try {
|
|
1888
|
+
await tx.rollback();
|
|
1889
|
+
}
|
|
1890
|
+
catch (ex2) {
|
|
1891
|
+
// In rare cases, a rollback may fail.
|
|
1892
|
+
// Safe to ignore.
|
|
1893
|
+
}
|
|
1894
|
+
throw ex;
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1693
1898
|
function isBatchedUpdateNotification(update) {
|
|
1694
1899
|
return 'tables' in update;
|
|
1695
1900
|
}
|
|
@@ -10455,7 +10660,7 @@ function requireDist () {
|
|
|
10455
10660
|
|
|
10456
10661
|
var distExports = requireDist();
|
|
10457
10662
|
|
|
10458
|
-
var version = "1.
|
|
10663
|
+
var version = "1.50.0";
|
|
10459
10664
|
var PACKAGE = {
|
|
10460
10665
|
version: version};
|
|
10461
10666
|
|
|
@@ -12488,7 +12693,7 @@ class TriggerManagerImpl {
|
|
|
12488
12693
|
}
|
|
12489
12694
|
async createDiffTrigger(options) {
|
|
12490
12695
|
await this.db.waitForReady();
|
|
12491
|
-
const { source, destination, columns, when, hooks,
|
|
12696
|
+
const { source, destination, columns, when, hooks, setupContext,
|
|
12492
12697
|
// Fall back to the provided default if not given on this level
|
|
12493
12698
|
useStorage = this.defaultConfig.useStorageByDefault } = options;
|
|
12494
12699
|
const operations = Object.keys(when);
|
|
@@ -12543,13 +12748,20 @@ class TriggerManagerImpl {
|
|
|
12543
12748
|
* we need to ensure we can cleanup the created resources.
|
|
12544
12749
|
* We unfortunately cannot rely on transaction rollback.
|
|
12545
12750
|
*/
|
|
12546
|
-
const cleanup = async () => {
|
|
12751
|
+
const cleanup = async (options) => {
|
|
12752
|
+
const { context } = options ?? {};
|
|
12547
12753
|
disposeWarningListener();
|
|
12548
|
-
|
|
12754
|
+
const doCleanup = async (tx) => {
|
|
12549
12755
|
await this.removeTriggers(tx, triggerIds);
|
|
12550
|
-
await tx.execute(
|
|
12756
|
+
await tx.execute(`DROP TABLE IF EXISTS ${destination};`);
|
|
12551
12757
|
await releaseStorageClaim?.();
|
|
12552
|
-
}
|
|
12758
|
+
};
|
|
12759
|
+
if (context) {
|
|
12760
|
+
await doCleanup(context);
|
|
12761
|
+
}
|
|
12762
|
+
else {
|
|
12763
|
+
await this.db.writeLock(doCleanup);
|
|
12764
|
+
}
|
|
12553
12765
|
};
|
|
12554
12766
|
const setup = async (tx) => {
|
|
12555
12767
|
// Allow user code to execute in this lock context before the trigger is created.
|
|
@@ -12623,12 +12835,17 @@ class TriggerManagerImpl {
|
|
|
12623
12835
|
}
|
|
12624
12836
|
};
|
|
12625
12837
|
try {
|
|
12626
|
-
|
|
12838
|
+
if (setupContext) {
|
|
12839
|
+
await setup(setupContext);
|
|
12840
|
+
}
|
|
12841
|
+
else {
|
|
12842
|
+
await this.db.writeLock(setup);
|
|
12843
|
+
}
|
|
12627
12844
|
return cleanup;
|
|
12628
12845
|
}
|
|
12629
12846
|
catch (error) {
|
|
12630
12847
|
try {
|
|
12631
|
-
await cleanup();
|
|
12848
|
+
await cleanup(setupContext ? { context: setupContext } : undefined);
|
|
12632
12849
|
}
|
|
12633
12850
|
catch (cleanupError) {
|
|
12634
12851
|
throw new AggregateError([error, cleanupError], 'Error during operation and cleanup');
|
|
@@ -13300,6 +13517,10 @@ SELECT * FROM crud_entries;
|
|
|
13300
13517
|
* Execute a SQL write (INSERT/UPDATE/DELETE) query
|
|
13301
13518
|
* and optionally return results.
|
|
13302
13519
|
*
|
|
13520
|
+
* When using the default client-side [JSON-based view system](https://docs.powersync.com/architecture/client-architecture#client-side-schema-and-sqlite-database-structure),
|
|
13521
|
+
* the returned result's `rowsAffected` may be `0` for successful `UPDATE` and `DELETE` statements.
|
|
13522
|
+
* Use a `RETURNING` clause and inspect `result.rows` when you need to confirm which rows changed.
|
|
13523
|
+
*
|
|
13303
13524
|
* @param sql The SQL query to execute
|
|
13304
13525
|
* @param parameters Optional array of parameters to bind to the query
|
|
13305
13526
|
* @returns The query result as an object with structured key-value pairs
|
|
@@ -13396,7 +13617,7 @@ SELECT * FROM crud_entries;
|
|
|
13396
13617
|
async readTransaction(callback, lockTimeout = DEFAULT_LOCK_TIMEOUT_MS) {
|
|
13397
13618
|
await this.waitForReady();
|
|
13398
13619
|
return this.database.readTransaction(async (tx) => {
|
|
13399
|
-
const res = await callback(
|
|
13620
|
+
const res = await callback(tx);
|
|
13400
13621
|
await tx.rollback();
|
|
13401
13622
|
return res;
|
|
13402
13623
|
}, { timeoutMs: lockTimeout });
|
|
@@ -14373,5 +14594,5 @@ const parseQuery = (query, parameters) => {
|
|
|
14373
14594
|
return { sqlStatement, parameters: parameters };
|
|
14374
14595
|
};
|
|
14375
14596
|
|
|
14376
|
-
export { ATTACHMENT_TABLE, AbortOperation, AbstractPowerSyncDatabase, AbstractPowerSyncDatabaseOpenFactory, AbstractQueryProcessor, AbstractRemote, AbstractStreamingSyncImplementation, ArrayComparator, AttachmentContext, AttachmentQueue, AttachmentService, AttachmentState, AttachmentTable, BaseObserver, Column, ColumnType, ConnectionClosedError, ConnectionManager, ControlledExecutor, CrudBatch, CrudEntry, CrudTransaction, DEFAULT_CRUD_BATCH_LIMIT, DEFAULT_CRUD_UPLOAD_THROTTLE_MS, DEFAULT_INDEX_COLUMN_OPTIONS, DEFAULT_INDEX_OPTIONS, DEFAULT_LOCK_TIMEOUT_MS, DEFAULT_POWERSYNC_CLOSE_OPTIONS, DEFAULT_POWERSYNC_DB_OPTIONS, DEFAULT_PRESSURE_LIMITS, DEFAULT_REMOTE_LOGGER, DEFAULT_REMOTE_OPTIONS, DEFAULT_RETRY_DELAY_MS, DEFAULT_ROW_COMPARATOR, DEFAULT_STREAMING_SYNC_OPTIONS, DEFAULT_STREAM_CONNECTION_OPTIONS, DEFAULT_SYNC_CLIENT_IMPLEMENTATION, DEFAULT_TABLE_OPTIONS, DEFAULT_WATCH_QUERY_OPTIONS, DEFAULT_WATCH_THROTTLE_MS, DataStream, DiffTriggerOperation, DifferentialQueryProcessor, EMPTY_DIFFERENTIAL, EncodingType, FalsyComparator, FetchImplementationProvider, FetchStrategy, GetAllQuery, Index, IndexedColumn, InvalidSQLCharacters, LockType, LogLevel, MAX_AMOUNT_OF_COLUMNS, MAX_OP_ID, MEMORY_TRIGGER_CLAIM_MANAGER, OnChangeQueryProcessor, OpType, OpTypeEnum, OplogEntry, PSInternalTable, PowerSyncControlCommand, RowUpdateType, Schema, SqliteBucketStorage, SyncClientImplementation, SyncDataBatch, SyncDataBucket, SyncProgress, SyncStatus, SyncStreamConnectionMethod, SyncingService, Table, TableV2, TriggerManagerImpl, UpdateType, UploadQueueStats, WatchedQueryListenerEvent, attachmentFromSql, column, compilableQueryWatch, createBaseLogger, createLogger, extractTableUpdates, isBatchedUpdateNotification, isContinueCheckpointRequest, isDBAdapter, isPowerSyncDatabaseOptionsWithSettings, isSQLOpenFactory, isSQLOpenOptions, isStreamingKeepalive, isStreamingSyncCheckpoint, isStreamingSyncCheckpointComplete, isStreamingSyncCheckpointDiff, isStreamingSyncCheckpointPartiallyComplete, isStreamingSyncData, isSyncNewCheckpointRequest,
|
|
14597
|
+
export { ATTACHMENT_TABLE, AbortOperation, AbstractPowerSyncDatabase, AbstractPowerSyncDatabaseOpenFactory, AbstractQueryProcessor, AbstractRemote, AbstractStreamingSyncImplementation, ArrayComparator, AttachmentContext, AttachmentQueue, AttachmentService, AttachmentState, AttachmentTable, BaseObserver, Column, ColumnType, ConnectionClosedError, ConnectionManager, ControlledExecutor, CrudBatch, CrudEntry, CrudTransaction, DBAdapterDefaultMixin, DBGetUtilsDefaultMixin, DEFAULT_CRUD_BATCH_LIMIT, DEFAULT_CRUD_UPLOAD_THROTTLE_MS, DEFAULT_INDEX_COLUMN_OPTIONS, DEFAULT_INDEX_OPTIONS, DEFAULT_LOCK_TIMEOUT_MS, DEFAULT_POWERSYNC_CLOSE_OPTIONS, DEFAULT_POWERSYNC_DB_OPTIONS, DEFAULT_PRESSURE_LIMITS, DEFAULT_REMOTE_LOGGER, DEFAULT_REMOTE_OPTIONS, DEFAULT_RETRY_DELAY_MS, DEFAULT_ROW_COMPARATOR, DEFAULT_STREAMING_SYNC_OPTIONS, DEFAULT_STREAM_CONNECTION_OPTIONS, DEFAULT_SYNC_CLIENT_IMPLEMENTATION, DEFAULT_TABLE_OPTIONS, DEFAULT_WATCH_QUERY_OPTIONS, DEFAULT_WATCH_THROTTLE_MS, DataStream, DiffTriggerOperation, DifferentialQueryProcessor, EMPTY_DIFFERENTIAL, EncodingType, FalsyComparator, FetchImplementationProvider, FetchStrategy, GetAllQuery, Index, IndexedColumn, InvalidSQLCharacters, LockType, LogLevel, MAX_AMOUNT_OF_COLUMNS, MAX_OP_ID, MEMORY_TRIGGER_CLAIM_MANAGER, Mutex, OnChangeQueryProcessor, OpType, OpTypeEnum, OplogEntry, PSInternalTable, PowerSyncControlCommand, RowUpdateType, Schema, SqliteBucketStorage, SyncClientImplementation, SyncDataBatch, SyncDataBucket, SyncProgress, SyncStatus, SyncStreamConnectionMethod, SyncingService, Table, TableV2, TriggerManagerImpl, UpdateType, UploadQueueStats, WatchedQueryListenerEvent, attachmentFromSql, column, compilableQueryWatch, createBaseLogger, createLogger, extractTableUpdates, isBatchedUpdateNotification, isContinueCheckpointRequest, isDBAdapter, isPowerSyncDatabaseOptionsWithSettings, isSQLOpenFactory, isSQLOpenOptions, isStreamingKeepalive, isStreamingSyncCheckpoint, isStreamingSyncCheckpointComplete, isStreamingSyncCheckpointDiff, isStreamingSyncCheckpointPartiallyComplete, isStreamingSyncData, isSyncNewCheckpointRequest, parseQuery, runOnSchemaChange, sanitizeSQL, sanitizeUUID, timeoutSignal };
|
|
14377
14598
|
//# sourceMappingURL=bundle.mjs.map
|