You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
1.1 KiB
55 lines
1.1 KiB
import { Transaction } from "./transaction.mjs"; |
|
|
|
export class TransactionManager { |
|
constructor(dbName, adapter) { |
|
this.dbName = dbName; |
|
this.adapter = adapter; |
|
this._queue = []; |
|
this._inTransaction = false; |
|
} |
|
|
|
transaction() { |
|
return new Transaction(this.dbName, this.adapter, |
|
this.enqueue.bind(this)); |
|
} |
|
|
|
enqueue() { |
|
let completeSignal; |
|
let transactionComplete = new Promise((r, _) => { |
|
completeSignal = r; |
|
}); |
|
|
|
let readySignal; |
|
let dbReady = new Promise((r, _) => { |
|
readySignal = () => { |
|
r(completeSignal); |
|
}; |
|
}); |
|
|
|
this._queue.push({readySignal, transactionComplete}); |
|
|
|
this._processQueue(); |
|
return dbReady; |
|
} |
|
|
|
async _processQueue() { |
|
// We're already processing the queue |
|
if (this._inTransaction) { |
|
return; |
|
} |
|
|
|
while (true) { |
|
let item = this._queue.shift(); |
|
if (!item) { |
|
return; |
|
} |
|
|
|
this._inTransaction = true; |
|
|
|
item.readySignal(); |
|
await item.transactionComplete; |
|
|
|
this._inTransaction = false; |
|
} |
|
} |
|
} |