import FDBTransaction from"./FDBTransaction.js";import{ConstraintError,InvalidAccessError,InvalidStateError,NotFoundError,TransactionInactiveError}from"./lib/errors.js";import FakeDOMStringList from"./lib/FakeDOMStringList.js";import FakeEventTarget from"./lib/FakeEventTarget.js";import ObjectStore from"./lib/ObjectStore.js";import{queueTask}from"./lib/scheduling.js";import validateKeyPath from"./lib/validateKeyPath.js";const confirmActiveVersionchangeTransaction=database=>{if(!database._runningVersionchangeTransaction)throw new InvalidStateError;const transactions=database._rawDatabase.transactions.filter((tx=>"versionchange"===tx.mode)),transaction=transactions[transactions.length-1];if(!transaction||"finished"===transaction._state)throw new InvalidStateError;if("active"!==transaction._state)throw new TransactionInactiveError;return transaction},closeConnection=connection=>{connection._closePending=!0;connection._rawDatabase.transactions.every((transaction=>"finished"===transaction._state))?(connection._closed=!0,connection._rawDatabase.connections=connection._rawDatabase.connections.filter((otherConnection=>connection!==otherConnection))):queueTask((()=>{closeConnection(connection)}))};class FDBDatabase extends FakeEventTarget{_closePending=!1;_closed=!1;_runningVersionchangeTransaction=!1;constructor(rawDatabase){super(),this._rawDatabase=rawDatabase,this._rawDatabase.connections.push(this),this.name=rawDatabase.name,this.version=rawDatabase.version,this.objectStoreNames=new FakeDOMStringList(...Array.from(rawDatabase.rawObjectStores.keys()).sort())}createObjectStore(name,options={}){if(void 0===name)throw new TypeError;const transaction=confirmActiveVersionchangeTransaction(this),keyPath=null!==options&&void 0!==options.keyPath?options.keyPath:null,autoIncrement=null!==options&&void 0!==options.autoIncrement&&options.autoIncrement;if(null!==keyPath&&validateKeyPath(keyPath),this._rawDatabase.rawObjectStores.has(name))throw new ConstraintError;if(autoIncrement&&(""===keyPath||Array.isArray(keyPath)))throw new InvalidAccessError;const objectStoreNames=[...this.objectStoreNames];transaction._rollbackLog.push((()=>{const objectStore=this._rawDatabase.rawObjectStores.get(name);objectStore&&(objectStore.deleted=!0),this.objectStoreNames=new FakeDOMStringList(...objectStoreNames),transaction._scope.delete(name),this._rawDatabase.rawObjectStores.delete(name)}));const rawObjectStore=new ObjectStore(this._rawDatabase,name,keyPath,autoIncrement);return this.objectStoreNames._push(name),this.objectStoreNames._sort(),transaction._scope.add(name),this._rawDatabase.rawObjectStores.set(name,rawObjectStore),transaction.objectStoreNames=new FakeDOMStringList(...this.objectStoreNames),transaction.objectStore(name)}deleteObjectStore(name){if(void 0===name)throw new TypeError;const transaction=confirmActiveVersionchangeTransaction(this),store=this._rawDatabase.rawObjectStores.get(name);if(void 0===store)throw new NotFoundError;this.objectStoreNames=new FakeDOMStringList(...Array.from(this.objectStoreNames).filter((objectStoreName=>objectStoreName!==name))),transaction.objectStoreNames=new FakeDOMStringList(...this.objectStoreNames),transaction._rollbackLog.push((()=>{store.deleted=!1,this._rawDatabase.rawObjectStores.set(name,store),this.objectStoreNames._push(name),this.objectStoreNames._sort()})),store.deleted=!0,this._rawDatabase.rawObjectStores.delete(name),transaction._objectStoresCache.delete(name)}transaction(storeNames,mode){if("readonly"!==(mode=void 0!==mode?mode:"readonly")&&"readwrite"!==mode&&"versionchange"!==mode)throw new TypeError("Invalid mode: "+mode);if(this._rawDatabase.transactions.some((transaction=>"active"===transaction._state&&"versionchange"===transaction.mode&&transaction.db===this)))throw new InvalidStateError;if(this._closePending)throw new InvalidStateError;if(Array.isArray(storeNames)||(storeNames=[storeNames]),0===storeNames.length&&"versionchange"!==mode)throw new InvalidAccessError;for(const storeName of storeNames)if(!this.objectStoreNames.contains(storeName))throw new NotFoundError("No objectStore named "+storeName+" in this database");const tx=new FDBTransaction(storeNames,mode,this);return this._rawDatabase.transactions.push(tx),this._rawDatabase.processTransactions(),tx}close(){closeConnection(this)}toString(){return"[object IDBDatabase]"}}export default FDBDatabase;