@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.node.cjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var asyncMutex = require('async-mutex');
|
|
4
3
|
var eventIterator = require('event-iterator');
|
|
5
4
|
var node_buffer = require('node:buffer');
|
|
6
5
|
|
|
@@ -661,7 +660,7 @@ class SyncingService {
|
|
|
661
660
|
updatedAttachments.push(downloaded);
|
|
662
661
|
break;
|
|
663
662
|
case exports.AttachmentState.QUEUED_DELETE:
|
|
664
|
-
const deleted = await this.deleteAttachment(attachment);
|
|
663
|
+
const deleted = await this.deleteAttachment(attachment, context);
|
|
665
664
|
updatedAttachments.push(deleted);
|
|
666
665
|
break;
|
|
667
666
|
}
|
|
@@ -739,17 +738,16 @@ class SyncingService {
|
|
|
739
738
|
* On failure, defers to error handler or archives.
|
|
740
739
|
*
|
|
741
740
|
* @param attachment - The attachment record to delete
|
|
741
|
+
* @param context - Attachment context for database operations
|
|
742
742
|
* @returns Updated attachment record
|
|
743
743
|
*/
|
|
744
|
-
async deleteAttachment(attachment) {
|
|
744
|
+
async deleteAttachment(attachment, context) {
|
|
745
745
|
try {
|
|
746
746
|
await this.remoteStorage.deleteFile(attachment);
|
|
747
747
|
if (attachment.localUri) {
|
|
748
748
|
await this.localStorage.deleteFile(attachment.localUri);
|
|
749
749
|
}
|
|
750
|
-
await
|
|
751
|
-
await ctx.deleteAttachment(attachment.id);
|
|
752
|
-
});
|
|
750
|
+
await context.deleteAttachment(attachment.id);
|
|
753
751
|
return {
|
|
754
752
|
...attachment,
|
|
755
753
|
state: exports.AttachmentState.ARCHIVED
|
|
@@ -787,32 +785,108 @@ class SyncingService {
|
|
|
787
785
|
}
|
|
788
786
|
|
|
789
787
|
/**
|
|
790
|
-
*
|
|
788
|
+
* An asynchronous mutex implementation.
|
|
789
|
+
*
|
|
790
|
+
* @internal This class is meant to be used in PowerSync SDKs only, and is not part of the public API.
|
|
791
791
|
*/
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
792
|
+
class Mutex {
|
|
793
|
+
inCriticalSection = false;
|
|
794
|
+
// Linked list of waiters. We don't expect the wait list to become particularly large, and this allows removing
|
|
795
|
+
// aborted waiters from the middle of the list efficiently.
|
|
796
|
+
firstWaiter;
|
|
797
|
+
lastWaiter;
|
|
798
|
+
addWaiter(onAcquire) {
|
|
799
|
+
const node = {
|
|
800
|
+
isActive: true,
|
|
801
|
+
onAcquire,
|
|
802
|
+
prev: this.lastWaiter
|
|
803
|
+
};
|
|
804
|
+
if (this.lastWaiter) {
|
|
805
|
+
this.lastWaiter.next = node;
|
|
806
|
+
this.lastWaiter = node;
|
|
807
|
+
}
|
|
808
|
+
else {
|
|
809
|
+
// First waiter
|
|
810
|
+
this.lastWaiter = this.firstWaiter = node;
|
|
811
|
+
}
|
|
812
|
+
return node;
|
|
813
|
+
}
|
|
814
|
+
deactivateWaiter(waiter) {
|
|
815
|
+
const { prev, next } = waiter;
|
|
816
|
+
waiter.isActive = false;
|
|
817
|
+
if (prev)
|
|
818
|
+
prev.next = next;
|
|
819
|
+
if (next)
|
|
820
|
+
next.prev = prev;
|
|
821
|
+
if (waiter == this.firstWaiter)
|
|
822
|
+
this.firstWaiter = next;
|
|
823
|
+
if (waiter == this.lastWaiter)
|
|
824
|
+
this.lastWaiter = prev;
|
|
825
|
+
}
|
|
826
|
+
acquire(abort) {
|
|
827
|
+
return new Promise((resolve, reject) => {
|
|
828
|
+
function rejectAborted() {
|
|
829
|
+
reject(abort?.reason ?? new Error('Mutex acquire aborted'));
|
|
810
830
|
}
|
|
811
|
-
|
|
812
|
-
|
|
831
|
+
if (abort?.aborted) {
|
|
832
|
+
return rejectAborted();
|
|
833
|
+
}
|
|
834
|
+
let holdsMutex = false;
|
|
835
|
+
const markCompleted = () => {
|
|
836
|
+
if (!holdsMutex)
|
|
837
|
+
return;
|
|
838
|
+
holdsMutex = false;
|
|
839
|
+
const waiter = this.firstWaiter;
|
|
840
|
+
if (waiter) {
|
|
841
|
+
this.deactivateWaiter(waiter);
|
|
842
|
+
// Still in critical section, but owned by next waiter now.
|
|
843
|
+
waiter.onAcquire();
|
|
844
|
+
}
|
|
845
|
+
else {
|
|
846
|
+
this.inCriticalSection = false;
|
|
847
|
+
}
|
|
848
|
+
};
|
|
849
|
+
if (!this.inCriticalSection) {
|
|
850
|
+
this.inCriticalSection = true;
|
|
851
|
+
holdsMutex = true;
|
|
852
|
+
return resolve(markCompleted);
|
|
853
|
+
}
|
|
854
|
+
else {
|
|
855
|
+
let node;
|
|
856
|
+
const onAbort = () => {
|
|
857
|
+
abort?.removeEventListener('abort', onAbort);
|
|
858
|
+
if (node.isActive) {
|
|
859
|
+
this.deactivateWaiter(node);
|
|
860
|
+
rejectAborted();
|
|
861
|
+
}
|
|
862
|
+
};
|
|
863
|
+
node = this.addWaiter(() => {
|
|
864
|
+
abort?.removeEventListener('abort', onAbort);
|
|
865
|
+
holdsMutex = true;
|
|
866
|
+
resolve(markCompleted);
|
|
867
|
+
});
|
|
868
|
+
abort?.addEventListener('abort', onAbort);
|
|
813
869
|
}
|
|
814
870
|
});
|
|
815
|
-
}
|
|
871
|
+
}
|
|
872
|
+
async runExclusive(fn, abort) {
|
|
873
|
+
const returnMutex = await this.acquire(abort);
|
|
874
|
+
try {
|
|
875
|
+
return await fn();
|
|
876
|
+
}
|
|
877
|
+
finally {
|
|
878
|
+
returnMutex();
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
function timeoutSignal(timeout) {
|
|
883
|
+
if (timeout == null)
|
|
884
|
+
return;
|
|
885
|
+
if ('timeout' in AbortSignal)
|
|
886
|
+
return AbortSignal.timeout(timeout);
|
|
887
|
+
const controller = new AbortController();
|
|
888
|
+
setTimeout(() => controller.abort(new Error('Timeout waiting for lock')), timeout);
|
|
889
|
+
return controller.signal;
|
|
816
890
|
}
|
|
817
891
|
|
|
818
892
|
/**
|
|
@@ -824,7 +898,7 @@ class AttachmentService {
|
|
|
824
898
|
db;
|
|
825
899
|
logger;
|
|
826
900
|
tableName;
|
|
827
|
-
mutex = new
|
|
901
|
+
mutex = new Mutex();
|
|
828
902
|
context;
|
|
829
903
|
constructor(db, logger, tableName = 'attachments', archivedCacheLimit = 100) {
|
|
830
904
|
this.db = db;
|
|
@@ -861,7 +935,7 @@ class AttachmentService {
|
|
|
861
935
|
* Executes a callback with exclusive access to the attachment context.
|
|
862
936
|
*/
|
|
863
937
|
async withContext(callback) {
|
|
864
|
-
return
|
|
938
|
+
return this.mutex.runExclusive(async () => {
|
|
865
939
|
return callback(this.context);
|
|
866
940
|
});
|
|
867
941
|
}
|
|
@@ -897,9 +971,15 @@ class AttachmentQueue {
|
|
|
897
971
|
tableName;
|
|
898
972
|
/** Logger instance for diagnostic information */
|
|
899
973
|
logger;
|
|
900
|
-
/** Interval in milliseconds between periodic sync operations.
|
|
974
|
+
/** Interval in milliseconds between periodic sync operations. Acts as a polling timer to retry
|
|
975
|
+
* failed uploads/downloads, especially after the app goes offline. Default: 30000 (30 seconds) */
|
|
901
976
|
syncIntervalMs = 30 * 1000;
|
|
902
|
-
/**
|
|
977
|
+
/** Throttle duration in milliseconds for the reactive watch query on the attachments table.
|
|
978
|
+
* When attachment records change, a watch query detects the change and triggers a sync.
|
|
979
|
+
* This throttle prevents the sync from firing too rapidly when many changes happen in
|
|
980
|
+
* quick succession (e.g., bulk inserts). This is distinct from syncIntervalMs — it controls
|
|
981
|
+
* how quickly the queue reacts to changes, while syncIntervalMs controls how often it polls
|
|
982
|
+
* for retries. Default: 30 (from DEFAULT_WATCH_THROTTLE_MS) */
|
|
903
983
|
syncThrottleDuration;
|
|
904
984
|
/** Whether to automatically download remote attachments. Default: true */
|
|
905
985
|
downloadAttachments = true;
|
|
@@ -923,8 +1003,8 @@ class AttachmentQueue {
|
|
|
923
1003
|
* @param options.watchAttachments - Callback for monitoring attachment changes in your data model
|
|
924
1004
|
* @param options.tableName - Name of the table to store attachment records. Default: 'ps_attachment_queue'
|
|
925
1005
|
* @param options.logger - Logger instance. Defaults to db.logger
|
|
926
|
-
* @param options.syncIntervalMs -
|
|
927
|
-
* @param options.syncThrottleDuration - Throttle duration for
|
|
1006
|
+
* @param options.syncIntervalMs - Periodic polling interval in milliseconds for retrying failed uploads/downloads. Default: 30000
|
|
1007
|
+
* @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
|
|
928
1008
|
* @param options.downloadAttachments - Whether to automatically download remote attachments. Default: true
|
|
929
1009
|
* @param options.archivedCacheLimit - Maximum archived attachments before cleanup. Default: 100
|
|
930
1010
|
*/
|
|
@@ -1532,6 +1612,49 @@ var Logger = /*@__PURE__*/getDefaultExportFromCjs(loggerExports);
|
|
|
1532
1612
|
* Set of generic interfaces to allow PowerSync compatibility with
|
|
1533
1613
|
* different SQLite DB implementations.
|
|
1534
1614
|
*/
|
|
1615
|
+
/**
|
|
1616
|
+
* Implements {@link DBGetUtils} on a {@link SqlRunner}.
|
|
1617
|
+
*/
|
|
1618
|
+
function DBGetUtilsDefaultMixin(Base) {
|
|
1619
|
+
return class extends Base {
|
|
1620
|
+
async getAll(sql, parameters) {
|
|
1621
|
+
const res = await this.execute(sql, parameters);
|
|
1622
|
+
return res.rows?._array ?? [];
|
|
1623
|
+
}
|
|
1624
|
+
async getOptional(sql, parameters) {
|
|
1625
|
+
const res = await this.execute(sql, parameters);
|
|
1626
|
+
return res.rows?.item(0) ?? null;
|
|
1627
|
+
}
|
|
1628
|
+
async get(sql, parameters) {
|
|
1629
|
+
const res = await this.execute(sql, parameters);
|
|
1630
|
+
const first = res.rows?.item(0);
|
|
1631
|
+
if (!first) {
|
|
1632
|
+
throw new Error('Result set is empty');
|
|
1633
|
+
}
|
|
1634
|
+
return first;
|
|
1635
|
+
}
|
|
1636
|
+
async executeBatch(query, params = []) {
|
|
1637
|
+
// If this context can run batch statements natively, use that.
|
|
1638
|
+
// @ts-ignore
|
|
1639
|
+
if (super.executeBatch) {
|
|
1640
|
+
// @ts-ignore
|
|
1641
|
+
return super.executeBatch(query, params);
|
|
1642
|
+
}
|
|
1643
|
+
// Emulate executeBatch by running statements individually.
|
|
1644
|
+
let lastInsertId;
|
|
1645
|
+
let rowsAffected = 0;
|
|
1646
|
+
for (const set of params) {
|
|
1647
|
+
const result = await this.execute(query, set);
|
|
1648
|
+
lastInsertId = result.insertId;
|
|
1649
|
+
rowsAffected += result.rowsAffected;
|
|
1650
|
+
}
|
|
1651
|
+
return {
|
|
1652
|
+
rowsAffected,
|
|
1653
|
+
insertId: lastInsertId
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1535
1658
|
/**
|
|
1536
1659
|
* Update table operation numbers from SQLite
|
|
1537
1660
|
*/
|
|
@@ -1541,6 +1664,89 @@ exports.RowUpdateType = void 0;
|
|
|
1541
1664
|
RowUpdateType[RowUpdateType["SQLITE_DELETE"] = 9] = "SQLITE_DELETE";
|
|
1542
1665
|
RowUpdateType[RowUpdateType["SQLITE_UPDATE"] = 23] = "SQLITE_UPDATE";
|
|
1543
1666
|
})(exports.RowUpdateType || (exports.RowUpdateType = {}));
|
|
1667
|
+
/**
|
|
1668
|
+
* A mixin to implement {@link DBAdapter} by delegating to {@link ConnectionPool.readLock} and
|
|
1669
|
+
* {@link ConnectionPool.writeLock}.
|
|
1670
|
+
*/
|
|
1671
|
+
function DBAdapterDefaultMixin(Base) {
|
|
1672
|
+
return class extends Base {
|
|
1673
|
+
readTransaction(fn, options) {
|
|
1674
|
+
return this.readLock((ctx) => TransactionImplementation.runWith(ctx, fn), options);
|
|
1675
|
+
}
|
|
1676
|
+
writeTransaction(fn, options) {
|
|
1677
|
+
return this.writeLock((ctx) => TransactionImplementation.runWith(ctx, fn), options);
|
|
1678
|
+
}
|
|
1679
|
+
getAll(sql, parameters) {
|
|
1680
|
+
return this.readLock((ctx) => ctx.getAll(sql, parameters));
|
|
1681
|
+
}
|
|
1682
|
+
getOptional(sql, parameters) {
|
|
1683
|
+
return this.readLock((ctx) => ctx.getOptional(sql, parameters));
|
|
1684
|
+
}
|
|
1685
|
+
get(sql, parameters) {
|
|
1686
|
+
return this.readLock((ctx) => ctx.get(sql, parameters));
|
|
1687
|
+
}
|
|
1688
|
+
execute(query, params) {
|
|
1689
|
+
return this.writeLock((ctx) => ctx.execute(query, params));
|
|
1690
|
+
}
|
|
1691
|
+
executeRaw(query, params) {
|
|
1692
|
+
return this.writeLock((ctx) => ctx.executeRaw(query, params));
|
|
1693
|
+
}
|
|
1694
|
+
executeBatch(query, params) {
|
|
1695
|
+
return this.writeTransaction((tx) => tx.executeBatch(query, params));
|
|
1696
|
+
}
|
|
1697
|
+
};
|
|
1698
|
+
}
|
|
1699
|
+
class BaseTransaction {
|
|
1700
|
+
inner;
|
|
1701
|
+
finalized = false;
|
|
1702
|
+
constructor(inner) {
|
|
1703
|
+
this.inner = inner;
|
|
1704
|
+
}
|
|
1705
|
+
async commit() {
|
|
1706
|
+
if (this.finalized) {
|
|
1707
|
+
return { rowsAffected: 0 };
|
|
1708
|
+
}
|
|
1709
|
+
this.finalized = true;
|
|
1710
|
+
return this.inner.execute('COMMIT');
|
|
1711
|
+
}
|
|
1712
|
+
async rollback() {
|
|
1713
|
+
if (this.finalized) {
|
|
1714
|
+
return { rowsAffected: 0 };
|
|
1715
|
+
}
|
|
1716
|
+
this.finalized = true;
|
|
1717
|
+
return this.inner.execute('ROLLBACK');
|
|
1718
|
+
}
|
|
1719
|
+
execute(query, params) {
|
|
1720
|
+
return this.inner.execute(query, params);
|
|
1721
|
+
}
|
|
1722
|
+
executeRaw(query, params) {
|
|
1723
|
+
return this.inner.executeRaw(query, params);
|
|
1724
|
+
}
|
|
1725
|
+
executeBatch(query, params) {
|
|
1726
|
+
return this.inner.executeBatch(query, params);
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
class TransactionImplementation extends DBGetUtilsDefaultMixin(BaseTransaction) {
|
|
1730
|
+
static async runWith(ctx, fn) {
|
|
1731
|
+
let tx = new TransactionImplementation(ctx);
|
|
1732
|
+
try {
|
|
1733
|
+
await ctx.execute('BEGIN IMMEDIATE');
|
|
1734
|
+
const result = await fn(tx);
|
|
1735
|
+
await tx.commit();
|
|
1736
|
+
return result;
|
|
1737
|
+
}
|
|
1738
|
+
catch (ex) {
|
|
1739
|
+
try {
|
|
1740
|
+
await tx.rollback();
|
|
1741
|
+
}
|
|
1742
|
+
catch (ex2) {
|
|
1743
|
+
// In rare cases, a rollback may fail.
|
|
1744
|
+
// Safe to ignore.
|
|
1745
|
+
}
|
|
1746
|
+
throw ex;
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1544
1750
|
function isBatchedUpdateNotification(update) {
|
|
1545
1751
|
return 'tables' in update;
|
|
1546
1752
|
}
|
|
@@ -7935,7 +8141,7 @@ function requireDist () {
|
|
|
7935
8141
|
|
|
7936
8142
|
var distExports = requireDist();
|
|
7937
8143
|
|
|
7938
|
-
var version = "1.
|
|
8144
|
+
var version = "1.50.0";
|
|
7939
8145
|
var PACKAGE = {
|
|
7940
8146
|
version: version};
|
|
7941
8147
|
|
|
@@ -9968,7 +10174,7 @@ class TriggerManagerImpl {
|
|
|
9968
10174
|
}
|
|
9969
10175
|
async createDiffTrigger(options) {
|
|
9970
10176
|
await this.db.waitForReady();
|
|
9971
|
-
const { source, destination, columns, when, hooks,
|
|
10177
|
+
const { source, destination, columns, when, hooks, setupContext,
|
|
9972
10178
|
// Fall back to the provided default if not given on this level
|
|
9973
10179
|
useStorage = this.defaultConfig.useStorageByDefault } = options;
|
|
9974
10180
|
const operations = Object.keys(when);
|
|
@@ -10023,13 +10229,20 @@ class TriggerManagerImpl {
|
|
|
10023
10229
|
* we need to ensure we can cleanup the created resources.
|
|
10024
10230
|
* We unfortunately cannot rely on transaction rollback.
|
|
10025
10231
|
*/
|
|
10026
|
-
const cleanup = async () => {
|
|
10232
|
+
const cleanup = async (options) => {
|
|
10233
|
+
const { context } = options ?? {};
|
|
10027
10234
|
disposeWarningListener();
|
|
10028
|
-
|
|
10235
|
+
const doCleanup = async (tx) => {
|
|
10029
10236
|
await this.removeTriggers(tx, triggerIds);
|
|
10030
|
-
await tx.execute(
|
|
10237
|
+
await tx.execute(`DROP TABLE IF EXISTS ${destination};`);
|
|
10031
10238
|
await releaseStorageClaim?.();
|
|
10032
|
-
}
|
|
10239
|
+
};
|
|
10240
|
+
if (context) {
|
|
10241
|
+
await doCleanup(context);
|
|
10242
|
+
}
|
|
10243
|
+
else {
|
|
10244
|
+
await this.db.writeLock(doCleanup);
|
|
10245
|
+
}
|
|
10033
10246
|
};
|
|
10034
10247
|
const setup = async (tx) => {
|
|
10035
10248
|
// Allow user code to execute in this lock context before the trigger is created.
|
|
@@ -10103,12 +10316,17 @@ class TriggerManagerImpl {
|
|
|
10103
10316
|
}
|
|
10104
10317
|
};
|
|
10105
10318
|
try {
|
|
10106
|
-
|
|
10319
|
+
if (setupContext) {
|
|
10320
|
+
await setup(setupContext);
|
|
10321
|
+
}
|
|
10322
|
+
else {
|
|
10323
|
+
await this.db.writeLock(setup);
|
|
10324
|
+
}
|
|
10107
10325
|
return cleanup;
|
|
10108
10326
|
}
|
|
10109
10327
|
catch (error) {
|
|
10110
10328
|
try {
|
|
10111
|
-
await cleanup();
|
|
10329
|
+
await cleanup(setupContext ? { context: setupContext } : undefined);
|
|
10112
10330
|
}
|
|
10113
10331
|
catch (cleanupError) {
|
|
10114
10332
|
throw new AggregateError([error, cleanupError], 'Error during operation and cleanup');
|
|
@@ -10315,7 +10533,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
|
|
|
10315
10533
|
this._schema = schema;
|
|
10316
10534
|
this.ready = false;
|
|
10317
10535
|
this.sdkVersion = '';
|
|
10318
|
-
this.runExclusiveMutex = new
|
|
10536
|
+
this.runExclusiveMutex = new Mutex();
|
|
10319
10537
|
// Start async init
|
|
10320
10538
|
this.subscriptions = {
|
|
10321
10539
|
firstStatusMatching: (predicate, abort) => this.waitForStatus(predicate, abort),
|
|
@@ -10780,6 +10998,10 @@ SELECT * FROM crud_entries;
|
|
|
10780
10998
|
* Execute a SQL write (INSERT/UPDATE/DELETE) query
|
|
10781
10999
|
* and optionally return results.
|
|
10782
11000
|
*
|
|
11001
|
+
* When using the default client-side [JSON-based view system](https://docs.powersync.com/architecture/client-architecture#client-side-schema-and-sqlite-database-structure),
|
|
11002
|
+
* the returned result's `rowsAffected` may be `0` for successful `UPDATE` and `DELETE` statements.
|
|
11003
|
+
* Use a `RETURNING` clause and inspect `result.rows` when you need to confirm which rows changed.
|
|
11004
|
+
*
|
|
10783
11005
|
* @param sql The SQL query to execute
|
|
10784
11006
|
* @param parameters Optional array of parameters to bind to the query
|
|
10785
11007
|
* @returns The query result as an object with structured key-value pairs
|
|
@@ -10876,7 +11098,7 @@ SELECT * FROM crud_entries;
|
|
|
10876
11098
|
async readTransaction(callback, lockTimeout = DEFAULT_LOCK_TIMEOUT_MS) {
|
|
10877
11099
|
await this.waitForReady();
|
|
10878
11100
|
return this.database.readTransaction(async (tx) => {
|
|
10879
|
-
const res = await callback(
|
|
11101
|
+
const res = await callback(tx);
|
|
10880
11102
|
await tx.rollback();
|
|
10881
11103
|
return res;
|
|
10882
11104
|
}, { timeoutMs: lockTimeout });
|
|
@@ -11873,6 +12095,8 @@ exports.ControlledExecutor = ControlledExecutor;
|
|
|
11873
12095
|
exports.CrudBatch = CrudBatch;
|
|
11874
12096
|
exports.CrudEntry = CrudEntry;
|
|
11875
12097
|
exports.CrudTransaction = CrudTransaction;
|
|
12098
|
+
exports.DBAdapterDefaultMixin = DBAdapterDefaultMixin;
|
|
12099
|
+
exports.DBGetUtilsDefaultMixin = DBGetUtilsDefaultMixin;
|
|
11876
12100
|
exports.DEFAULT_CRUD_BATCH_LIMIT = DEFAULT_CRUD_BATCH_LIMIT;
|
|
11877
12101
|
exports.DEFAULT_CRUD_UPLOAD_THROTTLE_MS = DEFAULT_CRUD_UPLOAD_THROTTLE_MS;
|
|
11878
12102
|
exports.DEFAULT_INDEX_COLUMN_OPTIONS = DEFAULT_INDEX_COLUMN_OPTIONS;
|
|
@@ -11904,6 +12128,7 @@ exports.LogLevel = LogLevel;
|
|
|
11904
12128
|
exports.MAX_AMOUNT_OF_COLUMNS = MAX_AMOUNT_OF_COLUMNS;
|
|
11905
12129
|
exports.MAX_OP_ID = MAX_OP_ID;
|
|
11906
12130
|
exports.MEMORY_TRIGGER_CLAIM_MANAGER = MEMORY_TRIGGER_CLAIM_MANAGER;
|
|
12131
|
+
exports.Mutex = Mutex;
|
|
11907
12132
|
exports.OnChangeQueryProcessor = OnChangeQueryProcessor;
|
|
11908
12133
|
exports.OpType = OpType;
|
|
11909
12134
|
exports.OplogEntry = OplogEntry;
|
|
@@ -11937,9 +12162,9 @@ exports.isStreamingSyncCheckpointDiff = isStreamingSyncCheckpointDiff;
|
|
|
11937
12162
|
exports.isStreamingSyncCheckpointPartiallyComplete = isStreamingSyncCheckpointPartiallyComplete;
|
|
11938
12163
|
exports.isStreamingSyncData = isStreamingSyncData;
|
|
11939
12164
|
exports.isSyncNewCheckpointRequest = isSyncNewCheckpointRequest;
|
|
11940
|
-
exports.mutexRunExclusive = mutexRunExclusive;
|
|
11941
12165
|
exports.parseQuery = parseQuery;
|
|
11942
12166
|
exports.runOnSchemaChange = runOnSchemaChange;
|
|
11943
12167
|
exports.sanitizeSQL = sanitizeSQL;
|
|
11944
12168
|
exports.sanitizeUUID = sanitizeUUID;
|
|
12169
|
+
exports.timeoutSignal = timeoutSignal;
|
|
11945
12170
|
//# sourceMappingURL=bundle.node.cjs.map
|