@react-native-replicache/react-native-op-sqlite
Version:
> Plug-in React Native compatibility bindings for [Replicache](https://replicache.dev/).
110 lines (108 loc) • 3.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ReplicacheOPSQLiteTransaction = void 0;
var _replicacheGenericSqlite = require("@react-native-replicache/replicache-generic-sqlite");
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
class ReplicacheOPSQLiteTransaction extends _replicacheGenericSqlite.ReplicacheGenericSQLiteTransaction {
constructor(db) {
super();
this.db = db;
_defineProperty(this, "_tx", null);
_defineProperty(this, "_transactionCommittedSubscriptions", new Set());
_defineProperty(this, "_txCommitted", false);
_defineProperty(this, "_transactionEndedSubscriptions", new Set());
_defineProperty(this, "_txEnded", false);
}
// op-sqlite doesn't support readonly
async start() {
return await new Promise((resolve, reject) => {
let didResolve = false;
try {
this.db.transaction(async tx => {
didResolve = true;
this._tx = tx;
resolve();
try {
// op-sqlite auto-commits our transaction when this callback ends.
// Lets artificially keep it open until we commit.
await this._waitForTransactionCommitted();
this._setTransactionEnded(false);
} catch {
this._setTransactionEnded(true);
}
});
} catch {
if (!didResolve) {
reject(new Error("Did not resolve"));
}
}
});
}
async execute(sqlStatement, args) {
const tx = this.assertTransactionReady();
const {
rows
} = tx.execute(sqlStatement, args);
if (!rows || rows.length === 0) {
return {
item: () => undefined,
length: 0
};
}
return {
item: idx => rows.item(idx),
length: rows.length
};
}
async commit() {
const tx = this.assertTransactionReady();
tx.commit();
this._txCommitted = true;
for (const resolver of this._transactionCommittedSubscriptions) {
resolver();
}
this._transactionCommittedSubscriptions.clear();
}
waitForTransactionEnded() {
if (this._txEnded) return;
return new Promise((resolve, reject) => {
this._transactionEndedSubscriptions.add({
resolve,
reject
});
});
}
assertTransactionReady() {
if (this._tx === null) throw new Error("Transaction is not ready.");
if (this._txCommitted) throw new Error("Transaction already committed.");
if (this._txEnded) throw new Error("Transaction already ended.");
return this._tx;
}
_waitForTransactionCommitted() {
if (this._txCommitted) return;
return new Promise(resolve => {
this._transactionCommittedSubscriptions.add(resolve);
});
}
_setTransactionEnded() {
let errored = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
this._txEnded = true;
for (const {
resolve,
reject
} of this._transactionEndedSubscriptions) {
if (errored) {
reject();
} else {
resolve();
}
}
this._transactionEndedSubscriptions.clear();
}
}
exports.ReplicacheOPSQLiteTransaction = ReplicacheOPSQLiteTransaction;
//# sourceMappingURL=replicache-op-sqlite-transaction.js.map