# Indexed Database API 3.0

## Editor’s Draft, 1 January 1970

This version:
  https://w3c.github.io/IndexedDB/
Latest published version:
  https://www.w3.org/TR/IndexedDB-3/
Previous Versions:
  https://www.w3.org/TR/IndexedDB/
Test Suite:
  https://github.com/web-platform-tests/wpt/tree/master/IndexedDB
Editors:
  Ali Alabbas (Microsoft Corp.)
  Joshua Bell (Google Inc.)

Copyright © 1970 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.

## Abstract

This document defines APIs for a database of records holding simple values and hierarchical objects. Each record consists of a key and some value. Moreover, the database maintains indexes over records it stores. An application developer directly uses an API to locate records either by their key or by using an index. A query language can be layered on this API. An indexed database can be implemented using a persistent B-tree data structure.

## Status of this document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document was published by the Web Applications Working Group as an Editors Draft. This document is intended to become a W3C Recommendation.

This document was published by the Web Applications Working Group as a Working Draft. Feedback and comments on this specification are welcome. Please use GitHub issues Historical discussions can be found in the public-webapps@w3.org archives.

Publication as an Editors Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 March 2019 W3C Process Document.

This is the Third Edition of Indexed Database API. The First Edition became a W3C Recommendation on 8 January 2015. The Second Edition became a W3C Recommendation on 30 January 2018.

## 1. Introduction

User agents need to store large numbers of objects locally in order to satisfy off-line data requirements of Web applications. [WEBSTORAGE] is useful for storing pairs of keys and their corresponding values. However, it does not provide in-order retrieval of keys, efficient searching over values, or storage of duplicate values for a key.

This specification provides a concrete API to perform advanced key-value data management that is at the heart of most sophisticated query processors. It does so by using transactional databases to store keys and their corresponding values (one or more per key), and providing a means of traversing keys in a deterministic order. This is often implemented through the use of persistent B-tree data structures that are considered efficient for insertion and deletion as well as in-order traversal of very large numbers of data records.

In the following example, the API is used to access a "library" database that holds books stored by their "isbn" attribute. Additionally, an index is maintained on the "title" attribute of the objects stored in the object store. This index can be used to look up books by title, and enforces a uniqueness constraint. Another index is maintained on the "author" attribute of the objects, and can be used to look up books by author.

A connection to the database is opened. If the "library" database did not already exist, it is created and an event handler creates the object store and indexes. Finally, the opened connection is saved for use in subsequent examples.

    const request = indexedDB.open("library");
    let db;

    request.onupgradeneeded = function() {
      // The database did not previously exist, so create object stores and indexes.
      const db = request.result;
      const store = db.createObjectStore("books", {keyPath: "isbn"});
      const titleIndex = store.createIndex("by_title", "title", {unique: true});
      const authorIndex = store.createIndex("by_author", "author");

      // Populate with initial data.
      store.put({title: "Quarry Memories", author: "Fred", isbn: 123456});
      store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567});
      store.put({title: "Bedrock Nights", author: "Barney", isbn: 345678});
    };

    request.onsuccess = function() {
      db = request.result;
    };

The following example populates the database using a transaction.

    const tx = db.transaction("books", "readwrite");
    const store = tx.objectStore("books");

    store.put({title: "Quarry Memories", author: "Fred", isbn: 123456});
    store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567});
    store.put({title: "Bedrock Nights", author: "Barney", isbn: 345678});

    tx.oncomplete = function() {
      // All requests have succeeded and the transaction has committed.
    };

The following example looks up a single book in the database by title using an index.

    const tx = db.transaction("books", "readonly");
    const store = tx.objectStore("books");
    const index = store.index("by_title");

    const request = index.get("Bedrock Nights");
    request.onsuccess = function() {
      const matching = request.result;
      if (matching !== undefined) {
        // A match was found.
        report(matching.isbn, matching.title, matching.author);
      } else {
        // No match was found.
        report(null);
      }
    };

The following example looks up all books in the database by author using an index and a cursor.

    const tx = db.transaction("books", "readonly");
    const store = tx.objectStore("books");
    const index = store.index("by_author");

    const request = index.openCursor(IDBKeyRange.only("Fred"));
    request.onsuccess = function() {
      const cursor = request.result;
      if (cursor) {
        // Called for each matching record.
        report(cursor.value.isbn, cursor.value.title, cursor.value.author);
        cursor.continue();
      } else {
        // No more matching records.
        report(null);
      }
    };

The following example shows how errors could be handled when a request fails.

    const tx = db.transaction("books", "readwrite");
    const store = tx.objectStore("books");
    const request = store.put({title: "Water Buffaloes", author: "Slate", isbn: 987654});
    request.onerror = function(event) {
      // The uniqueness constraint of the "by_title" index failed.
      report(request.error);
      // Could call event.preventDefault() to prevent the transaction from aborting.
    };
    tx.onabort = function() {
      // Otherwise the transaction will automatically abort due the failed request.
      report(tx.error);
    };

The database connection can be closed when it is no longer needed.

    db.close();

In the future, the database might have grown to contain other object stores and indexes. The following example shows one way to handle migrating from an older version of the database.

    const request = indexedDB.open("library", 3); // Request version 3.
    let db;

    request.onupgradeneeded = function(event) {
      const db = request.result;
      if (event.oldVersion < 1) {
        // Version 1 is the first version of the database.
        const store = db.createObjectStore("books", {keyPath: "isbn"});
        const titleIndex = store.createIndex("by_title", "title", {unique: true});
        const authorIndex = store.createIndex("by_author", "author");
      }
      if (event.oldVersion < 2) {
        // Version 2 introduces a new index of books by year.
        const bookStore = request.transaction.objectStore("books");
        const yearIndex = bookStore.createIndex("by_year", "year");
      }
      if (event.oldVersion < 3) {
        // Version 3 introduces a new object store for magazines with two indexes.
        const magazines = db.createObjectStore("magazines");
        const publisherIndex = magazines.createIndex("by_publisher", "publisher");
        const frequencyIndex = magazines.createIndex("by_frequency", "frequency");
      }
    };

    request.onsuccess = function() {
      db = request.result; // db.version will be 3.
    };

A single database can be used by multiple clients (pages and workers) simultaneously — transactions ensure they don’t clash while reading and writing. If a new client wants to upgrade the database (via the `upgradeneeded` event), it cannot do so until all other clients close their connection to the current version of the database.

To avoid blocking a new client from upgrading, clients can listen for the `versionchange` event. This fires when another client is wanting to upgrade the database. To allow this to continue, react to the `versionchange` event by doing something that ultimately closes this client’s connection to the database.

One way of doing this is to reload the page:

    db.onversionchange = function() {
      // First, save any unsaved data:
      saveUnsavedData().then(function() {
        // If the document isn’t being actively used, it could be appropriate to reload
        // the page without the user’s interaction.
        if (!document.hasFocus()) {
          location.reload();
          // Reloading will close the database, and also reload with the new JavaScript
          // and database definitions.
        } else {
          // If the document has focus, it can be too disruptive to reload the page.
          // Maybe ask the user to do it manually:
          displayMessage("Please reload this page for the latest version.");
        }
      });
    };

    function saveUnsavedData() {
      // How you do this depends on your app.
    }

    function displayMessage() {
      // Show a non-modal message to the user.
    }

Another way is to call the connection's `close()` method. However, you need to make sure your app is aware of this, as subsequent attempts to access the database will fail.

    db.onversionchange = function() {
      saveUnsavedData().then(function() {
        db.close();
        stopUsingTheDatabase();
      });
    };

    function stopUsingTheDatabase() {
      // Put the app into a state where it no longer uses the database.
    }

The new client (the one attempting the upgrade) can use the `blocked` event to detect if other clients are preventing the upgrade from happening. The `blocked` event fires if other clients still hold a connection to the database after their `versionchange` events have fired.

    const request = indexedDB.open("library", 4); // Request version 4.
    let blockedTimeout;

    request.onblocked = function() {
      // Give the other clients time to save data asynchronously.
      blockedTimeout = setTimeout(function() {
        displayMessage("Upgrade blocked - Please close other tabs displaying this site.");
      }, 1000);
    };

    request.onupgradeneeded = function(event) {
      clearTimeout(blockedTimeout);
      hideMessage();
      // ...
    };

    function hideMessage() {
      // Hide a previously displayed message.
    }

The user will only see the above message if another client fails to disconnect from the database. Ideally the user will never see this.

## 2. Constructs

A name is a string equivalent to a `DOMString`; that is, an arbitrary sequence of 16-bit code units of any length, including the empty string. Names are always compared as opaque sequences of 16-bit code units.

As a result, name comparison is sensitive to variations in case as well as other minor variations such as normalization form, the inclusion or omission of controls, and other variations in Unicode text. [Charmod-Norm]

If an implementation uses a storage mechanism which does not support arbitrary strings, the implementation can use an escaping mechanism or something similar to map the provided name to a string that it can store.

A sorted name list is a list containing names sorted in ascending order by 16-bit code unit.

Details
This matches the Array.prototype.sort on an Array of Strings. This ordering compares the 16-bit code units in each string, producing a highly efficient, consistent, and deterministic sort order. The resulting list will not match any particular alphabet or lexicographical order, particularly for code points represented by a surrogate pair.

### 2.1. Database

Each origin has an associated set of databases. A database has zero or more object stores which hold the data stored in the database.

A database has a name which identifies it within a specific origin. The name is a name, and stays constant for the lifetime of the database.

A database has a version. When a database is first created, its version is 0 (zero).

Each database has one version at a time; a database can’t exist in multiple versions at once. The only way to change the version is using an upgrade transaction.

A database has at most one associated upgrade transaction, which is either null or an upgrade transaction, and is initially null.

#### 2.1.1. Database Connection

Script does not interact with databases directly. Instead, script has indirect access via a connection. A connection object can be used to manipulate the objects of that database. It is also the only way to obtain a transaction for that database.

The act of opening a database creates a connection. There may be multiple connections to a given database at any given time.

A connection can only access databases associated with the origin of the global scope from which the connection is opened.

This is not affected by changes to the `Document`'s `domain`.

A connection has a version, which is set when the connection is created. It remains constant for the lifetime of the connection unless an upgrade is aborted, in which case it is set to the previous version of the database. Once the connection is closed the version does not change.

Each connection has a close pending flag which is initially false.

When a connection is initially created it is in an opened state. The connection can be closed through several means. If the execution context where the connection was created is destroyed (for example due to the user navigating away from that page), the connection is closed. The connection can also be closed explicitly using the steps to close a database connection. When the connection is closed its close pending flag is always set to true if it hasn’t already been.

A connection may be closed by a user agent in exceptional circumstances, for example due to loss of access to the file system, a permission change, or clearing of the origin’s storage. If this occurs the user agent must run close a database connection with the connection and with the forced flag set to true.

A connection has an object store set, which is initialized to the set of object stores in the associated database when the connection is created. The contents of the set will remain constant except when an upgrade transaction is running.

A connection's get the parent algorithm returns null.

A `versionchange` will be fired at an open connection if an attempt is made to upgrade or delete the database. This gives the connection the opportunity to close to allow the upgrade or delete to proceed.

### 2.2. Object Store

An object store is the primary storage mechanism for storing data in a database.

Each database has a set of object stores. The set of object stores can be changed, but only using an upgrade transaction, i.e. in response to an `upgradeneeded` event. When a new database is created it doesn’t contain any object stores.

An object store has a list of records which hold the data stored in the object store. Each record consists of a key and a value. The list is sorted according to key in ascending order. There can never be multiple records in a given object store with the same key.

An object store has a name, which is a name. At any one time, the name is unique within the database to which it belongs.

An object store optionally has a key path. If the object store has a key path it is said to use in-line keys. Otherwise it is said to use out-of-line keys.

An object store optionally has a key generator.

An object store can derive a key for a record from one of three sources:

1. A key generator. A key generator generates a monotonically increasing numbers every time a key is needed.

2. Keys can be derived via a key path.

3. Keys can also be explicitly specified when a value is stored in the object store.

#### 2.2.1. Object Store Handle

Script does not interact with object stores directly. Instead, within a transaction, script has indirect access via an object store handle.

An object store handle has an associated object store and an associated transaction. Multiple handles may be associated with the same object store in different transactions, but there must be only one object store handle associated with a particular object store within a transaction.

An object store handle has an index set, which is initialized to the set of indexes that reference the associated object store when the object store handle is created. The contents of the set will remain constant except when an upgrade transaction is running.

An object store handle has a name, which is initialized to the name of the associated object store when the object store handle is created. The name will remain constant except when an upgrade transaction is running.

### 2.3. Values

Each record is associated with a value. User agents must support any serializable object. This includes simple types such as String primitive values and Date objects as well as Object and Array instances, `File` objects, `Blob` objects, `ImageData` objects, and so on. Record values are stored and retrieved by value rather than by reference; later changes to a value have no effect on the record stored in the database.

Record values are Records output by the StructuredSerializeForStorage operation.

### 2.4. Keys

In order to efficiently retrieve records stored in an indexed database, each record is organized according to its key.

A key has an associated type which is one of: number, date, string, binary, or array.

A key also has an associated value, which will be either: an `unrestricted double` if type is number or date, a `DOMString` if type is string, a byte sequence if type is binary, or a list of other keys if type is array.

An ECMAScript [ECMA-262] value can be converted to a key by following the steps to convert a value to a key.

The following ECMAScript types are valid keys:

- Number primitive values, except NaN. This includes Infinity and -Infinity.

- Date objects, except where the [[DateValue]] internal slot is NaN.

- String primitive values.

- ArrayBuffer objects (or views on buffers such as Uint8Array).

- Array objects, where every item is defined, is itself a valid key, and does not directly or indirectly contain itself. This includes empty arrays. Arrays can contain other arrays.

Attempting to convert other ECMAScript values to a key will fail.

An array key is a key with type array. The subkeys of an array key are the items of the array key's value.

To compare two keys a and b, run these steps:

1. Let ta be the type of a.

2. Let tb be the type of b.

3. If ta does not equal tb, then run these steps:

   1. If ta is array, then return 1.

   2. If tb is array, then return -1.

   3. If ta is binary, then return 1.

   4. If tb is binary, then return -1.

   5. If ta is string, then return 1.

   6. If tb is string, then return -1.

   7. If ta is date, then return 1.

   8. Assert: tb is date.

   9. Return -1.

4. Let va be the value of a.

5. Let vb be the value of b.

6. Switch on ta:

   number
   date

     1. If va is greater than vb, then return 1.

     2. If va is less than vb, then return -1.

     3. Return 0.

   string

     1. If va is code unit less than vb, then return -1.

     2. If vb is code unit less than va, then return 1.

     3. Return 0.

   binary

     1. If va is byte less than vb, then return -1.

     2. If vb is byte less than va, then return 1.

     3. Return 0.

   array

     1. Let length be the lesser of va’s size and vb’s size.

     2. Let i be 0.

     3. While i is less than length, then:

        1. Let c be the result of recursively running compare two keys with va[i] and vb[i].

        2. If c is not 0, return c.

        3. Increase i by 1.

     4. If va’s size is greater than vb’s size, then return 1.

     5. If va’s size is less than vb’s size, then return -1.

     6. Return 0.

The key a is greater than the key b if the result of running compare two keys with a and b is 1.

The key a is less than the key b if the result of running compare two keys with a and b is -1.

The key a is equal to the key b if the result of running compare two keys with a and b is 0.

As a result of the above rules, negative infinity is the lowest possible value for a key. Number keys are less than date keys. Date keys are less than string keys. String keys are less than binary keys. Binary keys are less than array keys. There is no highest possible key value. This is because an array of any candidate highest key followed by another key is even higher.
Members of binary keys are compared as unsigned byte values (in the range 0 to 255 inclusive) rather than signed `byte` values (in the range -128 to 127 inclusive).

### 2.5. Key Path

A key path is a string or list of strings that defines how to extract a key from a value. A valid key path is one of:

- An empty string.

- An identifier, which is a string matching the IdentifierName production from the ECMAScript Language Specification [ECMA-262].

- A string consisting of two or more identifiers separated by periods (U+002E FULL STOP).

- A non-empty list containing only strings conforming to the above requirements.

Spaces are not allowed within a key path.

Key path values can only be accessed from properties explicitly copied by StructuredSerializeForStorage, as well as the following type-specific properties:

Type | Properties
--- | ---
`Blob` | `size`, `type`
`File` | `name`, `lastModified`
Array | `length`
String | `length`

### 2.6. Index

It is sometimes useful to retrieve records in an object store through other means than their key. An index allows looking up records in an object store using properties of the values in the object stores records.

An index is a specialized persistent key-value storage and has a referenced object store. The index has a list of records which hold the data stored in the index. The records in an index are automatically populated whenever records in the referenced object store are inserted, updated or deleted. There can be several indexes referencing the same object store, in which changes to the object store cause all such indexes to get updated.

The values in the index’s records are always values of keys in the index’s referenced object store. The keys are derived from the referenced object store’s values using a key path. If a given record with key X in the object store referenced by the index has the value A, and evaluating the index’s key path on A yields the result Y, then the index will contain a record with key Y and value X.

For example, if an index’s referenced object store contains a record with the key `123` and the value `{ name: "Alice", title: "CEO" }`, and the index’s key path is "`name`" then the index would contain a record with the key "`Alice`" and the value `123`.

Records in an index are said to have a referenced value. This is the value of the record in the index’s referenced object store which has a key equal to the index’s record’s value. So in the example above, the record in the index whose key is Y and value is X has a referenced value of A.

In the preceding example, the record in the index with key "`Alice`" and value `123` would have a referenced value of `{ name: "Alice", title: "CEO" }`.
Each record in an index references one and only one record in the index’s referenced object store. However there can be multiple records in an index which reference the same record in the object store. And there can also be no records in an index which reference a given record in an object store.

The records in an index are always sorted according to the record's key. However unlike object stores, a given index can contain multiple records with the same key. Such records are additionally sorted according to the index's record's value (meaning the key of the record in the referenced object store).

An index has a name, which is a name. At any one time, the name is unique within index’s referenced object store.

An index has a unique flag. When true, the index enforces that no two records in the index has the same key. If a record in the index’s referenced object store is attempted to be inserted or modified such that evaluating the index’s key path on the records new value yields a result which already exists in the index, then the attempted modification to the object store fails.

An index has a multiEntry flag. This flag affects how the index behaves when the result of evaluating the index’s key path yields an array key. If its multiEntry flag is false, then a single record whose key is an array key is added to the index. If its multiEntry flag is true, then one record is added to the index for each of the subkeys.

#### 2.6.1. Index Handle

Script does not interact with indexes directly. Instead, within a transaction, script has indirect access via an index handle.

An index handle has an associated index and an associated object store handle. The transaction of an index handle is the transaction of its associated object store handle. Multiple handles may be associated with the same index in different transactions, but there must be only one index handle associated with a particular index within a transaction.

An index handle has a name, which is initialized to the name of the associated index when the index handle is created. The name will remain constant except when an upgrade transaction is running.

### 2.7. Transactions

A Transaction is used to interact with the data in a database. Whenever data is read or written to the database it is done by using a transaction.

Transactions offer some protection from application and system failures. A transaction may be used to store multiple data records or to conditionally modify certain data records. A transaction represents an atomic and durable set of data access and data mutation operations.

All transactions are created through a connection, which is the transaction’s connection.

A transaction has a scope that determines the object stores with which the transaction may interact. A transaction’s scope remains fixed for the lifetime of that transaction.

A transaction has a mode that determines which types of interactions can be performed upon that transaction. The mode is set when the transaction is created and remains fixed for the life of the transaction. A transaction's mode is one of the following:

`"readonly"`

  The transaction is only allowed to read data. No modifications can be done by this type of transaction. This has the advantage that several read-only transactions can run at the same time even if their scopes are overlapping, i.e. if they are using the same object stores. This type of transaction can be created any time once a database has been opened.

`"readwrite"`

  The transaction is allowed to read, modify and delete data from existing object stores. However object stores and indexes can’t be added or removed. Multiple `"readwrite"` transactions can’t run at the same time if their scopes are overlapping since that would mean that they can modify each other’s data in the middle of the transaction. This type of transaction can be created any time once a database has been opened.

`"versionchange"`

  The transaction is allowed to read, modify and delete data from existing object stores, and can also create and remove object stores and indexes. It is the only type of transaction that can do so. This type of transaction can’t be manually created, but instead is created automatically when an `upgradeneeded` event is fired.

A transaction optionally has a cleanup event loop which is an event loop.

A transaction has a request list of pending requests which have been made against the transaction.

A transaction has a error which is set if the transaction is aborted.

A transaction's get the parent algorithm returns the transaction’s connection.

A read-only transaction is a transaction with mode `"readonly"`.

A read/write transaction is a transaction with mode `"readwrite"`.

#### 2.7.1. Transaction Lifecycle

A transaction has a state, which is one of the following:

active

  A transaction is in this state when it is first created, and during dispatch of an event from a request associated with the transaction.

  New requests can be made against the transaction when it is in this state.

inactive

  A transaction is in this state after control returns to the event loop after its creation, and when events are not being dispatched.

  No requests can be made against the transaction when it is in this state.

committing

  Once all requests associated with a transaction have completed, the transaction will enter this state as it attempts to commit.

  No requests can be made against the transaction when it is in this state.

finished

  Once a transaction has committed or aborted, it enters this state.

  No requests can be made against the transaction when it is in this state.

Transactions are expected to be short lived. This is encouraged by the automatic committing functionality described below.

Authors can still cause transactions to run for a long time; however, this usage pattern is not advised as it can lead to a poor user experience.

The lifetime of a transaction is as follows:

1. A transaction is created with a scope and a mode. When a transaction is created its state is initially active.

2. When an implementation is able to enforce the constraints for the transaction’s scope and mode, defined below, the implementation must queue a task to start the transaction asynchronously.

   Once the transaction has been started the implementation can begin executing the requests placed against the transaction. Requests must be executed in the order in which they were made against the transaction. Likewise, their results must be returned in the order the requests were placed against a specific transaction. There is no guarantee about the order that results from requests in different transactions are returned.

   Transaction modes ensure that two requests placed against different transactions can execute in any order without affecting what resulting data is stored in the database.

3. When each request associated with a transaction is processed, a `success` or `error` event will be fired. While the event is being dispatched, the transaction state is set to active, allowing additional requests to be made against the transaction. Once the event dispatch is complete, the transaction’s state is set to inactive again.

4. A transaction can be aborted at any time before it is finished, even if the transaction isn’t currently active or hasn’t yet started.

   An explicit call to `abort()` will initiate an abort. An abort will also be initiated following a failed request that is not handled by script.

   When a transaction is aborted the implementation must undo (roll back) any changes that were made to the database during that transaction. This includes both changes to the contents of object stores as well as additions and removals of object stores and indexes.

5. The implementation must attempt to commit a transaction when all requests placed against the transaction have completed and their returned results handled, no new requests have been placed against the transaction, and the transaction has not been aborted

   An explicit call to `commit()` will initiate a commit without waiting for request results to be handled by script.

   When committing, the transaction state is set to committing. The implementation must atomically write any changes to the database made by requests placed against the transaction. That is, either all of the changes must be written, or if an error occurs, such as a disk write error, the implementation must not write any of the changes to the database, and the steps to abort a transaction will be followed.

6. When a transaction is committed or aborted, its state is set to finished.

The implementation must allow requests to be placed against the transaction whenever it is active. This is the case even if the transaction has not yet been started. Until the transaction is started the implementation must not execute these requests; however, the implementation must keep track of the requests and their order.

To cleanup Indexed Database transactions, run the following steps. They will return true if any transactions were cleaned up, or false otherwise.

1. If there are no transactions with cleanup event loop matching the current event loop, return false.

2. For each transaction transaction with cleanup event loop matching the current event loop:

   1. Set transaction’s state to inactive.

   2. Clear transaction’s cleanup event loop.

3. Return true.

This behavior is invoked by [HTML]. It ensures that transactions created by a script call to `transaction()` are deactivated once the task that invoked the script has completed. The steps are run at most once for each transaction.

#### 2.7.2. Transaction Scheduling

An event with type `complete` is fired at a transaction that has successfully committed.

An event with type `abort` is fired at a transaction that has aborted.

The following constraints define when a transaction can be started:

- Any number of read-only transactions are allowed to run concurrently, even if the transaction’s scope overlap and include the same object stores. As long as a read-only transaction is running, the data that the implementation returns through requests created with that transaction must remain constant. That is, two requests to read the same piece of data must yield the same result both for the case when data is found and the result is that data, and for the case when data is not found and a lack of data is indicated.

  There are a number of ways that an implementation can ensure this. The implementation could prevent any read/write transaction, whose scope overlaps the scope of the read-only transaction, from starting until the read-only transaction finishes. Or the implementation could allow the read-only transaction to see a snapshot of the contents of the object stores which is taken when the read-only transaction started.

- Similarly, implementations must ensure that a read/write transaction is only affected by changes to object stores that are made using the transaction itself. For example, the implementation must ensure that another transaction does not modify the contents of object stores in the read/write transaction’s scope. The implementation must also ensure that if the read/write transaction completes successfully, the changes written to object stores using the transaction can be committed to the database without merge conflicts. An implementation must not abort a transaction due to merge conflicts.

- If multiple read/write transactions are attempting to access the same object store (i.e. if they have overlapping scope), the transaction that was created first must be the transaction which gets access to the object store first. Due to the requirements in the previous paragraph, this also means that it is the only transaction which has access to the object store until the transaction is finished.

- Any transaction created after a read/write transaction must see the changes written by the read/write transaction. So if a read/write transaction, A, is created, and later another transaction B, is created, and the two transactions have overlapping scopes, then B must see any changes made to any object stores that are part of that overlapping scope. Due to the requirements in the previous paragraph, this also means that the B transaction does not have access to any object stores in that overlapping scope until the A transaction is finished.

  Generally speaking, the above requirements mean that any transaction which has an overlapping scope with a read/write transaction and which was created after that read/write transaction, can’t run in parallel with that read/write transaction.

- User agents must ensure a reasonable level of fairness across transactions to prevent starvation. For example, if multiple read-only transactions are started one after another the implementation must not indefinitely prevent a pending read/write transaction from starting.

#### 2.7.3. Upgrade Transactions

An upgrade transaction is a transaction with mode `"versionchange"`.

An upgrade transaction is automatically created when running the steps to run an upgrade transaction after a connection is opened to a database, if a version greater than the current version is specified. This transaction will be active inside the `upgradeneeded` event handler.

An upgrade transaction enables the creation, renaming, and deletion of object stores and indexes in a database.

An upgrade transaction is exclusive. The steps to open a database ensure that only one connection to the database is open when an upgrade transaction is running. The `upgradeneeded` event isn’t fired, and thus the upgrade transaction isn’t started, until all other connections to the same database are closed. This ensures that all previous transactions are finished. As long as an upgrade transaction is running, attempts to open more connections to the same database are delayed, and any attempts to use the same connection to start additional transactions by calling `transaction()` will throw an exception. Thus upgrade transactions not only ensure that no other transactions are running concurrently, but also ensure that no new transactions are queued against the same database as long as the transaction is running.

This ensures that once an upgrade transaction is complete, the set of object stores and indexes in a database remain constant for the lifetime of all subsequent connections and transactions.

### 2.8. Requests

Each asynchronous operation on a database is done using a request. Every request represents one operation.

A request has a processed flag which is initially false. This flag is set to true when the operation associated with the request has been executed.

A request is said to be processed when its processed flag is true.

A request has a done flag which is initially false. This flag is set to true when the result of the operation associated with the request is available.

A request has a source object.

A request has a result and an error, neither of which are accessible until its done flag is true.

A request has a transaction which is initially null. This will be set when a request is placed against a transaction using the steps to asynchronously execute a request.

When a request is made, a new request is returned with its done flag set to false. If a request completes successfully, its done flag is set to true, its result is set to the result of the request, and an event with type `success` is fired at the request.

If an error occurs while performing the operation, the request’s done flag is set to true, the request’s error is set to the error, and an event with type `error` is fired at the request.

A request's get the parent algorithm returns the request’s transaction.

Requests are not typically re-used, but there are exceptions. When a cursor is iterated, the success of the iteration is reported on the same request object used to open the cursor. And when an upgrade transaction is necessary, the same open request is used for both the `upgradeneeded` event and final result of the open operation itself. In some cases, the request’s done flag will be set to false, then set to true again, and the result can change or error could be set instead.

#### 2.8.1. Open Requests

An open request is a special type of request used when opening a connection or deleting a database. In addition to `success` and `error` events, `blocked` and `upgradeneeded` events may be fired at an open request to indicate progress.

The source of an open request is always null.

The transaction of an open request is null unless an `upgradeneeded` event has been fired.

An open request's get the parent algorithm returns null.

Open requests are processed in a connection queue. The queue contains all open requests associated with an origin and a name. Requests added to the connection queue processed in order and each request must run to completion before the next request is processed. An open request may be blocked on other connections, requiring those connections to close before the request can complete and allow further requests to be processed.

A connection queue is not a task queue associated with an event loop, as the requests are processed outside any specific browsing context. The delivery of events to completed open request still goes through a task queue associated with the event loop of the context where the request was made.

### 2.9. Key Range

Records can be retrieved from object stores and indexes using either keys or key ranges. A key range is a continuous interval over some data type used for keys.

A key range has an associated lower bound (null or a key).

A key range has an associated upper bound (null or a key).

A key range has an associated lower open flag. Unless otherwise stated it is false.

A key range has an associated upper open flag. Unless otherwise stated it is false.

A key range may have a lower bound equal to its upper bound. A key range must not have a lower bound greater than its upper bound.

A key range containing only key has both lower bound and upper bound equal to key.

A key is in a key range range if both of the following conditions are fulfilled:

- The range’s lower bound is null, or it is less than key, or it is both equal to key and the range’s lower open flag is false.

- The range’s upper bound is null, or it is greater than key, or it is both equal to key and the range’s upper open flag is false.

- If a key range's lower open flag is false, the lower bound key of the key range is included in the range itself.

- If a key range's lower open flag is true, the lower bound key of the key range is excluded from the range itself.

- If a key range's upper open flag is false, the upper bound key of the key range is included in the range itself.

- If a key range's upper open flag is true, the upper bound key of the key range is excluded from the range itself.

An unbounded key range is a key range that has both lower bound and upper bound equal to null. All keys are in an unbounded key range.

To convert a value to a key range with value and optional null disallowed flag, run these steps:

1. If value is a key range, return value.

2. If value is undefined or is null, then throw a "`DataError`" `DOMException` if null disallowed flag is true, or return an unbounded key range otherwise.

3. Let key be the result of running convert a value to a key with value. Rethrow any exceptions.

4. If key is invalid, throw a "`DataError`" `DOMException`.

5. Return a key range containing only key.

### 2.10. Cursor

A cursor is used to iterate over a range of records in an index or an object store in a specific direction.

A cursor has a transaction, the transaction that was active when the cursor was created.

A cursor has a range of records in either an index or an object store.

A cursor has a source that indicates which index or an object store is associated with the records over which the cursor is iterating.

A cursor has a direction that determines whether it moves in monotonically increasing or decreasing order of the record keys when iterated, and if it skips duplicated values when iterating indexes. The direction of a cursor also determines if the cursor initial position is at the start of its source or at its end. A cursor’s direction is one of the following:

`"next"`

  This direction causes the cursor to be opened at the start of the source. When iterated, the cursor should yield all records, including duplicates, in monotonically increasing order of keys.

`"nextunique"`

  This direction causes the cursor to be opened at the start of the source. When iterated, the cursor should not yield records with the same key, but otherwise yield all records, in monotonically increasing order of keys. For every key with duplicate values, only the first record is yielded. When the source is an object store or an index with its unique flag set to true, this direction has exactly the same behavior as `"next"`.

`"prev"`

  This direction causes the cursor to be opened at the end of the source. When iterated, the cursor should yield all records, including duplicates, in monotonically decreasing order of keys.

`"prevunique"`

  This direction causes the cursor to be opened at the end of the source. When iterated, the cursor should not yield records with the same key, but otherwise yield all records, in monotonically decreasing order of keys. For every key with duplicate values, only the first record is yielded. When the source is an object store or an index with its unique flag set to true, this direction has exactly the same behavior as `"prev"`.

A cursor has a position within its range. It is possible for the list of records which the cursor is iterating over to change before the full range of the cursor has been iterated. In order to handle this, cursors maintain their position not as an index, but rather as a key of the previously returned record. For a forward iterating cursor, the next time the cursor is asked to iterate to the next record it returns the record with the lowest key greater than the one previously returned. For a backwards iterating cursor, the situation is opposite and it returns the record with the highest key less than the one previously returned.

For cursors iterating indexes the situation is a little bit more complicated since multiple records can have the same key and are therefore also sorted by value. When iterating indexes the cursor also has an object store position, which indicates the value of the previously found record in the index. Both position and the object store position are used when finding the next appropriate record.

A cursor has a key and a value which represent the key and the value of the last iterated record.

A cursor has a got value flag. When this flag is false, the cursor is either in the process of loading the next value or it has reached the end of its range. When it is true, it indicates that the cursor is currently holding a value and that it is ready to iterate to the next one.

If the source of a cursor is an object store, the effective object store of the cursor is that object store and the effective key of the cursor is the cursor’s position. If the source of a cursor is an index, the effective object store of the cursor is that index’s referenced object store and the effective key is the cursor’s object store position.

A cursor has a request, which is the request used to open the cursor.

A cursor also has a key only flag, that indicates whether the cursor’s value is exposed via the API.

### 2.11. Key Generators

When a object store is created it can be specified to use a key generator. A key generator is used to generate keys for records inserted into an object store if not otherwise specified.

A key generator has a current number. The current number is always a positive integer less than or equal to 253 (9007199254740992) + 1. The initial value of a key generator's current number is 1, set when the associated object store is created. The current number is incremented as keys are generated, and may be updated to a specific value by using explicit keys.

Every object store that uses key generators uses a separate generator. That is, interacting with one object store never affects the key generator of any other object store.

Modifying a key generator’s current number is considered part of a database operation. This means that if the operation fails and the operation is reverted, the current number is reverted to the value it had before the operation started. This applies both to modifications that happen due to the current number getting increased by 1 when the key generator is used, and to modifications that happen due to a record being stored with a key value specified in the call to store the record.

Likewise, if a transaction is aborted, the current number of the key generator for each object store in the transaction’s scope is reverted to the value it had before the transaction was started.

The current number for a key generator never decreases, other than as a result of database operations being reverted. Deleting a record from an object store never affects the object store’s key generator. Even clearing all records from an object store, for example using the `clear()` method, does not affect the current number of the object store’s key generator.

When a record is stored and a key is not specified in the call to store the record, a key is generated.

To generate a key for an object store store, run these steps:

1. Let generator be store’s key generator.

2. Let key be generator’s current number.

3. If key is greater than 253 (9007199254740992), then return failure.

4. Increase generator’s current number by 1.

5. Return key.

When a record is stored and a key is specified in the call to store the record, the associated key generator may be updated.

To possibly update the key generator for an object store store with key, run these steps:

1. If the type of key is not number, abort these steps.

2. Let value be the value of key.

3. Let value be the minimum of value and 253 (9007199254740992).

4. Let value be the largest integer not greater than value.

5. Let generator be store’s key generator.

6. If value is greater than or equal to generator’s current number, then set generator’s current number to value + 1.

A key can be specified both for object stores which use in-line keys, by setting the property on the stored value which the object store’s key path points to, and for object stores which use out-of-line keys, by passing a key argument to the call to store the record.

Only specified keys of type number can affect the current number of the key generator. Keys of type date, array (regardless of the other keys they contain), binary, or string (regardless of whether they could be parsed as numbers) have no effect on the current number of the key generator. Keys of type number with value less than 1 do not affect the current number since they are always lower than the current number.

When the current number of a key generator reaches above the value 253 (9007199254740992) any subsequent attempts to use the key generator to generate a new key will result in a "`ConstraintError`" `DOMException`. It is still possible to insert records into the object store by specifying an explicit key, however the only way to use a key generator again for such records is to delete the object store and create a new one.

This limit arises because integers greater than 9007199254740992 cannot be uniquely represented as ECMAScript Numbers. As an example, `9007199254740992 + 1 === 9007199254740992` in ECMAScript.

As long as key generators are used in a normal fashion this limit will not be a problem. If you generate a new key 1000 times per second day and night, you won’t run into this limit for over 285000 years.

A practical result of this is that the first key generated for an object store is always 1 (unless a higher numeric key is inserted first) and the key generated for an object store is always a positive integer higher than the highest numeric key in the store. The same key is never generated twice for the same object store unless a transaction is rolled back.

Each object store gets its own key generator:

    store1 = db.createObjectStore("store1", { autoIncrement: true });
    store1.put("a"); // Will get key 1
    store2 = db.createObjectStore("store2", { autoIncrement: true });
    store2.put("a"); // Will get key 1
    store1.put("b"); // Will get key 2
    store2.put("b"); // Will get key 2

If an insertion fails due to constraint violations or IO error, the key generator is not updated.

    transaction.onerror = function(e) { e.preventDefault() };
    store = db.createObjectStore("store1", { autoIncrement: true });
    index = store.createIndex("index1", "ix", { unique: true });
    store.put({ ix: "a"}); // Will get key 1
    store.put({ ix: "a"}); // Will fail
    store.put({ ix: "b"}); // Will get key 2

Removing items from an objectStore never affects the key generator. Including when `clear()` is called.

    store = db.createObjectStore("store1", { autoIncrement: true });
    store.put("a"); // Will get key 1
    store.delete(1);
    store.put("b"); // Will get key 2
    store.clear();
    store.put("c"); // Will get key 3
    store.delete(IDBKeyRange.lowerBound(0));
    store.put("d"); // Will get key 4

Inserting an item with an explicit key affects the key generator if, and only if, the key is numeric and higher than the last generated key.

    store = db.createObjectStore("store1", { autoIncrement: true });
    store.put("a"); // Will get key 1
    store.put("b", 3); // Will use key 3
    store.put("c"); // Will get key 4
    store.put("d", -10); // Will use key -10
    store.put("e"); // Will get key 5
    store.put("f", 6.00001); // Will use key 6.0001
    store.put("g"); // Will get key 7
    store.put("f", 8.9999); // Will use key 8.9999
    store.put("g"); // Will get key 9
    store.put("h", "foo"); // Will use key "foo"
    store.put("i"); // Will get key 10
    store.put("j", [1000]); // Will use key [1000]
    store.put("k"); // Will get key 11
    // All of these would behave the same if the objectStore used a
    // keyPath and the explicit key was passed inline in the object

Aborting a transaction rolls back any increases to the key generator which happened during the transaction. This is to make all rollbacks consistent since rollbacks that happen due to crash never has a chance to commit the increased key generator value.

    db.createObjectStore("store", { autoIncrement: true });
    trans1 = db.transaction(["store"], "readwrite");
    store_t1 = trans1.objectStore("store");
    store_t1.put("a"); // Will get key 1
    store_t1.put("b"); // Will get key 2
    trans1.abort();
    trans2 = db.transaction(["store"], "readwrite");
    store_t2 = trans2.objectStore("store");
    store_t2.put("c"); // Will get key 1
    store_t2.put("d"); // Will get key 2

The following examples illustrate the different behaviors when trying to use in-line keys and key generators to save an object to an object store.

If the following conditions are true:

- The object store has a key generator.

- There is no in-line value for the key path property.

Then the value provided by the key generator is used to populate the key value. In the example below the key path for the object store is "`foo.bar`". The actual object has no value for the `bar` property, `{ foo: {} }`. When the object is saved in the object store the `bar` property is assigned a value of 1 because that is the next key generated by the key generator.

    const store = db.createObjectStore("store", { keyPath: "foo.bar",
                                                  autoIncrement: true });
    store.put({ foo: {} }).onsuccess = function(e) {
      const key = e.target.result;
      console.assert(key === 1);
    };

If the following conditions are true:

- The object store has a key generator.

- There is a value for the key path property.

Then the value associated with the key path property is used. The auto-generated key is not used. In the example below the key path for the object store is "`foo.bar`". The actual object has a value of 10 for the `bar` property, `{ foo: { bar: 10} }`. When the object is saved in the object store the `bar` property keeps its value of 10, because that is the key value.

    const store = db.createObjectStore("store", { keyPath: "foo.bar",
                                                  autoIncrement: true });
    store.put({ foo: { bar: 10 } }).onsuccess = function(e) {
      const key = e.target.result;
      console.assert(key === 10);
    };

The following example illustrates the scenario when the specified in-line key is defined through a key path but there is no property matching it. The value provided by the key generator is then used to populate the key value and the system is responsible for creating as many properties as it requires to suffice the property dependencies on the hierarchy chain. In the example below the key path for the object store is "`foo.bar.baz`". The actual object has no value for the `foo` property, `{ zip: {} }`. When the object is saved in the object store the `foo`, `bar`, and `baz` properties are created each as a child of the other until a value for `foo.bar.baz` can be assigned. The value for `foo.bar.baz` is the next key generated by the object store.

    const store = db.createObjectStore("store", { keyPath: "foo.bar.baz",
                                                  autoIncrement: true });
    store.put({ zip: {} }).onsuccess = function(e) {
      const key = e.target.result;
      console.assert(key === 1);
      store.get(key).onsuccess = function(e) {
        const value = e.target.result;
        // value will be: { zip: {}, foo: { bar: { baz: 1 } } }
        console.assert(value.foo.bar.baz === 1);
      };
    };

Attempting to store a property on a primitive value will fail and throw an error. In the first example below the key path for the object store is "`foo`". The actual object is a primitive with the value, `4`. Trying to define a property on that primitive value fails. The same is true for arrays. Properties are not allowed on an array. In the second example below, the actual object is an array, `[10]`. Trying to define a property on the array fails.

    const store = db.createObjectStore("store", { keyPath: "foo", autoIncrement: true });

    // The key generation will attempt to create and store the key path
    // property on this primitive.
    store.put(4); // will throw DataError

    // The key generation will attempt to create and store the key path
    // property on this array.
    store.put([10]); // will throw DataError

## 3. Exceptions

Each of the exceptions used in this document is a `DOMException` with a specific type. The exception types and properties such as legacy code value are defined in [WEBIDL].

The table below lists the `DOMException`s used in this document along with a description of the exception type’s usage.

Type | Description
--- | ---
`AbortError` | A request was aborted.
`ConstraintError` | A mutation operation in the transaction failed because a constraint was not satisfied.
`DataCloneError` | The data being stored could not be cloned by the internal structured cloning algorithm.
`DataError` | Data provided to an operation does not meet requirements.
`InvalidAccessError` | An invalid operation was performed on an object.
`InvalidStateError` | An operation was called on an object on which it is not allowed or at a time when it is not allowed, or if a request is made on a source object that has been deleted or removed.
`NotFoundError` | The operation failed because the requested database object could not be found.
`QuotaExceededError` | The operation failed because there was not enough remaining storage space, or the storage quota was reached and the user declined to give more space to the database.
`SyntaxError` | The keyPath argument contains an invalid key path.
`ReadOnlyError` | The mutating operation was attempted in a read-only transaction.
`TransactionInactiveError` | A request was placed against a transaction which is currently not active, or which is finished.
`UnknownError` | The operation failed for reasons unrelated to the database itself and not covered by any other errors.
`VersionError` | An attempt was made to open a database using a lower version than the existing version.

Given that multiple Indexed DB operations can throw the same type of error, and that even a single operation can throw the same type of error for multiple reasons, implementations are encouraged to provide more specific messages to enable developers to identify the cause of errors.

## 4. API

The API methods return without blocking the calling thread. All asynchronous operations immediately return an `IDBRequest` instance. This object does not initially contain any information about the result of the operation. Once information becomes available, an event is fired on the request and the information becomes available through the properties of the `IDBRequest` instance.

The task source for these tasks is the database access task source.

### 4.1. The `IDBRequest` interface

The `IDBRequest` interface provides the means to access results of asynchronous requests to databases and database objects using event handler IDL attributes [HTML].

Every method for making asynchronous requests returns an `IDBRequest` object that communicates back to the requesting application through events. This design means that any number of requests can be active on any database at a time.

In the following example, we open a database asynchronously. Various event handlers are registered for responding to various situations.

    const request = indexedDB.open('AddressBook', 15);
    request.onsuccess = function(evt) {...};
    request.onerror = function(evt) {...};

    [Exposed=(Window,Worker)]
    interface IDBRequest : EventTarget {
      readonly attribute any result;
      readonly attribute DOMException? error;
      readonly attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;
      readonly attribute IDBTransaction? transaction;
      readonly attribute IDBRequestReadyState readyState;

      // Event handlers:
      attribute EventHandler onsuccess;
      attribute EventHandler onerror;
    };

    enum IDBRequestReadyState {
      "pending",
      "done"
    };

request . `result`

  When a request is completed, returns the result, or `undefined` if the request failed. Throws a "`InvalidStateError`" `DOMException` if the request is still pending.

request . `error`

  When a request is completed, returns the error (a `DOMException`), or null if the request succeeded. Throws a "`InvalidStateError`" `DOMException` if the request is still pending.

request . `source`

  Returns the `IDBObjectStore`, `IDBIndex`, or `IDBCursor` the request was made against, or null if it was an open request.

request . `transaction`

  Returns the `IDBTransaction` the request was made within. If this as an open request, then it returns an upgrade transaction while it is running, or null otherwise.

request . `readyState`

  Returns `"pending"` until a request is complete, then returns `"done"`.

The `result` attribute’s getter must throw an "`InvalidStateError`" `DOMException` if this's done flag is false. Otherwise, the attribute’s getter must return this's result, or undefined if the request resulted in an error.

The `error` attribute’s getter must throw an "`InvalidStateError`" `DOMException` if this's done flag is false. Otherwise, the attribute’s getter must return this's error, or null if no error occurred.

The `source` attribute’s getter must return this's source, or null if no source is set.

The `transaction` attribute’s getter must return this's transaction. This property can be null for certain requests, such as for requests returned from `open()`.

The `readyState` attribute’s getter must return `"pending"` if this's done flag is false, and `"done"` otherwise.

The `onsuccess` attribute is the event handler for the `success` event.

The `onerror` attribute is the event handler for the `error` event.

Methods on `IDBDatabase` that return a open request use an extended interface to allow listening to the `blocked` and `upgradeneeded` events.

    [Exposed=(Window,Worker)]
    interface IDBOpenDBRequest : IDBRequest {
      // Event handlers:
      attribute EventHandler onblocked;
      attribute EventHandler onupgradeneeded;
    };

The `onblocked` attribute is the event handler for the `blocked` event.

The `onupgradeneeded` attribute is the event handler for the `upgradeneeded` event.

### 4.2. Event interfaces

This specification fires events with the following custom interfaces:

    [Exposed=(Window,Worker)]
    interface IDBVersionChangeEvent : Event {
      constructor(DOMString type, optional IDBVersionChangeEventInit eventInitDict = {});
      readonly attribute unsigned long long oldVersion;
      readonly attribute unsigned long long? newVersion;
    };

    dictionary IDBVersionChangeEventInit : EventInit {
      unsigned long long oldVersion = 0;
      unsigned long long? newVersion = null;
    };

The `oldVersion` attribute getter returns the previous version of the database.

The `newVersion` attribute getter returns the new version of the database, or null if the database is being deleted. See the steps to run an upgrade transaction.

Events are constructed as defined in DOM §2.5 Constructing events.

To fire a version change event named e at target given oldVersion and newVersion, run these steps:

1. Let event be the result of creating an event using `IDBVersionChangeEvent`.

2. Set event’s `type` attribute to e.

3. Set event’s `bubbles` and `cancelable` attributes to false.

4. Set event’s `oldVersion` attribute to oldVersion.

5. Set event’s `newVersion` attribute to newVersion.

6. Let legacyOutputDidListenersThrowFlag be false.

7. Dispatch event at target with legacyOutputDidListenersThrowFlag.

8. Return legacyOutputDidListenersThrowFlag.

   The return value of this algorithm is not always used.

### 4.3. The `IDBFactory` interface

Database objects are accessed through methods on the `IDBFactory` interface. A single object implementing this interface is present in the global scope of environments that support Indexed DB operations.

    partial interface mixin WindowOrWorkerGlobalScope {
      [SameObject] readonly attribute IDBFactory indexedDB;
    };

The `indexedDB` attribute provides applications a mechanism for accessing capabilities of indexed databases.

    [Exposed=(Window,Worker)]
    interface IDBFactory {
      [NewObject] IDBOpenDBRequest open(DOMString name,
                                        optional [EnforceRange] unsigned long long version);
      [NewObject] IDBOpenDBRequest deleteDatabase(DOMString name);

      Promise<sequence<IDBDatabaseInfo>> databases();

      short cmp(any first, any second);
    };

    dictionary IDBDatabaseInfo {
      DOMString name;
      unsigned long long version;
    };

request = indexedDB . `open`(name)

  Attempts to open a connection to the named database with the current version, or 1 if it does not already exist. If the request is successful request’s `result` will be the connection.

request = indexedDB . `open`(name, version)

  Attempts to open a connection to the named database with the specified version. If the database already exists with a lower version and there are open connections that don’t close in response to a `versionchange` event, the request will be blocked until they all close, then an upgrade will occur. If the database already exists with a higher version the request will fail. If the request is successful request’s `result` will be the connection.

request = indexedDB . `deleteDatabase`(name)

  Attempts to delete the named database. If the database already exists and there are open connections that don’t close in response to a `versionchange` event, the request will be blocked until they all close. If the request is successful request’s `result` will be null.

result = await indexedDB . `databases`()

  Returns a promise which resolves to a list of objects giving a snapshot of the names and versions of databases within the origin.

  This API is intended for web applications to introspect the use of databases, for example to clean up from earlier versions of a site’s code. Note that the result is a snapshot; there are no guarantees about the sequencing of the collection of the data or the delivery of the response with respect to requests to create, upgrade, or delete databases by this context or others.

The `open(name, version)` method, when invoked, must run these steps:

1. If version is 0 (zero), throw a TypeError.

2. Let origin be the origin of the global scope used to access this.

3. If origin is an opaque origin, throw a "`SecurityError`" `DOMException` and abort these steps.

4. Let request be a new open request.

5. Run these steps in parallel:

   1. Let result be the result of running open a database, with origin, name, version if given and undefined otherwise, and request.

      What happens if version is not given?
      If version is not given and a database with that name already exists, a connection will be opened without changing the version. If version is not given and no database with that name exists, a new database will be created with version equal to 1.

   2. Queue a task to run these steps:

      1. If result is an error, then:

         1. Set request’s result to undefined.

         2. Set request’s error to result.

         3. Set request’s done flag to true.

         4. Fire an event named `error` at request with its `bubbles` and `cancelable` attributes initialized to true.

      2. Otherwise:

         1. Set request’s result to result.

         2. Set request’s done flag to true.

         3. Fire an event named `success` at request.

         If the steps above resulted in an upgrade transaction being run, these steps will run after that transaction finishes. This ensures that in the case where another version upgrade is about to happen, the success event is fired on the connection first so that the script gets a chance to register a listener for the `versionchange` event.
         Why aren’t the steps to fire a success event or fire an error event used?
         There is no transaction associated with the request (at this point), so those steps — which activate an associated transaction before dispatch and deactivate the transaction after dispatch — do not apply.

6. Return a new `IDBOpenDBRequest` object for request.

The `deleteDatabase(name)` method, when invoked, must run these steps:

1. Let origin be the origin of the global scope used to access this.

2. If origin is an opaque origin, throw a "`SecurityError`" `DOMException` and abort these steps.

3. Let request be a new open request.

4. Run these steps in parallel:

   1. Let result be the result of running delete a database, with origin, name, and request.

   2. Set request’s processed flag to true.

   3. Queue a task to run these steps:

      1. If result is an error, set request’s error to result, set request’s done flag to true, and fire an event named `error` at request with its `bubbles` and `cancelable` attributes initialized to true.

      2. Otherwise, set request’s result to undefined, set request’s done flag to true, and fire a version change event named `success` at request with result and null.

         Why aren’t the steps to fire a success event or fire an error event used?
         There is no transaction associated with the request, so those steps — which activate an associated transaction before dispatch and deactivate the transaction after dispatch — do not apply.

         Also, the `success` event here is a `IDBVersionChangeEvent` which includes the `oldVersion` and `newVersion` details.

5. Return a new `IDBOpenDBRequest` object for request.

The `databases()` method, when invoked, must run these steps:

1. Let origin be the origin of the global scope used to access this.

2. If origin is an opaque origin, then return a promise rejected with a "`SecurityError`" `DOMException`.

3. Let p be a new promise.

4. Run these steps in parallel:

   1. Let databases be the set of databases in origin. If this cannot be determined for any reason, then reject p with an appropriate error (e.g. an "`UnknownError`" `DOMException`) and terminate these steps.

   2. Let result be a new list.

   3. For each db of databases:

      1. Let info be a new `IDBDatabaseInfo` dictionary.

      2. Set info’s `name` dictionary member to db’s name.

      3. Set info’s `version` dictionary member to db’s version.

      4. Append info to result.

   4. Resolve p with result.

5. Return p.

🚧 The `databases()` method is new in this edition. 🚧

result = indexedDB . `cmp`(key1, key2)

  Compares two values as keys. Returns -1 if key1 precedes key2, 1 if key2 precedes key1, and 0 if the keys are equal.

  Throws a "`DataError`" `DOMException` if either input is not a valid key.

The `cmp(first, second)` method, when invoked, must run these steps:

1. Let a be the result of running convert a value to a key with first. Rethrow any exceptions.

2. If a is invalid, throw a "`DataError`" `DOMException`.

3. Let b be the result of running convert a value to a key with second. Rethrow any exceptions.

4. If b is invalid, throw a "`DataError`" `DOMException`.

5. Return the results of running compare two keys with a and b.

### 4.4. The `IDBDatabase` interface

The `IDBDatabase` interface represents a connection to a database.

An `IDBDatabase` object must not be garbage collected if its associated connection's close pending flag is false and it has one or more event listeners registers whose type is one of `abort`, `error`, or `versionchange`. If an `IDBDatabase` object is garbage collected, the associated connection must be closed.

    [Exposed=(Window,Worker)]
    interface IDBDatabase : EventTarget {
      readonly attribute DOMString name;
      readonly attribute unsigned long long version;
      readonly attribute DOMStringList objectStoreNames;

      [NewObject] IDBTransaction transaction((DOMString or sequence<DOMString>) storeNames,
                                             optional IDBTransactionMode mode = "readonly");
      void close();

      [NewObject] IDBObjectStore createObjectStore(
        DOMString name,
        optional IDBObjectStoreParameters options = {});
      void deleteObjectStore(DOMString name);

      // Event handlers:
      attribute EventHandler onabort;
      attribute EventHandler onclose;
      attribute EventHandler onerror;
      attribute EventHandler onversionchange;
    };

    dictionary IDBObjectStoreParameters {
      (DOMString or sequence<DOMString>)? keyPath = null;
      boolean autoIncrement = false;
    };

connection . `name`

  Returns the name of the database.

connection . `version`

  Returns the version of the database.

The `name` attribute’s getter must return this's associated database's name. The attribute must return this name even if this's close pending flag is true. In other words, the value of this attribute stays constant for the lifetime of the `IDBDatabase` instance.

The `version` attribute’s getter must return this's version.

Is this the same as the database's version?
As long as the connection is open, this is the same as the connected database's version. But once the connection has closed, this attribute will not reflect changes made with a later upgrade transaction.

connection . `objectStoreNames`

  Returns a list of the names of object stores in the database.

store = connection . `createObjectStore`(name [, options])

  Creates a new object store with the given name and options and returns a new `IDBObjectStore`.

  Throws a "`InvalidStateError`" `DOMException` if not called within an upgrade transaction.

connection . `deleteObjectStore`(name)

  Deletes the object store with the given name.

  Throws a "`InvalidStateError`" `DOMException` if not called within an upgrade transaction.

The `objectStoreNames` attribute’s getter must return a `DOMStringList` associated with a sorted name list of the names of the object stores in this's object store set.

Is this the same as the database's object store names?
As long as the connection is open, this is the same as the connected database's object store names. But once the connection has closed, this attribute will not reflect changes made with a later upgrade transaction.

The `createObjectStore(name, options)` method, when invoked, must run these steps:

1. Let database be this's associated database.

2. Let transaction be database’s upgrade transaction if it is not null, or throw an "`InvalidStateError`" `DOMException` otherwise.

3. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

4. Let keyPath be options’s `keyPath` member if it is not undefined or null, or null otherwise.

5. If keyPath is not null and is not a valid key path, throw a "`SyntaxError`" `DOMException`.

6. If an object store named name already exists in database throw a "`ConstraintError`" `DOMException`.

7. Let autoIncrement be options’s `autoIncrement` member.

8. If autoIncrement is true and keyPath is an empty string or any sequence (empty or otherwise), throw an "`InvalidAccessError`" `DOMException`.

9. Let store be a new object store in database. Set the created object store's name to name. If autoIncrement is true, then the created object store uses a key generator. If keyPath is not null, set the created object store's key path to keyPath.

10. Return a new object store handle associated with store and transaction.

This method creates and returns a new object store with the given name in the connected database. Note that this method must only be called from within an upgrade transaction.

This method synchronously modifies the `objectStoreNames` property on the `IDBDatabase` instance on which it was called.

In some implementations it is possible for the implementation to run into problems after queuing a task to create the object store after the `createObjectStore()` method has returned. For example in implementations where metadata about the newly created object store is inserted into the database asynchronously, or where the implementation might need to ask the user for permission for quota reasons. Such implementations must still create and return an `IDBObjectStore` object, and once the implementation determines that creating the object store has failed, it must abort the transaction using the steps to abort a transaction using the appropriate error. For example if creating the object store failed due to quota reasons, a "`QuotaExceededError`" `DOMException` must be used as error.

The `deleteObjectStore(name)` method, when invoked, must run these steps:

1. Let database be this's associated database.

2. Let transaction be database’s upgrade transaction if it is not null, or throw an "`InvalidStateError`" `DOMException` otherwise.

3. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

4. Let store be the object store named name in database, or throw a "`NotFoundError`" `DOMException` if none.

5. Remove store from this's object store set.

6. If there is an object store handle associated with store and transaction, remove all entries from its index set.

7. Destroy store.

This method destroys the object store with the given name in the connected database. Note that this method must only be called from within an upgrade transaction.

This method synchronously modifies the `objectStoreNames` property on the `IDBDatabase` instance on which it was called.

transaction = connection . `transaction`(scope [, mode = "readonly"])

  Returns a new transaction with the given mode (`"readonly"` or `"readwrite"`) and scope which can be a single object store name or an array of names.

connection . `close`()

  Closes the connection once all running transactions have finished.

The `transaction(storeNames, mode)` method, when invoked, must run these steps:

1. If a running upgrade transaction is associated with the connection, throw an "`InvalidStateError`" `DOMException`.

2. If this's close pending flag is true, then throw an "`InvalidStateError`" `DOMException`.

3. Let scope be the set of unique strings in storeNames if it is a sequence, or a set containing one string equal to storeNames otherwise.

4. If any string in scope is not the name of an object store in the connected database, throw a "`NotFoundError`" `DOMException`.

5. If scope is empty, throw an "`InvalidAccessError`" `DOMException`.

6. If mode is not `"readonly"` or `"readwrite"`, throw a TypeError.

7. Let transaction be a newly created transaction with connection, mode and the set of object stores named in scope.

8. Set transaction’s cleanup event loop to the current event loop.

9. Return an `IDBTransaction` object representing transaction.

The created transaction will follow the lifetime rules.

The `close()` method, when invoked, must run these steps:

1. Run close a database connection with this connection.

The connection will not actually close until all outstanding transactions have completed. Subsequent calls to `close()` will have no effect.

The `onabort` attribute is the event handler for the `abort` event.

The `onclose` attribute is the event handler for the `close` event.

The `onerror` attribute is the event handler for the `error` event.

The `onversionchange` attribute is the event handler for the `versionchange` event.

### 4.5. The `IDBObjectStore` interface

The `IDBObjectStore` interface represents an object store handle.

    [Exposed=(Window,Worker)]
    interface IDBObjectStore {
      attribute DOMString name;
      readonly attribute any keyPath;
      readonly attribute DOMStringList indexNames;
      [SameObject] readonly attribute IDBTransaction transaction;
      readonly attribute boolean autoIncrement;

      [NewObject] IDBRequest put(any value, optional any key);
      [NewObject] IDBRequest add(any value, optional any key);
      [NewObject] IDBRequest delete(any query);
      [NewObject] IDBRequest clear();
      [NewObject] IDBRequest get(any query);
      [NewObject] IDBRequest getKey(any query);
      [NewObject] IDBRequest getAll(optional any query,
                                    optional [EnforceRange] unsigned long count);
      [NewObject] IDBRequest getAllKeys(optional any query,
                                        optional [EnforceRange] unsigned long count);
      [NewObject] IDBRequest count(optional any query);

      [NewObject] IDBRequest openCursor(optional any query,
                                        optional IDBCursorDirection direction = "next");
      [NewObject] IDBRequest openKeyCursor(optional any query,
                                           optional IDBCursorDirection direction = "next");

      IDBIndex index(DOMString name);

      [NewObject] IDBIndex createIndex(DOMString name,
                                       (DOMString or sequence<DOMString>) keyPath,
                                       optional IDBIndexParameters options = {});
      void deleteIndex(DOMString name);
    };

    dictionary IDBIndexParameters {
      boolean unique = false;
      boolean multiEntry = false;
    };

store . `name`

  Returns the name of the store.

store . `name` = newName

  Updates the name of the store to newName.

  Throws "`InvalidStateError`" `DOMException` if not called within an upgrade transaction.

store . `keyPath`

  Returns the key path of the store, or null if none.

list . `indexNames`

  Returns a list of the names of indexes in the store.

store . `transaction`

  Returns the associated transaction.

store . `autoIncrement`

  Returns true if the store has a key generator, and false otherwise.

The `name` attribute’s getter must return this's name.

Is this the same as the object store's name?
As long as the transaction has not finished, this is the same as the associated object store's name. But once the transaction has finished, this attribute will not reflect changes made with a later upgrade transaction.

The `name` attribute’s setter must run these steps:

1. Let name be the given value.

2. Let transaction be this's transaction.

3. Let store be this's object store.

4. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

5. If transaction is not an upgrade transaction, throw an "`InvalidStateError`" `DOMException`.

6. If transaction’s state is not active, throw a "`TransactionInactiveError`" `DOMException`.

7. If store’s name is equal to name, terminate these steps.

8. If an object store named name already exists in store’s database, throw a "`ConstraintError`" `DOMException`.

9. Set store’s name to name.

10. Set this's name to name.

The `keyPath` attribute’s getter must return this's object store's key path, or null if none. The key path is converted as a `DOMString` (if a string) or a sequence<DOMString> (if a list of strings), per [WEBIDL].

The returned value is not the same instance that was used when the object store was created. However, if this attribute returns an object (specifically an Array), it returns the same object instance every time it is inspected. Changing the properties of the object has no effect on the object store.

The `indexNames` attribute’s getter must return a `DOMStringList` associated with a sorted name list of the names of indexes in this's index set.

Is this the same as object store's list of index names?
As long as the transaction has not finished, this is the same as the associated object store's list of index names. But once the transaction has finished, this attribute will not reflect changes made with a later upgrade transaction.

The `transaction` attribute’s getter must return this's transaction.

The `autoIncrement` attribute’s getter must return true if this's object store has a key generator, and false otherwise.

The following methods throw a "`ReadOnlyError`" `DOMException` if called within a read-only transaction, and a "`TransactionInactiveError`" `DOMException` if called when the transaction is not active.

request = store . `put`(value [, key])
request = store . `add`(value [, key])

  Adds or updates a record in store with the given value and key.

  If the store uses in-line keys and key is specified a "`DataError`" `DOMException` will be thrown.

  If `put()` is used, any existing record with the key will be replaced. If `add()` is used, and if a record with the key already exists the request will fail, with request’s `error` set to a "`ConstraintError`" `DOMException`.

  If successful, request’s `result` will be the record's key.

request = store . `delete`(query)

  Deletes records in store with the given key or in the given key range in query.

  If successful, request’s `result` will be `undefined`.

request = store . `clear`()

  Deletes all records in store.

  If successful, request’s `result` will be `undefined`.

The `put(value, key)` method, when invoked, must return the result of running add or put with this, value, key and the no-overwrite flag false.

The `add(value, key)` method, when invoked, must return the result of running add or put with this, value, key and the no-overwrite flag true.

To add or put with handle, value, key, and no-overwrite flag, run these steps:

1. Let transaction be handle’s transaction.

2. Let store be handle’s object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. If transaction is a read-only transaction, throw a "`ReadOnlyError`" `DOMException`.

6. If store uses in-line keys and key was given, throw a "`DataError`" `DOMException`.

7. If store uses out-of-line keys and has no key generator and key was not given, throw a "`DataError`" `DOMException`.

8. If key was given, then:

   1. Let r be the result of running convert a value to a key with key. Rethrow any exceptions.

   2. If r is invalid, throw a "`DataError`" `DOMException`.

   3. Let key be r.

9. Let targetRealm be a user-agent defined Realm.

10. Let clone be a clone of value in targetRealm during transaction. Rethrow any exceptions.

    Why create a copy of the value?
    The value is serialized when stored. Treating it as a copy here allows other algorithms in this specification to treat it as an ECMAScript value, but implementations can optimize this if the difference in behavior is not observable.

11. If store uses in-line keys, then:

    1. Let kpk be the result of running extract a key from a value using a key path with clone and store’s key path. Rethrow any exceptions.

    2. If kpk is invalid, throw a "`DataError`" `DOMException`.

    3. If kpk is not failure, let key be kpk.

    4. Otherwise (kpk is failure):

       1. If store does not have a key generator, throw a "`DataError`" `DOMException`.

       2. Otherwise, if check that a key could be injected into a value with clone and store’s key path return false, throw a "`DataError`" `DOMException`.

12. Return the result (an `IDBRequest`) of running asynchronously execute a request with handle as source and store a record into an object store as operation, using store, the clone as value, key, and no-overwrite flag.

The `delete(query)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. If transaction is a read-only transaction, throw a "`ReadOnlyError`" `DOMException`.

6. Let range be the result of running convert a value to a key range with query and null disallowed flag true. Rethrow any exceptions.

7. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and delete records from an object store as operation, using store and range.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the records keys to be deleted.

Unlike other methods which take keys or key ranges, this method does not allow null to be given as key. This is to reduce the risk that a small bug would clear a whole object store.

The `clear()` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. If transaction is a read-only transaction, throw a "`ReadOnlyError`" `DOMException`.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and clear an object store as operation, using store.

The following methods throw a "`TransactionInactiveError`" `DOMException` if called when the transaction is not active.

request = store . `get`(query)

  Retrieves the value of the first record matching the given key or key range in query.

  If successful, request’s `result` will be the value, or `undefined` if there was no matching record.

request = store . `getKey`(query)

  Retrieves the key of the first record matching the given key or key range in query.

  If successful, request’s `result` will be the key, or `undefined` if there was no matching record.

request = store . `getAll`(query [, count])

  Retrieves the values of the records matching the given key or key range in query (up to count if given).

  If successful, request’s `result` will be an Array of the values.

request = store . `getAllKeys`(query [, count])

  Retrieves the keys of records matching the given key or key range in query (up to count if given).

  If successful, request’s `result` will be an Array of the keys.

request = store . `count`(query)

  Retrieves the number of records matching the given key or key range in query.

  If successful, request’s `result` will be the count.

The `get(query)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query and null disallowed flag true. Rethrow any exceptions.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and retrieve a value from an object store as operation, using the current Realm as targetRealm, store and range.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the record to be retrieved. If a range is specified, the method retrieves the first existing value in that range.

This method produces the same result if a record with the given key doesn’t exist as when a record exists, but has `undefined` as value. If you need to tell the two situations apart, you can use `openCursor()` with the same key. This will return a cursor with `undefined` as value if a record exists, or no cursor if no such record exists.

The `getKey(query)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query and null disallowed flag true. Rethrow any exceptions.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and retrieve a key from an object store as operation, using store and range.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the record key to be retrieved. If a range is specified, the method retrieves the first existing key in that range.

The `getAll(query, count)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query. Rethrow any exceptions.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and retrieve multiple values from an object store as operation, using the current Realm as targetRealm, store, range, and count if given.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the records to be retrieved. If null or not given, an unbounded key range is used. If count is specified and there are more than count records in range, only the first count will be retrieved.

The `getAllKeys(query, count)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query. Rethrow any exceptions.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and retrieve multiple keys from an object store as operation, using store, range, and count if given.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the records keys to be retrieved. If null or not given, an unbounded key range is used. If count is specified and there are more than count keys in range, only the first count will be retrieved.

The `count(query)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query. Rethrow any exceptions.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and count the records in a range as operation, using source and range.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the records keys to be counted. If null or not given, an unbounded key range is used.

The following methods throw a "`TransactionInactiveError`" `DOMException` if called when the transaction is not active.

request = store . `openCursor`([query [, direction = "next"]])

  Opens a cursor over the records matching query, ordered by direction. If query is null, all records in store are matched.

  If successful, request’s `result` will be an `IDBCursorWithValue` pointing at the first matching record, or null if there were no matching records.

request = store . `openKeyCursor`([query [, direction = "next"]])

  Opens a cursor with key only flag set to true over the records matching query, ordered by direction. If query is null, all records in store are matched.

  If successful, request’s `result` will be an `IDBCursor` pointing at the first matching record, or null if there were no matching records.

The `openCursor(query, direction)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query. Rethrow any exceptions.

6. Let cursor be a new cursor with its transaction set to transaction, undefined position, direction set to direction, got value flag set to false, undefined key and value, source set to store, range set to range, and key only flag set to false.

7. Let request be the result of running asynchronously execute a request with this as source and iterate a cursor as operation, using the current Realm as targetRealm, and cursor.

8. Set cursor’s request to request.

9. Return request.

The query parameter may be a key or key range (an `IDBKeyRange`) to use as the cursor's range. If null or not given, an unbounded key range is used.

The `openKeyCursor(query, direction)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query. Rethrow any exceptions.

6. Let cursor be a new cursor with its transaction set to transaction, undefined position, direction set to direction, got value flag set to false, undefined key and value, source set to store, range set to range, and key only flag set to true.

7. Let request be the result of running asynchronously execute a request with this as source and iterate a cursor as operation, using the current Realm as targetRealm, and cursor.

8. Set cursor’s request to request.

9. Return request.

The query parameter may be a key or key range (an `IDBKeyRange`) to use as the cursor's range. If null or not given, an unbounded key range is used.

index = store . index(name)

  Returns an `IDBIndex` for the index named name in store.

index = store . `createIndex`(name, keyPath [, options])

  Creates a new index in store with the given name, keyPath and options and returns a new `IDBIndex`. If the keyPath and options define constraints that cannot be satisfied with the data already in store the upgrade transaction will abort with a "`ConstraintError`" `DOMException`.

  Throws an "`InvalidStateError`" `DOMException` if not called within an upgrade transaction.

store . `deleteIndex`(name)

  Deletes the index in store with the given name.

  Throws an "`InvalidStateError`" `DOMException` if not called within an upgrade transaction.

The `createIndex(name, keyPath, options)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If transaction is not an upgrade transaction, throw an "`InvalidStateError`" `DOMException`.

4. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

5. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

6. If an index named name already exists in store, throw a "`ConstraintError`" `DOMException`.

7. If keyPath is not a valid key path, throw a "`SyntaxError`" `DOMException`.

8. Let unique be options’s `unique` member.

9. Let multiEntry be options’s `multiEntry` member.

10. If keyPath is a sequence and multiEntry is true, throw an "`InvalidAccessError`" `DOMException`.

11. Let index be a new index in store. Set index’s name to name, key path to keyPath, unique flag to unique, and multiEntry flag to multiEntry.

12. Add index to this's index set.

13. Return a new index handle associated with index and this.

This method creates and returns a new index with the given name in the object store. Note that this method must only be called from within an upgrade transaction.

The index that is requested to be created can contain constraints on the data allowed in the index’s referenced object store, such as requiring uniqueness of the values referenced by the index’s key path. If the referenced object store already contains data which violates these constraints, this must not cause the implementation of `createIndex()` to throw an exception or affect what it returns. The implementation must still create and return an `IDBIndex` object, and the implementation must queue a task to abort the upgrade transaction which was used for the `createIndex()` call.

This method synchronously modifies the `indexNames` property on the `IDBObjectStore` instance on which it was called. Although this method does not return an `IDBRequest` object, the index creation itself is processed as an asynchronous request within the upgrade transaction.

In some implementations it is possible for the implementation to asynchronously run into problems creating the index after the createIndex method has returned. For example in implementations where metadata about the newly created index is queued up to be inserted into the database asynchronously, or where the implementation might need to ask the user for permission for quota reasons. Such implementations must still create and return an `IDBIndex` object, and once the implementation determines that creating the index has failed, it must run the steps to abort a transaction using an appropriate error as error. For example if creating the index failed due to quota reasons, a "`QuotaExceededError`" `DOMException` must be used as error and if the index can’t be created due to unique flag constraints, a "`ConstraintError`" `DOMException` must be used as error.

The asynchronous creation of indexes is observable in the following example:

        const request1 = objectStore.put({name: "betty"}, 1);
        const request2 = objectStore.put({name: "betty"}, 2);
        const index = objectStore.createIndex("by_name", "name", {unique: true});

At the point where `createIndex()` called, neither of the requests have executed. When the second request executes, a duplicate name is created. Since the index creation is considered an asynchronous request, the index’s uniqueness constraint does not cause the second request to fail. Instead, the transaction will be aborted when the index is created and the constraint fails.

The `index(name)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is finished, then throw an "`InvalidStateError`" `DOMException`.

5. Let index be the index named name in this's index set if one exists, or throw a "`NotFoundError`" `DOMException` otherwise.

6. Return an index handle associated with index and this.

Each call to this method on the same `IDBObjectStore` instance with the same name returns the same `IDBIndex` instance.
The returned `IDBIndex` instance is specific to this `IDBObjectStore` instance. If this method is called on a different `IDBObjectStore` instance with the same name, a different `IDBIndex` instance is returned.

The `deleteIndex(name)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let store be this's object store.

3. If transaction is not an upgrade transaction, throw an "`InvalidStateError`" `DOMException`.

4. If store has been deleted, throw an "`InvalidStateError`" `DOMException`.

5. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

6. Let index be the index named name in store if one exists, or throw a "`NotFoundError`" `DOMException` otherwise.

7. Remove index from this's index set.

8. Destroy index.

This method destroys the index with the given name in the object store. Note that this method must only be called from within an upgrade transaction.

This method synchronously modifies the `indexNames` property on the `IDBObjectStore` instance on which it was called. Although this method does not return an `IDBRequest` object, the index destruction itself is processed as an asynchronous request within the upgrade transaction.

### 4.6. The `IDBIndex` interface

The `IDBIndex` interface represents an index handle.

    [Exposed=(Window,Worker)]
    interface IDBIndex {
      attribute DOMString name;
      [SameObject] readonly attribute IDBObjectStore objectStore;
      readonly attribute any keyPath;
      readonly attribute boolean multiEntry;
      readonly attribute boolean unique;

      [NewObject] IDBRequest get(any query);
      [NewObject] IDBRequest getKey(any query);
      [NewObject] IDBRequest getAll(optional any query,
                                    optional [EnforceRange] unsigned long count);
      [NewObject] IDBRequest getAllKeys(optional any query,
                                        optional [EnforceRange] unsigned long count);
      [NewObject] IDBRequest count(optional any query);

      [NewObject] IDBRequest openCursor(optional any query,
                                        optional IDBCursorDirection direction = "next");
      [NewObject] IDBRequest openKeyCursor(optional any query,
                                           optional IDBCursorDirection direction = "next");
    };

index . `name`

  Returns the name of the index.

index . `name` = newName

  Updates the name of the store to newName.

Throws an "`InvalidStateError`" `DOMException` if not called within an upgrade transaction.

index . `objectStore`

  Returns the `IDBObjectStore` the index belongs to.

index . keyPath

  Returns the key path of the index.

index . multiEntry

  Returns true if the index’s multiEntry flag is true.

index . unique

  Returns true if the index’s unique flag is true.

The `name` attribute’s getter must return this's name.

Is this the same as the index's name?
As long as the transaction has not finished, this is the same as the associated index's name. But once the transaction has finished, this attribute will not reflect changes made with a later upgrade transaction.

The `name` attribute’s setter must run these steps:

1. Let name be the given value.

2. Let transaction be this's transaction.

3. Let index be this's index.

4. If transaction is not an upgrade transaction, throw an "`InvalidStateError`" `DOMException`.

5. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

6. If index or index’s object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

7. If index’s name is equal to name, terminate these steps.

8. If an index named name already exists in index’s object store, throw a "`ConstraintError`" `DOMException`.

9. Set index’s name to name.

10. Set this's name to name.

The `objectStore` attribute’s getter must return this's object store handle.

The `keyPath` attribute’s getter must return this's index's key path. The key path is converted as a `DOMString` (if a string) or a sequence<DOMString> (if a list of strings), per [WEBIDL].

The returned value is not the same instance that was used when the index was created. However, if this attribute returns an object (specifically an Array), it returns the same object instance every time it is inspected. Changing the properties of the object has no effect on the index.

The `multiEntry` attribute’s getter must return this's index's multiEntry flag.

The `unique` attribute’s getter must return this's index's unique flag.

The following methods throw an "`TransactionInactiveError`" `DOMException` if called when the transaction is not active.

request = index . `get`(query)

  Retrieves the value of the first record matching the given key or key range in query.

  If successful, request’s `result` will be the value, or `undefined` if there was no matching record.

request = index . `getKey`(query)

  Retrieves the key of the first record matching the given key or key range in query.

  If successful, request’s `result` will be the key, or `undefined` if there was no matching record.

request = index . `getAll`(query [, count])

  Retrieves the values of the records matching the given key or key range in query (up to count if given).

  If successful, request’s `result` will be an Array of the values.

request = index . `getAllKeys`(query [, count])

  Retrieves the keys of records matching the given key or key range in query (up to count if given).

  If successful, request’s `result` will be an Array of the keys.

request = index . `count`(query)

  Retrieves the number of records matching the given key or key range in query.

  If successful, request’s `result` will be the count.

The `get(query)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let index be this's index.

3. If index or index’s object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query and null disallowed flag true. Rethrow any exceptions.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and retrieve a referenced value from an index as operation, using the current Realm as targetRealm, index and range.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the record to be retrieved. If a range is specified, the method retrieves the first existing record in that range.

This method produces the same result if a record with the given key doesn’t exist as when a record exists, but has `undefined` as value. If you need to tell the two situations apart, you can use `openCursor()` with the same key. This will return a cursor with `undefined` as value if a record exists, or no cursor if no such record exists.

The `getKey(query)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let index be this's index.

3. If index or index’s object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query and null disallowed flag true. Rethrow any exceptions.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and retrieve a value from an index as operation, using index and range.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the record key to be retrieved. If a range is specified, the method retrieves the first existing key in that range.

The `getAll(query, count)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let index be this's index.

3. If index or index’s object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query. Rethrow any exceptions.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and retrieve multiple referenced values from an index as operation, using the current Realm as targetRealm, index, range, and count if given.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the records to be retrieved. If null or not given, an unbounded key range is used. If count is specified and there are more than count records in range, only the first count will be retrieved.

The `getAllKeys(query, count)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let index be this's index.

3. If index or index’s object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query. Rethrow any exceptions.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and retrieve multiple values from an index as operation, using index, range, and count if given.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the records keys to be retrieved. If null or not given, an unbounded key range is used. If count is specified and there are more than count keys in range, only the first count will be retrieved.

The `count(query)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let index be this's index.

3. If index or index’s object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query. Rethrow any exceptions.

6. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and count the records in a range as operation, using index as source and range.

The query parameter may be a key or key range (an `IDBKeyRange`) identifying the records keys to be counted. If null or not given, an unbounded key range is used.

The following methods throw an "`TransactionInactiveError`" `DOMException` if called when the transaction is not active.

request = index . `openCursor`([query [, direction = "next"]])

  Opens a cursor over the records matching query, ordered by direction. If query is null, all records in index are matched.

  If successful, request’s `result` will be an `IDBCursorWithValue`, or null if there were no matching records.

request = index . `openKeyCursor`([query [, direction = "next"]])

  Opens a cursor with key only flag set to true over the records matching query, ordered by direction. If query is null, all records in index are matched.

  If successful, request’s `result` will be an `IDBCursor`, or null if there were no matching records.

The `openCursor(query, direction)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let index be this's index.

3. If index or index’s object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query. Rethrow any exceptions.

6. Let cursor be a new cursor with its transaction set to transaction, undefined position, direction set to direction, got value flag set to false, undefined key and value, source set to index, range set to range, and key only flag set to false.

7. Let request be the result of running asynchronously execute a request with this as source and iterate a cursor as operation, using the current Realm as targetRealm, and cursor.

8. Set cursor’s request to request.

9. Return request.

The query parameter may be a key or key range (an `IDBKeyRange`) to use as the cursor's range. If null or not given, an unbounded key range is used.

The `openKeyCursor(query, direction)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. Let index be this's index.

3. If index or index’s object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

5. Let range be the result of running convert a value to a key range with query. Rethrow any exceptions.

6. Let cursor be a new cursor with its transaction set to transaction, undefined position, direction set to direction, got value flag set to false, undefined key and value, source set to index, range set to range, and key only flag set to true.

7. Let request be the result of running asynchronously execute a request with this as source and iterate a cursor as operation, using the current Realm as targetRealm, and cursor.

8. Set cursor’s request to request.

9. Return request.

The query parameter may be a key or key range (an `IDBKeyRange`) to use as the cursor's range. If null or not given, an unbounded key range is used.

### 4.7. The `IDBKeyRange` interface

The `IDBKeyRange` interface represents a key range.

    [Exposed=(Window,Worker)]
    interface IDBKeyRange {
      readonly attribute any lower;
      readonly attribute any upper;
      readonly attribute boolean lowerOpen;
      readonly attribute boolean upperOpen;

      // Static construction methods:
      [NewObject] static IDBKeyRange only(any value);
      [NewObject] static IDBKeyRange lowerBound(any lower, optional boolean open = false);
      [NewObject] static IDBKeyRange upperBound(any upper, optional boolean open = false);
      [NewObject] static IDBKeyRange bound(any lower,
                                           any upper,
                                           optional boolean lowerOpen = false,
                                           optional boolean upperOpen = false);

      boolean includes(any key);
    };

range . `lower`

  Returns the range’s lower bound, or `undefined` if none.

range . `upper`

  Returns the range’s upper bound, or `undefined` if none.

range . `lowerOpen`

  Returns the range’s lower open flag.

range . `upperOpen`

  Returns the range’s upper open flag.

The `lower` attribute’s getter must return result of running convert a key to a value with this's lower bound if it is not null, or undefined otherwise.

The `upper` attribute’s getter must return the result of running convert a key to a value with this's upper bound if it is not null, or undefined otherwise.

The `lowerOpen` attribute’s getter must return this's lower open flag.

The `upperOpen` attribute’s getter must return this's upper open flag.

range = `IDBKeyRange` . `only`(key)

  Returns a new `IDBKeyRange` spanning only key.

range = `IDBKeyRange` . `lowerBound`(key [, open = false])

  Returns a new `IDBKeyRange` starting at key with no upper bound. If open is true, key is not included in the range.

range = `IDBKeyRange` . `upperBound`(key [, open = false])

  Returns a new `IDBKeyRange` with no lower bound and ending at key. If open is true, key is not included in the range.

range = `IDBKeyRange` . `bound`(lower, upper [, lowerOpen = false [, upperOpen = false]])

  Returns a new `IDBKeyRange` spanning from lower to upper. If lowerOpen is true, lower is not included in the range. If upperOpen is true, upper is not included in the range.

The `only(value)` method, when invoked, must run these steps:

1. Let key be the result of running convert a value to a key with value. Rethrow any exceptions.

2. If key is invalid, throw a "`DataError`" `DOMException`.

3. Create and return a new key range containing only key.

The `lowerBound(lower, open)` method, when invoked, must run these steps:

1. Let lowerKey be the result of running convert a value to a key with lower. Rethrow any exceptions.

2. If lowerKey is invalid, throw a "`DataError`" `DOMException`.

3. Create and return a new key range with lower bound set to lowerKey, lower open flag set to open, upper bound set to null, and upper open flag set to true.

The `upperBound(upper, open)` method, when invoked, must run these steps:

1. Let upperKey be the result of running convert a value to a key with upper. Rethrow any exceptions.

2. If upperKey is invalid, throw a "`DataError`" `DOMException`.

3. Create and return a new key range with lower bound set to null, lower open flag set to true, upper bound set to upperKey, and upper open flag set to open.

The `bound(lower, upper, lowerOpen, upperOpen)` method, when invoked, must run these steps:

1. Let lowerKey be the result of running convert a value to a key with lower. Rethrow any exceptions.

2. If lowerKey is invalid, throw a "`DataError`" `DOMException`.

3. Let upperKey be the result of running convert a value to a key with upper. Rethrow any exceptions.

4. If upperKey is invalid, throw a "`DataError`" `DOMException`.

5. If lowerKey is greater than upperKey, throw a "`DataError`" `DOMException`.

6. Create and return a new key range with lower bound set to lowerKey, lower open flag set to lowerOpen, upper bound set to upperKey and upper open flag set to upperOpen.

range . `includes`(key)

  Returns true if key is included in the range, and false otherwise.

The `includes(key)` method, when invoked, must run these steps:

1. Let k be the result of running convert a value to a key with key. Rethrow any exceptions.

2. If k is invalid, throw a "`DataError`" `DOMException`.

3. Return true if k is in this range, and false otherwise.

### 4.8. The `IDBCursor` interface

Cursor objects implement the `IDBCursor` interface. There is only ever one `IDBCursor` instance representing a given cursor. There is no limit on how many cursors can be used at the same time.

    [Exposed=(Window,Worker)]
    interface IDBCursor {
      readonly attribute (IDBObjectStore or IDBIndex) source;
      readonly attribute IDBCursorDirection direction;
      readonly attribute any key;
      readonly attribute any primaryKey;
      [SameObject] readonly attribute IDBRequest request;

      void advance([EnforceRange] unsigned long count);
      void continue(optional any key);
      void continuePrimaryKey(any key, any primaryKey);

      [NewObject] IDBRequest update(any value);
      [NewObject] IDBRequest delete();
    };

    enum IDBCursorDirection {
      "next",
      "nextunique",
      "prev",
      "prevunique"
    };

cursor . `source`

  Returns the `IDBObjectStore` or `IDBIndex` the cursor was opened from.

cursor . `direction`

  Returns the direction (`"next"`, `"nextunique"`, `"prev"` or `"prevunique"`) of the cursor.

cursor . `key`

  Returns the key of the cursor. Throws a "`InvalidStateError`" `DOMException` if the cursor is advancing or is finished.

cursor . `primaryKey`

  Returns the effective key of the cursor. Throws a "`InvalidStateError`" `DOMException` if the cursor is advancing or is finished.

cursor . `request`

  Returns the request that was used to obtain this cursor.

The `source` attribute’s getter must return this's source. This attribute never returns null or throws an exception, even if the cursor is currently being iterated, has iterated past its end, or its transaction is not active.

The `direction` attribute’s getter must return this's direction.

The `key` attribute’s getter must return the result of running convert a key to a value with the cursor’s current key. Note that if this property returns an object (e.g. a Date or Array), it returns the same object instance every time it is inspected, until the cursor’s key is changed. This means that if the object is modified, those modifications will be seen by anyone inspecting the value of the cursor. However modifying such an object does not modify the contents of the database.

The `primaryKey` attribute’s getter must return the result of running convert a key to a value with the cursor’s current effective key. Note that if this property returns an object (e.g. a Date or Array), it returns the same object instance every time it is inspected, until the cursor’s effective key is changed. This means that if the object is modified, those modifications will be seen by anyone inspecting the value of the cursor. However modifying such an object does not modify the contents of the database.

The `request` attribute’s getter must return this's request.

🚧 The `request` attribute is new in this edition. 🚧
The following methods advance a cursor. Once the cursor has advanced, a `success` event will be fired at the same `IDBRequest` returned when the cursor was opened. The `result` will be the same cursor if a record was in range, or `undefined` otherwise.

If called while the cursor is already advancing, an "`InvalidStateError`" `DOMException` will be thrown.

The following methods throw a "`TransactionInactiveError`" `DOMException` if called when the transaction is not active.

cursor . `advance`(count)

  Advances the cursor through the next count records in range.

cursor . `continue`()

  Advances the cursor to the next record in range.

cursor . `continue`(key)

  Advances the cursor to the next record in range matching or after key.

cursor . `continuePrimaryKey`(key, primaryKey)

  Advances the cursor to the next record in range matching or after key and primaryKey. Throws an "`InvalidAccessError`" `DOMException` if the source is not an index.

The `advance(count)` method, when invoked, must run these steps:

1. If count is 0 (zero), throw a TypeError.

2. Let transaction be this's transaction.

3. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

4. If this's source or effective object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

5. If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "`InvalidStateError`" `DOMException`.

6. Set this's got value flag to false.

7. Let request be this's request.

8. Set request’s processed flag to false.

9. Set request’s done flag to false.

10. Run asynchronously execute a request with this's source as source, iterate a cursor as operation and request, using the current Realm as targetRealm, this, and count.

Calling this method more than once before new cursor data has been loaded - for example, calling `advance()` twice from the same onsuccess handler - results in an "`InvalidStateError`" `DOMException` being thrown on the second call because the cursor’s got value flag has been set to false.

The `continue(key)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

3. If this's source or effective object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "`InvalidStateError`" `DOMException`.

5. If key is given, then:

   1. Let r be the result of running convert a value to a key with key. Rethrow any exceptions.

   2. If r is invalid, throw a "`DataError`" `DOMException`.

   3. Let key be r.

   4. If key is less than or equal to this's position and this's direction is `"next"` or `"nextunique"`, then throw a "`DataError`" `DOMException`.

   5. If key is greater than or equal to this's position and this's direction is `"prev"` or `"prevunique"`, then throw a "`DataError`" `DOMException`.

6. Set this's got value flag to false.

7. Let request be this's request.

8. Set request’s processed flag to false.

9. Set request’s done flag to false.

10. Run asynchronously execute a request with this's source as source, iterate a cursor as operation and request, using the current Realm as targetRealm, this, and key (if given).

Calling this method more than once before new cursor data has been loaded - for example, calling `continue()` twice from the same onsuccess handler - results in an "`InvalidStateError`" `DOMException` being thrown on the second call because the cursor’s got value flag has been set to false.

The `continuePrimaryKey(key, primaryKey)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

3. If this's source or effective object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

4. If this's source is not an index throw an "`InvalidAccessError`" `DOMException`.

5. If this's direction is not `"next"` or `"prev"`, throw an "`InvalidAccessError`" `DOMException`.

6. If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "`InvalidStateError`" `DOMException`.

7. Let r be the result of running convert a value to a key with key. Rethrow any exceptions.

8. If r is invalid, throw a "`DataError`" `DOMException`.

9. Let key be r.

10. Let r be the result of running convert a value to a key with primaryKey. Rethrow any exceptions.

11. If r is invalid, throw a "`DataError`" `DOMException`.

12. Let primaryKey be r.

13. If key is less than this's position and this's direction is `"next"`, throw a "`DataError`" `DOMException`.

14. If key is greater than this's position and this's direction is `"prev"`, throw a "`DataError`" `DOMException`.

15. If key is equal to this's position and primaryKey is less than or equal to this's object store position and this's direction is `"next"`, throw a "`DataError`" `DOMException`.

16. If key is equal to this's position and primaryKey is greater than or equal to this's object store position and this's direction is `"prev"`, throw a "`DataError`" `DOMException`.

17. Set this's got value flag to false.

18. Let request be this's request.

19. Set request’s processed flag to false.

20. Set request’s done flag to false.

21. Run asynchronously execute a request with this's source as source, iterate a cursor as operation and request, using the current Realm as targetRealm, this, key and primaryKey.

Calling this method more than once before new cursor data has been loaded - for example, calling `continuePrimaryKey()` twice from the same onsuccess handler - results in an "`InvalidStateError`" `DOMException` being thrown on the second call because the cursor’s got value flag has been set to false.
The following methods throw a "`ReadOnlyError`" `DOMException` if called within a read-only transaction, and a "`TransactionInactiveError`" `DOMException` if called when the transaction is not active.

request = cursor . `update`(value)

  Updated the record pointed at by the cursor with a new value.

  Throws a "`DataError`" `DOMException` if the effective object store uses in-line keys and the key would have changed.

  If successful, request’s `result` will be the record's key.

request = cursor . `delete`()

  Delete the record pointed at by the cursor with a new value.

  If successful, request’s `result` will be `undefined`.

The `update(value)` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

3. If transaction is a read-only transaction, throw a "`ReadOnlyError`" `DOMException`.

4. If this's source or effective object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

5. If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "`InvalidStateError`" `DOMException`.

6. If this's key only flag is true, throw an "`InvalidStateError`" `DOMException`.

7. Let targetRealm be a user-agent defined Realm.

8. Let clone be a clone of value in targetRealm during transaction. Rethrow any exceptions.

   Why create a copy of the value?
   The value is serialized when stored. Treating it as a copy here allows other algorithms in this specification to treat it as an ECMAScript value, but implementations can optimize this if the difference in behavior is not observable.

9. If this's effective object store uses in-line keys, then:

   1. Let kpk be the result of running extract a key from a value using a key path with clone and the key path of this's effective object store. Rethrow any exceptions.

   2. If kpk is failure, invalid, or not equal to this's effective key, throw a "`DataError`" `DOMException`.

10. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and store a record into an object store as operation, using this's effective object store as store, the clone as value, this's effective key as key, and with the no-overwrite flag false.

A result of running the steps to store a record into an object store is that if the record has been deleted since the cursor moved to it, a new record will be created.

The `delete()` method, when invoked, must run these steps:

1. Let transaction be this's transaction.

2. If transaction’s state is not active, then throw a "`TransactionInactiveError`" `DOMException`.

3. If transaction is a read-only transaction, throw a "`ReadOnlyError`" `DOMException`.

4. If this's source or effective object store has been deleted, throw an "`InvalidStateError`" `DOMException`.

5. If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "`InvalidStateError`" `DOMException`.

6. If this's key only flag is true, throw an "`InvalidStateError`" `DOMException`.

7. Return the result (an `IDBRequest`) of running asynchronously execute a request with this as source and delete records from an object store as operation, using this's effective object store and effective key as store and key respectively.

A cursor that has its key only flag set to false implements the `IDBCursorWithValue` interface as well.

    [Exposed=(Window,Worker)]
    interface IDBCursorWithValue : IDBCursor {
      readonly attribute any value;
    };

cursor . `value`

  Returns the cursor's current value.

The `value` attribute’s getter must return this's current value. Note that if this property returns an object, it returns the same object instance every time it is inspected, until the cursor’s value is changed. This means that if the object is modified, those modifications will be seen by anyone inspecting the value of the cursor. However modifying such an object does not modify the contents of the database.

### 4.9. The `IDBTransaction` interface

transaction objects implement the following interface:

    [Exposed=(Window,Worker)]
    interface IDBTransaction : EventTarget {
      readonly attribute DOMStringList objectStoreNames;
      readonly attribute IDBTransactionMode mode;
      [SameObject] readonly attribute IDBDatabase db;
      readonly attribute DOMException? error;

      IDBObjectStore objectStore(DOMString name);
      void commit();
      void abort();

      // Event handlers:
      attribute EventHandler onabort;
      attribute EventHandler oncomplete;
      attribute EventHandler onerror;
    };

    enum IDBTransactionMode {
      "readonly",
      "readwrite",
      "versionchange"
    };

transaction . `objectStoreNames`

  Returns a list of the names of object stores in the transaction’s scope. For an upgrade transaction this is all object stores in the database.

transaction . `mode`

  Returns the mode the transaction was created with (`"readonly"` or `"readwrite"`), or `"versionchange"` for an upgrade transaction.

transaction . `db`

  Returns the transaction’s connection.

transaction . `error`

  If the transaction was aborted, returns the error (a `DOMException`) providing the reason.

The `objectStoreNames` attribute’s getter must run these steps:

1. If this is an upgrade transaction, then return a `DOMStringList` associated with a sorted name list of the names of the object stores in this's connection's object store set.

2. Otherwise, return a `DOMStringList` associated with a sorted name list of the names of the object stores in this's scope.

The contents of each list returned by this attribute does not change, but subsequent calls to this attribute during an upgrade transaction can return lists with different contents as object stores are created and deleted.

The `mode` attribute’s getter must return this's mode.

The `db` attribute’s getter must return this's connection's associated database.

The `error` attribute’s getter must return this's error, or null if none.

If this transaction was aborted due to a failed request, this will be the same as the request's error. If this transaction was aborted due to an uncaught exception in an event handler, the error will be a "`AbortError`" `DOMException`. If the transaction was aborted due to an error while committing, it will reflect the reason for the failure (e.g. "`QuotaExceededError`", "`ConstraintError`", or "`UnknownError`" `DOMException`).

transaction . `objectStore`(name)

  Returns an `IDBObjectStore` in the transaction's scope.

transaction . `abort()`

  Aborts the transaction. All pending requests will fail with a "`AbortError`" `DOMException` and all changes made to the database will be reverted.

transaction . `commit()`

  Attempts to commit the transaction. All pending requests will be allowed to complete, but no new requests will be accepted. This can be used to force a transaction to quickly finish, without waiting for pending requests to fire `success` events before attempting to commit normally.

  The transaction will abort if a pending request fails, for example due to a constraint error. The `success` events for successful requests will still fire, but throwing an exception in an event handler will not abort the transaction. Similarly, `error` events for failed requests will still fire, but calling `preventDefault()` will not prevent the transaction from aborting.

The `objectStore(name)` method, when invoked, must run these steps:

1. If transaction’s state is finished, then throw an "`InvalidStateError`" `DOMException`.

2. Let store be the object store named name in this's scope, or throw a "`NotFoundError`" `DOMException` if none.

3. Return an object store handle associated with store and this.

Each call to this method on the same `IDBTransaction` instance with the same name returns the same `IDBObjectStore` instance.
The returned `IDBObjectStore` instance is specific to this `IDBTransaction`. If this method is called on a different `IDBTransaction`, a different `IDBObjectStore` instance is returned.

The `abort()` method, when invoked, must run these steps:

1. If this's state is committing or finished, then throw an "`InvalidStateError`" `DOMException`.

2. Set this's state to inactive and run abort a transaction with null as error.

The `commit()` method, when invoked, must run these steps:

1. If this's state is not active, then throw an "`InvalidStateError`" `DOMException`.

2. Run commit a transaction with this.

🚧 The `commit()` method is new in this edition. 🚧
It is not normally necessary to call `commit()` on a transaction. A transaction will automatically commit when all outstanding requests have been satisfied and no new requests have been made. This call can be used to start the commit process without waiting for events from outstanding requests to be dispatched.

The `onabort` attribute is the event handler for the `abort` event.

The `oncomplete` attribute is the event handler for the `complete` event.

The `onerror` attribute is the event handler for the `error` event.

To determine if a transaction has completed successfully, listen to the transaction's `complete` event rather than the `success` event of a particular request, because the transaction can still fail after the `success` event fires.

## 5. Algorithms

### 5.1. Opening a database

To open a database with origin which requested the database to be opened, a database name, a database version, and a request, run these steps:

1. Let queue be the connection queue for origin and name.

2. Add request to queue.

3. Wait until all previous requests in queue have been processed.

4. Let db be the database named name in origin, or null otherwise.

5. If version is undefined, let version be 1 if db is null, or db’s version otherwise.

6. If db is null, let db be a new database with name name, version 0 (zero), and with no object stores. If this fails for any reason, return an appropriate error (e.g. a "`QuotaExceededError`" or "`UnknownError`" `DOMException`).

7. If db’s version is greater than version, return a newly created "`VersionError`" `DOMException` and abort these steps.

8. Let connection be a new connection to db.

9. Set connection’s version to version.

10. If db’s version is less than version, then:

    1. Let openConnections be the set of all connections, except connection, associated with db.

    2. For each entry of openConnections that does not have its close pending flag set to true, queue a task to fire a version change event named `versionchange` at entry with db’s version and version.

       Firing this event might cause one or more of the other objects in openConnections to be closed, in which case the `versionchange` event is not fired at those objects, even if that hasn’t yet been done.

    3. Wait for all of the events to be fired.

    4. If any of the connections in openConnections are still not closed, queue a task to fire a version change event named `blocked` at request with db’s version and version.

    5. Wait until all connections in openConnections are closed.

    6. Run run an upgrade transaction using connection, version and request.

    7. If connection was closed, return a newly created "`AbortError`" `DOMException` and abort these steps.

    8. If the upgrade transaction was aborted, run the steps to close a database connection with connection, return a newly created "`AbortError`" `DOMException` and abort these steps.

11. Return connection.

### 5.2. Closing a database

To close a database connection with a connection object, and an optional forced flag, run these steps:

1. Set connection’s close pending flag to true.

2. If the forced flag is true, then for each transaction created using connection run abort a transaction with transaction and newly created "`AbortError`" `DOMException`.

3. Wait for all transactions created using connection to complete. Once they are complete, connection is closed.

4. If the forced flag is true, then fire an event named `close` at connection.

   The `close` event only fires if the connection closes abnormally, e.g. if the origin’s storage is cleared, or there is corruption or an I/O error. If `close()` is called explicitly the event does not fire.

Once a connection's close pending flag has been set to true, no new transactions can be created using the connection. All methods that create transactions first check the connection's close pending flag first and throw an exception if it is true.
Once the connection is closed, this can unblock the steps to run an upgrade transaction, and the steps to delete a database, which both wait for connections to a given database to be closed before continuing.

### 5.3. Deleting a database

To delete a database with the origin that requested the database to be deleted, a database name, and a request, run these steps:

1. Let queue be the connection queue for origin and name.

2. Add request to queue.

3. Wait until all previous requests in queue have been processed.

4. Let db be the database named name in origin, if one exists. Otherwise, return 0 (zero).

5. Let openConnections be the set of all connections associated with db.

6. For each entry of openConnections that does not have its close pending flag set to true, queue a task to fire a version change event named `versionchange` at entry with db’s version and null.

   Firing this event might cause one or more of the other objects in openConnections to be closed, in which case the `versionchange` event is not fired at those objects, even if that hasn’t yet been done.

7. Wait for all of the events to be fired.

8. If any of the connections in openConnections are still not closed, queue a task to fire a version change event named `blocked` at request with db’s version and null.

9. Wait until all connections in openConnections are closed.

10. Let version be db’s version.

11. Delete db. If this fails for any reason, return an appropriate error (e.g. "`QuotaExceededError`" or "`UnknownError`" `DOMException`).

12. Return version.

### 5.4. Committing a transaction

To commit a transaction with the transaction to commit, run these steps:

1. Set transaction’s state to committing.

2. Run the following steps in parallel:

   1. Wait until every item in transaction’s request list is processed.

   2. If transaction’s state is no longer committing, then terminate these steps.

   3. Attempt to write any outstanding changes made by transaction to the database.

   4. If an error occurs while writing the changes to the database, then run abort a transaction with transaction and an appropriate type for the error, for example "`QuotaExceededError`" or "`UnknownError`" `DOMException`, and terminate these steps.

   5. Queue a task to run these steps:

      1. If transaction is an upgrade transaction, then set transaction’s connection's associated database's upgrade transaction to null.

      2. Set transaction’s state to finished.

      3. Fire an event named `complete` at transaction.

         Even if an exception is thrown from one of the event handlers of this event, the transaction is still committed since writing the database changes happens before the event takes places. Only after the transaction has been successfully written is the `complete` event fired.

      4. If transaction is an upgrade transaction, then let request be the request associated with transaction and set request’s transaction to null.

### 5.5. Aborting a transaction

To abort a transaction with the transaction to abort, and error, run these steps:

1. All the changes made to the database by the transaction are reverted. For upgrade transactions this includes changes to the set of object stores and indexes, as well as the change to the version. Any object stores and indexes which were created during the transaction are now considered deleted for the purposes of other algorithms.

2. If transaction is an upgrade transaction, run the steps to abort an upgrade transaction with transaction.

   This reverts changes to all connection, object store handle, and index handle instances associated with transaction.

3. Set transaction’s state to finished.

4. If error is not null, set transaction’s error to error.

5. For each request of transaction’s request list, abort the steps to asynchronously execute a request for request, set request’s processed flag to true, and queue a task to run these steps:

   1. Set request’s done flag to true.

   2. Set request’s result to undefined.

   3. Set request’s error to a newly created "`AbortError`" `DOMException`.

   4. Fire an event named `error` at request with its `bubbles` and `cancelable` attributes initialized to true.

   This does not always result in any `error` events being fired. For example if a transaction is aborted due to an error while committing the transaction, or if it was the last remaining request that failed.

6. Queue a task to run these steps:

   1. If transaction is an upgrade transaction, then set transaction’s connection's associated database's upgrade transaction to null.

   2. Fire an event named `abort` at transaction with its `bubbles` attribute initialized to true.

   3. If transaction is an upgrade transaction, then:

      1. Let request be the open request associated with transaction.

      2. Set request’s transaction to null.

      3. Set request’s result to undefined.

      4. Set request’s processed flag to false.

      5. Set request’s done flag to false.

### 5.6. Asynchronously executing a request

To asynchronously execute a request with the source object and an operation to perform on a database, and an optional request, run these steps:

These steps can be aborted at any point if the transaction the created request belongs to is aborted using the steps to abort a transaction.

1. Let transaction be the transaction associated with source.

2. Assert: transaction’s state is active.

3. If request was not given, let request be a new request with source as source.

4. Add request to the end of transaction’s request list.

5. Run these steps in parallel:

   1. Wait until request is the first item in transaction’s request list that is not processed.

   2. Let result be the result of performing operation.

   3. If result is an error and transaction’s state is committing, then run abort a transaction with transaction and error, and terminate these steps.

   4. If result is an error, then revert all changes made by operation.

      This only reverts the changes done by this request, not any other changes made by the transaction.

   5. Set request’s processed flag to true.

   6. Queue a task to run these steps:

      1. Remove request from transaction’s request list.

      2. Set request’s done flag to true.

      3. If result is an error, then:

         1. Set request’s result to undefined.

         2. Set request’s error to result.

         3. Fire an error event at request.

      4. Otherwise:

         1. Set request’s result to result.

         2. Set request’s error to undefined.

         3. Fire a success event at request.

6. Return request.

### 5.7. Running an upgrade transaction

To run an upgrade transaction with a connection object which is used to update the database, a new version to be set for the database, and a request, run these steps:

1. Let db be connection’s database.

2. Let transaction be a new upgrade transaction with connection used as connection. The scope of transaction includes every object store in connection.

3. Set database’s upgrade transaction to transaction.

4. Set transaction’s state to inactive.

5. Start transaction.

   Note that until this transaction is finished, no other connections can be opened to the same database.

6. Let old version be db’s version.

7. Set db’s version to version. This change is considered part of the transaction, and so if the transaction is aborted, this change is reverted.

8. Set request’s processed flag to true.

9. Queue a task to run these steps:

   1. Set request’s result to connection.

   2. Set request’s transaction to transaction.

   3. Set request’s done flag to true.

   4. Set transaction’s state to active.

   5. Let didThrow be the result of running fire a version change event named `upgradeneeded` at request with old version and version.

   6. Set transaction’s state to inactive.

   7. If didThrow is true, run abort a transaction with the error property set to a newly created "`AbortError`" `DOMException`.

10. Wait for transaction to finish.

    Some of the algorithms invoked during the transaction's lifetime, such as the steps to commit a transaction and the steps to abort a transaction, include steps specific to upgrade transactions.

### 5.8. Aborting an upgrade transaction

To abort an upgrade transaction with transaction, run these steps:

These steps are run as needed by the steps to abort a transaction, which revert changes to the database including the set of associated object stores and indexes, as well as the change to the version.

1. Let connection be transaction’s connection.

2. Let database be connection’s database.

3. Set connection’s version to database’s version if database previously existed, or 0 (zero) if database was newly created.

   This reverts the value of `version` returned by the `IDBDatabase` object.

4. Set connection’s object store set to the set of object stores in database if database previously existed, or the empty set if database was newly created.

   This reverts the value of `objectStoreNames` returned by the `IDBDatabase` object.

5. For each object store handle handle associated with transaction, including those for object stores that were created or deleted during transaction:

   1. If handle’s object store was not newly created during transaction, set handle’s name to its object store's name.

   2. Set handle’s index set to the set of indexes that reference its object store.

   This reverts the values of `name` and `indexNames` returned by related `IDBObjectStore` objects.
   How is this observable?
   Although script cannot access an object store by using the `objectStore()` method on an `IDBTransaction` instance after the transaction is aborted, it can still have references to `IDBObjectStore` instances where the `name` and `indexNames` properties can be queried.

6. For each index handle handle associated with transaction, including those for indexes that were created or deleted during transaction:

   1. If handle’s index was not newly created during transaction, set handle’s name to its index's name.

   This reverts the value of `name` returned by related `IDBIndex` objects.
   How is this observable?
   Although script cannot access an index by using the `index()` method on an `IDBObjectStore` instance after the transaction is aborted, it can still have references to `IDBIndex` instances where the `name` property can be queried.

The `name` property of the `IDBDatabase` instance is not modified, even if the aborted upgrade transaction was creating a new database.

### 5.9. Firing a success event

To fire a success event at a request, run these steps:

1. Let event be the result of creating an event using `Event`.

2. Set event’s `type` attribute to "`success`".

3. Set event’s `bubbles` and `cancelable` attributes to false.

4. Let transaction be request’s transaction.

5. Let legacyOutputDidListenersThrowFlag be initially false.

6. If transaction’s state is inactive, then set transaction’s state to active.

7. Dispatch event at request with legacyOutputDidListenersThrowFlag.

8. If transaction’s state is active, then:

   1. Set transaction’s state to inactive.

   2. If legacyOutputDidListenersThrowFlag is true, then run abort a transaction with transaction and a newly created "`AbortError`" `DOMException`.

   3. If transaction’s request list is empty, then run commit a transaction with transaction.

### 5.10. Firing an error event

To fire an error event at a request, run these steps:

1. Let event be the result of creating an event using `Event`.

2. Set event’s `type` attribute to "`error`".

3. Set event’s `bubbles` and `cancelable` attributes to true.

4. Let transaction be request’s transaction.

5. Let legacyOutputDidListenersThrowFlag be initially false.

6. If transaction’s state is inactive, then set transaction’s state to active.

7. Dispatch event at request with legacyOutputDidListenersThrowFlag.

8. If transaction’s state is active, then:

   1. Set transaction’s state to inactive.

   2. If legacyOutputDidListenersThrowFlag is true, then run abort a transaction with transaction and a newly created "`AbortError`" `DOMException` and terminate these steps. This is done even if event’s canceled flag is false.

      This means that if an error event is fired and any of the event handlers throw an exception, transaction’s `error` property is set to an `AbortError` rather than request’s error, even if `preventDefault()` is never called.

   3. If event’s canceled flag is false, then run abort a transaction using transaction and request's error, and terminate these steps.

   4. If transaction’s request list is empty, then run commit a transaction with transaction.

### 5.11. Clone a value

To make a clone of value in targetRealm during transaction, run these steps:

1. Assert: transaction’s state is active.

2. Set transaction’s state to inactive.

   The transaction is made inactive so that getters or other side effects triggered by the cloning operation are unable to make additional requests against the transaction.

3. Let serialized be ? StructuredSerializeForStorage(value).

4. Let clone be ? StructuredDeserialize(serialized, targetRealm).

5. Set transaction’s state to active.

6. Return clone.

## 6. Database operations

This section describes various operations done on the data in object stores and indexes in a database. These operations are run by the steps to asynchronously execute a request.

Invocations of StructuredDeserialize() in the operation steps below can be asserted not to throw (as indicated by the ! prefix) because they operate only on previous output of StructuredSerializeForStorage().

### 6.1. Object Store Storage Operation

To store a record into an object store with store, value, an optional key, and a no-overwrite flag, run these steps:

1. If store uses a key generator, then:

   1. If key is undefined, then:

      1. Let key be the result of running generate a key for store.

      2. If key is failure, then this operation failed with a "`ConstraintError`" `DOMException`. Abort this algorithm without taking any further steps.

      3. If store also uses in-line keys, then run inject a key into a value using a key path with value, key and store’s key path.

   2. Otherwise, run possibly update the key generator for store with key.

2. If the no-overwrite flag was given to these steps and is true, and a record already exists in store with its key equal to key, then this operation failed with a "`ConstraintError`" `DOMException`. Abort this algorithm without taking any further steps.

3. If a record already exists in store with its key equal to key, then remove the record from store using delete records from an object store.

4. Store a record in store containing key as its key and ! StructuredSerializeForStorage(value) as its value. The record is stored in the object store’s list of records such that the list is sorted according to the key of the records in ascending order.

5. For each index which references store:

   1. Let index key be the result of running extract a key from a value using a key path with value, index’s key path, and index’s multiEntry flag.

   2. If index key is an exception, or invalid, or failure, take no further actions for index, and continue these steps for the next index.

      An exception thrown in this step is not rethrown.

   3. If index’s multiEntry flag is false, or if index key is not an array key, and if index already contains a record with key equal to index key, and index’s unique flag is true, then this operation failed with a "`ConstraintError`" `DOMException`. Abort this algorithm without taking any further steps.

   4. If index’s multiEntry flag is true and index key is an array key, and if index already contains a record with key equal to any of the subkeys of index key, and index’s unique flag is true, then this operation failed with a "`ConstraintError`" `DOMException`. Abort this algorithm without taking any further steps.

   5. If index’s multiEntry flag is false, or if index key is not an array key then store a record in index containing index key as its key and key as its value. The record is stored in index’s list of records such that the list is sorted primarily on the records keys, and secondarily on the records values, in ascending order.

   6. If index’s multiEntry flag is true and index key is an array key, then for each subkey of the subkeys of index key store a record in index containing subkey as its key and key as its value. The records are stored in index’s list of records such that the list is sorted primarily on the records keys, and secondarily on the records values, in ascending order.

      It is valid for there to be no subkeys. In this case no records are added to the index.
      Even if any member of subkeys is itself an array key, the member is used directly as the key for the index record. Nested array keys are not flattened or "unpacked" to produce multiple rows; only the outer-most array key is.

6. Return key.

### 6.2. Object Store Retrieval Operations

To retrieve a value from an object store with targetRealm, store and range, run these steps:

1. Let record be the first record in store’s list of records whose key is in range, if any.

2. If record was not found, return undefined.

3. Let serialized be of record’s value.

4. Return ! StructuredDeserialize(serialized, targetRealm).

To retrieve multiple values from an object store with targetRealm, store, range and optional count, run these steps:

1. If count is not given or is 0 (zero), let count be infinity.

2. Let records be a list containing the first count records in store’s list of records whose key is in range.

3. Let list be an empty list.

4. For each record of records:

   1. Let serialized be record’s value.

   2. Let entry be ! StructuredDeserialize(serialized, targetRealm).

   3. Append entry to list.

5. Return list converted to a sequence<any>.

To retrieve a key from an object store with store and range, run these steps:

1. Let record be the first record in store’s list of records whose key is in range, if any.

2. If record was not found, return undefined.

3. Return the result of running convert a key to a value with record’s key.

To retrieve multiple keys from an object store with store, range and optional count, run these steps:

1. If count is not given or is 0 (zero), let count be infinity.

2. Let records be a list containing the first count records in store’s list of records whose key is in range.

3. Let list be an empty list.

4. For each record of records:

   1. Let entry be the result of running convert a key to a value with record’s key.

   2. Append entry to list.

5. Return list converted to a sequence<any>.

### 6.3. Index Retrieval Operations

To retrieve a referenced value from an index with targetRealm, index and range, run these steps:

1. Let record be the first record in index’s list of records whose key is in range, if any.

2. If record was not found, return undefined.

3. Let serialized be record’s referenced value.

4. Return ! StructuredDeserialize(serialized, targetRealm).

To retrieve multiple referenced values from an index with targetRealm, index, range and optional count, run these steps:

1. If count is not given or is 0 (zero), let count be infinity.

2. Let records be a list containing the first count records in index’s list of records whose key is in range.

3. Let list be an empty list.

4. For each record of records:

   1. Let serialized be record’s referenced value.

   2. Let entry be ! StructuredDeserialize(serialized, targetRealm).

   3. Append entry to list.

5. Return list converted to a sequence<any>.

The values of an record in an index are the keys of records in the referenced object store.

To retrieve a value from an index with index and range, run these steps:

1. Let record be the first record in index’s list of records whose key is in range, if any.

2. If record was not found, return undefined.

3. Return the result of running convert a key to a value with record’s value.

To retrieve multiple values from an index with index, range and optional count, run these steps:

1. If count is not given or is 0 (zero), let count be infinity.

2. Let records be a list containing the first count records in index’s list of records whose key is in range.

3. Let list be an empty list.

4. For each record of records:

   1. Let entry be the result of running convert a key to a value with record’s value.

   2. Append entry to list.

5. Return list converted to a sequence<any>.

### 6.4. Object Store Deletion Operation

To delete records from an object store with store and range, run these steps:

1. Remove all records, if any, from store’s list of records with key in range.

2. For each index which references store, remove every record from index’s list of records whose value is in range, if any such records exist.

3. Return undefined.

### 6.5. Record Counting Operation

To count the records in a range with source and range, run these steps:

1. Let count be the number of records, if any, in source’s list of records with key in range.

2. Return count.

### 6.6. Object Store Clear Operation

To clear an object store with store, run these steps:

1. Remove all records from store.

2. In all indexes which reference store, remove all records.

3. Return undefined.

### 6.7. Cursor Iteration Operation

To iterate a cursor with targetRealm, cursor, an optional key and primaryKey to iterate to, and an optional count, run these steps:

1. Let source be cursor’s source.

2. Let direction be cursor’s direction.

3. Assert: if primaryKey is given, source is an index and direction is `"next"` or `"prev"`.

4. Let records be the list of records in source.

   records is always sorted in ascending key order. In the case of source being an index, records is secondarily sorted in ascending value order (where the value in an index is the key of the record in the referenced object store).

5. Let range be cursor’s range.

6. Let position be cursor’s position.

7. Let object store position be cursor’s object store position.

8. If count is not given, let count be 1.

9. While count is greater than 0:

   1. Switch on direction:

      `"next"`

        Let found record be the first record in records which satisfy all of the following requirements:

        - If key is defined, the record’s key is greater than or equal to key.

        - If primaryKey is defined, the record’s key is equal to key and the record’s value is greater than or equal to primaryKey, or the record’s key is greater than key.

        - If position is defined, and source is an object store, the record’s key is greater than position.

        - If position is defined, and source is an index, the record’s key is equal to position and the record’s value is greater than object store position or the record’s key is greater than position.

        - The record’s key is in range.

      `"nextunique"`

        Let found record be the first record in records which satisfy all of the following requirements:

        - If key is defined, the record’s key is greater than or equal to key.

        - If position is defined, the record’s key is greater than position.

        - The record’s key is in range.

      `"prev"`

        Let found record be the last record in records which satisfy all of the following requirements:

        - If key is defined, the record’s key is less than or equal to key.

        - If primaryKey is defined, the record’s key is equal to key and the record’s value is less than or equal to primaryKey, or the record’s key is less than key.

        - If position is defined, and source is an object store, the record’s key is less than position.

        - If position is defined, and source is an index, the record’s key is equal to position and the record’s value is less than object store position or the record’s key is less than position.

        - The record’s key is in range.

      `"prevunique"`

        Let temp record be the last record in records which satisfy all of the following requirements:

        - If key is defined, the record’s key is less than or equal to key.

        - If position is defined, the record’s key is less than position.

        - The record’s key is in range.

        If temp record is defined, let found record be the first record in records whose key is equal to temp record’s key.

        Iterating with `"prevunique"` visits the same records that `"nextunique"` visits, but in reverse order.

   2. If found record is not defined, then:

      1. Set cursor’s key to undefined.

      2. If source is an index, set cursor’s object store position to undefined.

      3. If cursor’s key only flag is false, set cursor’s value to undefined.

      4. Return null.

   3. Let position be found record’s key.

   4. If source is an index, let object store position be found record’s value.

   5. Decrease count by 1.

10. Set cursor’s position to position.

11. If source is an index, set cursor’s object store position to object store position.

12. Set cursor’s key to found record’s key.

13. If cursor’s key only flag is false, then:

    1. Let serialized be found record’s referenced value.

    2. Set cursor’s value to ! StructuredDeserialize(serialized, targetRealm)

14. Set cursor’s got value flag to true.

15. Return cursor.

## 7. ECMAScript binding

This section defines how key values defined in this specification are converted to and from ECMAScript values, and how they may be extracted from and injected into ECMAScript values using key paths. This section references types and algorithms and uses some algorithm conventions from the ECMAScript Language Specification. [ECMA-262] Conversions not detailed here are defined in [WEBIDL].

### 7.1. Extract a key from a value

To extract a key from a value using a key path with value, keyPath and an optional multiEntry flag, run the following steps. The result of these steps is a key, invalid, or failure, or the steps may throw an exception.

1. Let r be the result of running evaluate a key path on a value with value and keyPath. Rethrow any exceptions.

2. If r is failure, return failure.

3. Let key be the result of running convert a value to a key with r if the multiEntry flag is false, and the result of running convert a value to a multiEntry key with r otherwise. Rethrow any exceptions.

4. If key is invalid, return invalid.

5. Return key.

To evaluate a key path on a value with value and keyPath, run the following steps. The result of these steps is an ECMAScript value or failure, or the steps may throw an exception.

1. If keyPath is a list of strings, then:

   1. Let result be a new Array object created as if by the expression `[]`.

   2. Let i be 0.

   3. For each item of keyPath:

      1. Let key be the result of recursively running evaluate a key path on a value using item as keyPath and value as value.

      2. Assert: key is not an abrupt completion.

      3. If key is failure, abort the overall algorithm and return failure.

      4. Let p be ! ToString(i).

      5. Let status be CreateDataProperty(result, p, key).

      6. Assert: status is true.

      7. Increase i by 1.

   4. Return result.

      This will only ever "recurse" one level since key path sequences can’t ever be nested.

2. If keyPath is the empty string, return value and skip the remaining steps.

3. Let identifiers be the result of strictly splitting keyPath on U+002E FULL STOP characters (.).

4. For each identifier of identifiers, jump to the appropriate step below:

   If Type(value) is String, and identifier is "`length`"

     Let value be a Number equal to the number of elements in value.

   If value is an Array and identifier is "`length`"

     Let value be ! ToLength(! Get(value, "`length`")).

   If value is a `Blob` and identifier is "`size`"

     Let value be a Number equal to value’s `size`.

   If value is a `Blob` and identifier is "`type`"

     Let value be a String equal to value’s `type`.

   If value is a `File` and identifier is "`name`"

     Let value be a String equal to value’s `name`.

   If value is a `File` and identifier is "`lastModified`"

     Let value be a Number equal to value’s `lastModified`.

   Otherwise

     1. If Type(value) is not Object, return failure.

     2. Let hop be ! HasOwnProperty(value, identifier).

     3. If hop is false, return failure.

     4. Let value be ! Get(value, identifier).

     5. If value is undefined, return failure.

5. Assert: value is not an abrupt completion.

6. Return value.

Assertions can be made in the above steps because this algorithm is only applied to values that are the output of StructuredDeserialize and only access "own" properties.

### 7.2. Inject a key into a value

The key paths used in this section are always strings and never sequences, since it is not possible to create a object store which has a key generator and also has a key path that is a sequence.

To check that a key could be injected into a value with value and a keyPath, run the following steps. The result of these steps is either true or false.

1. Let identifiers be the result of strictly splitting keyPath on U+002E FULL STOP characters (.).

2. Assert: identifiers is not empty.

3. Remove the last item of identifiers.

4. For each remaining identifier of identifiers, if any:

   1. If value is not an Object or an Array, return false.

   2. Let hop be ! HasOwnProperty(value, identifier).

   3. If hop is false, return true.

   4. Let value be ! Get(value, identifier).

5. Return true if value is an Object or an Array, or false otherwise.

Assertions can be made in the above steps because this algorithm is only applied to values that are the output of StructuredDeserialize.

To inject a key into a value using a key path with value, a key and a keyPath, run these steps:

1. Let identifiers be the result of strictly splitting keyPath on U+002E FULL STOP characters (.).

2. Assert: identifiers is not empty.

3. Let last be the last item of identifiers and remove it from the list.

4. For each remaining identifier of identifiers:

   1. Assert: value is an Object or an Array.

   2. Let hop be ! HasOwnProperty(value, identifier).

   3. If hop is false, then:

      1. Let o be a new Object created as if by the expression `({})`.

      2. Let status be CreateDataProperty(value, identifier, o).

      3. Assert: status is true.

   4. Let value be ! Get(value, identifier).

5. Assert: value is an Object or an Array.

6. Let keyValue be the result of running convert a key to a value with key.

7. Let status be CreateDataProperty(value, last, keyValue).

8. Assert: status is true.

Assertions can be made in the above steps because this algorithm is only applied to values that are the output of StructuredDeserialize, and the steps to check that a key could be injected into a value have been run.

### 7.3. Convert a key to a value

To convert a key to a value with key, run the following steps. The steps return an ECMAScript value.

1. Let type be key’s type.

2. Let value be key’s value.

3. Switch on type:

   number

     Return an ECMAScript Number value equal to value

   string

     Return an ECMAScript String value equal to value

   date

     1. Let date be the result of executing the ECMAScript Date constructor with the single argument value.

     2. Assert: date is not an abrupt completion.

     3. Return date.

   binary

     1. Let len be value’s length.

     2. Let buffer be the result of executing the ECMAScript ArrayBuffer constructor with len.

     3. Assert: buffer is not an abrupt completion.

     4. Set the entries in buffer’s [[ArrayBufferData]] internal slot to the entries in value.

     5. Return buffer.

   array

     1. Let array be the result of executing the ECMAScript Array constructor with no arguments.

     2. Assert: array is not an abrupt completion.

     3. Let len be value’s size.

     4. Let index be 0.

     5. While index is less than len:

        1. Let entry be the result of running convert a key to a value with value[index].

        2. Let status be CreateDataProperty(array, index, entry).

        3. Assert: status is true.

        4. Increase index by 1.

     6. Return array.

### 7.4. Convert a value to a key

To convert a value to a key with an ECMAScript value input, and an optional set seen, run the following steps. The result of these steps is a key or invalid, or the steps may throw an exception.

1. If seen was not given, then let seen be a new empty set.

2. If seen contains input, then return invalid.

3. Jump to the appropriate step below:

   If Type(input) is Number

     1. If input is NaN then return invalid.

     2. Otherwise, return a new key with type number and value input.

   If input is a Date (has a [[DateValue]] internal slot)

     1. Let ms be the value of input’s [[DateValue]] internal slot.

     2. If ms is NaN then return invalid.

     3. Otherwise, return a new key with type date and value ms.

   If Type(input) is String

     1. Return a new key with type string and value input.

   If input is a buffer source type

     1. Let bytes be the result of running get a copy of the bytes held by the buffer source input. Rethrow any exceptions.

     2. Return a new key with type binary and value bytes.

   If input is an Array exotic object

     1. Let len be ? ToLength( ? Get(input, "`length`")).

     2. Append input to seen.

     3. Let keys be a new empty list.

     4. Let index be 0.

     5. While index is less than len:

        1. Let hop be ? HasOwnProperty(input, index).

        2. If hop is false, return invalid.

        3. Let entry be ? Get(input, index).

        4. Let key be the result of running convert a value to a key with arguments entry and seen.

        5. ReturnIfAbrupt(key).

        6. If key is invalid abort these steps and return invalid.

        7. Append key to keys.

        8. Increase index by 1.

     6. Return a new array key with value keys.

   Otherwise

     Return invalid.

To convert a value to a multiEntry key with an ECMAScript value input, run the following steps. The result of these steps is a key or invalid, or the steps may throw an exception.

1. If input is an Array exotic object, then:

   1. Let len be ? ToLength( ? Get(input, "`length`")).

   2. Let seen be a new set containing only input.

   3. Let keys be a new empty list.

   4. Let index be 0.

   5. While index is less than len:

      1. Let entry be Get(input, index).

      2. If entry is not an abrupt completion, then:

         1. Let key be the result of running convert a value to a key with arguments entry and seen.

         2. If key is not invalid or an abrupt completion, and there is no item in keys equal to key, then append key to keys.

      3. Increase index by 1.

   6. Return a new array key with value set to keys.

2. Otherwise, return the result of running convert a value to a key with argument input. Rethrow any exceptions.

These steps are similar to those to convert a value to a key but if the top-level value is an Array then members which can not be converted to keys are ignored, and duplicates are removed.

For example, the value `[10, 20, null, 30, 20]` is converted to an array key with subkeys 10, 20, 30.

## 8. Privacy Considerations

This section is non-normative.

### 8.1. User tracking

A third-party host (or any object capable of getting content distributed to multiple sites) could use a unique identifier stored in its client-side database to track a user across multiple sessions, building a profile of the user’s activities. In conjunction with a site that is aware of the user’s real id object (for example an e-commerce site that requires authenticated credentials), this could allow oppressive groups to target individuals with greater accuracy than in a world with purely anonymous Web usage.

There are a number of techniques that can be used to mitigate the risk of user tracking:

Blocking third-party storage

  User agents may restrict access to the database objects to scripts originating at the domain of the top-level document of the browsing context, for instance denying access to the API for pages from other domains running in `iframe`s.

Expiring stored data

  User agents may automatically delete stored data after a period of time.

  This can restrict the ability of a site to track a user, as the site would then only be able to track the user across multiple sessions when she authenticates with the site itself (e.g. by making a purchase or logging in to a service).

  However, this also puts the user’s data at risk.

Treating persistent storage as cookies

  User agents should present the database feature to the user in a way that associates them strongly with HTTP session cookies. [COOKIES]

  This might encourage users to view such storage with healthy suspicion.

Site-specific safe-listing of access to databases

  User agents may require the user to authorize access to databases before a site can use the feature.

Origin-tracking of stored data

  User agents may record the origins of sites that contained content from third-party origins that caused data to be stored.

  If this information is then used to present the view of data currently in persistent storage, it would allow the user to make informed decisions about which parts of the persistent storage to prune. Combined with a blocklist ("delete this data and prevent this domain from ever storing data again"), the user can restrict the use of persistent storage to sites that she trusts.

Shared blocklists

  User agents may allow users to share their persistent storage domain blocklists.

  This would allow communities to act together to protect their privacy.

While these suggestions prevent trivial use of this API for user tracking, they do not block it altogether. Within a single domain, a site can continue to track the user during a session, and can then pass all this information to the third party along with any identifying information (names, credit card numbers, addresses) obtained by the site. If a third party cooperates with multiple sites to obtain such information, a profile can still be created.

However, user tracking is to some extent possible even with no cooperation from the user agent whatsoever, for instance by using session identifiers in URLs, a technique already commonly used for innocuous purposes but easily repurposed for user tracking (even retroactively). This information can then be shared with other sites, using visitors' IP addresses and other user-specific data (e.g. user-agent headers and configuration settings) to combine separate sessions into coherent user profiles.

### 8.2. Cookie resurrection

If the user interface for persistent storage presents data in the persistent storage features described in this specification separately from data in HTTP session cookies, then users are likely to delete data in one and not the other. This would allow sites to use the two features as redundant backup for each other, defeating a user’s attempts to protect his privacy.

### 8.3. Sensitivity of data

User agents should treat persistently stored data as potentially sensitive; it is quite possible for e-mails, calendar appointments, health records, or other confidential documents to be stored in this mechanism.

To this end, user agents should ensure that when deleting data, it is promptly deleted from the underlying storage.

## 9. Security Considerations

### 9.1. DNS spoofing attacks

Because of the potential for DNS spoofing attacks, one cannot guarantee that a host claiming to be in a certain domain really is from that domain. To mitigate this, pages can use TLS. Pages using TLS can be sure that only pages using TLS that have certificates identifying them as being from the same domain can access their databases.

### 9.2. Cross-directory attacks

Different authors sharing one host name, for example users hosting content on `geocities.com`, all share one set of databases.

There is no feature to restrict the access by pathname. Authors on shared hosts are therefore recommended to avoid using these features, as it would be trivial for other authors to read the data and overwrite it.

Even if a path-restriction feature was made available, the usual DOM scripting security model would make it trivial to bypass this protection and access the data from any path.

### 9.3. Implementation risks

The two primary risks when implementing these persistent storage features are letting hostile sites read information from other domains, and letting hostile sites write information that is then read from other domains.

Letting third-party sites read data that is not supposed to be read from their domain causes information leakage, For example, a user’s shopping wish list on one domain could be used by another domain for targeted advertising; or a user’s work-in-progress confidential documents stored by a word-processing site could be examined by the site of a competing company.

Letting third-party sites write data to the persistent storage of other domains can result in information spoofing, which is equally dangerous. For example, a hostile site could add records to a user’s wish list; or a hostile site could set a user’s session identifier to a known ID that the hostile site can then use to track the user’s actions on the victim site.

Thus, strictly following the origin model described in this specification is important for user security.

If origins or database names are used to construct paths for persistence to a file system they must be appropriately escaped to prevent an adversary from accessing information from other origins using relative paths such as "`../`".

### 9.4. Persistence risks

Practical implementations will persist data to a non-volatile storage medium. Data will be serialized when stored and deserialized when retrieved, although the details of the serialization format will be user-agent specific. User agents are likely to change their serialization format over time. For example, the format may be updated to handle new data types, or to improve performance. To satisfy the operational requirements of this specification, implementations must therefore handle older serialization formats in some way. Improper handling of older data can result in security issues. In addition to basic serialization concerns, serialized data could encode assumptions which are not valid in newer versions of the user agent.

A practical example of this is the RegExp type. The StructuredSerializeForStorage operation allows serializing RegExp objects. A typical user agent will compile a regular expression into native machine instructions, with assumptions about how the input data is passed and results returned. If this internal state was serialized as part of the data stored to the database, various problems could arise when the internal representation was later deserialized. For example, the means by which data was passed into the code could have changed. Security bugs in the compiler output could have been identified and fixed in updates to the user agent, but remain in the serialized internal state.

User agents must identify and handle older data appropriately. One approach is to include version identifiers in the serialization format, and to reconstruct any internal state from script-visible state when older data is encountered.

## 10. Revision History

This section is non-normative.

The following is an informative summary of the changes since the last publication of this specification. A complete revision history can be found here. For the revision history of the first edition, see that document’s Revision History. For the revision history of the second edition, see that document’s Revision History.

- The cleanup Indexed Database transactions algorithm now returns a value for integration with other specs. (PR #232)

- Updated partial interface definition since `WindowOrWorkerGlobalScope` is now a `mixin` (PR #238).

- Added `databases()` method. (Issue #31)

- Added `commit()` method. (Issue #234)

- Added `request` attribute. (Issue #255)

- Removed handling for nonstandard `lastModifiedDate` property of `File` objects. (Issue #215)

- Remove escaping `includes()` method. (Issue #294)

- Restrict array keys to Array exotic objects (i.e. disallow proxies). (Issue #309

- Transactions are now temporarily made inactive during clone operations.

## 11. Acknowledgements

This section is non-normative.

Special thanks to Nikunj Mehta, the original author of the first edition, and Jonas Sicking, Eliot Graff, Andrei Popescu, and Jeremy Orlow, additional editors of the first edition.

Garret Swart was extremely influential in the design of this specification.

Thanks to Tab Atkins, Jr. for creating and maintaining Bikeshed, the specification authoring tool used to create this document, and for his general authoring advice.

Special thanks to Chris Anderson, Jake Archibald, Yannic Bonenberger, Andreas Butler, Pablo Castro, Victor Costan, Kristof Degrave, Domenic Denicola, Jake Drew, Ben Dilts, João Eiras, Alec Flett, Dana Florescu, David Grogan, Israel Hilerio, Jerome Hode, Kyle Huey, Philip Jägenstedt, Laxminarayan G Kamath A, Anne van Kesteren, Adam Klein, Marijn Kruisselbrink, Tobie Langel, Kang-Hao Lu, Andrea Marchesini, Josh Matthews, Glenn Maynard, Isiah Meadows, Ms2ger, Odin Omdal, Danillo Paiva, Olli Pettay, Addison Phillips, Simon Pieters, Anthony Ramine, Yonathan Randolph, Arun Ranganathan, Kagami Sascha Rosylight, Margo Seltzer, Maciej Stachowiak, Andrew Sutherland, Yaron Tausky, Bevis Tseng, Ben Turner, Kyaw Tun, Hans Wennborg, Shawn Wilsher, Brett Zamir, Boris Zbarsky, Zhiqiang Zhang, and Kris Zyp, all of whose feedback and suggestions have led to improvements to this specification.

## Conformance

### Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with `class="example"`, like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with `class="note"`, like this:

Note, this is an informative note.

### Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

.

## Index

### Terms defined by this specification

- abort
  - dfn for transaction, in §2.7.1
  - event for transaction, in §2.7.2
- abort(), in §4.9
- abort an upgrade transaction, in §5.8
- abort a transaction, in §5.5
- aborted, in §2.7.1
- aborting, in §2.7.1
- active, in §2.7.1
- add or put, in §4.5
- add(value), in §4.5
- add(value, key), in §4.5
- advance(count), in §4.8
- array key, in §2.4
- ascending, in §2.4
- asynchronously execute a request, in §5.6
- autoIncrement
  - attribute for IDBObjectStore, in §4.5
  - dict-member for IDBObjectStoreParameters, in §4.4
- blocked, in §2.8.1
- bound(lower, upper), in §4.7
- bound(lower, upper, lowerOpen), in §4.7
- bound(lower, upper, lowerOpen, upperOpen), in §4.7
- check that a key could be injected into a value, in §7.2
- cleanup event loop, in §2.7
- cleanup Indexed Database transactions, in §2.7.1
- clear(), in §4.5
- clear an object store, in §6.6
- clone, in §5.11
- close(), in §4.4
- close a database connection, in §5.2
- closed, in §2.1.1
- close pending flag, in §2.1.1
- cmp(first, second), in §4.3
- commit, in §2.7.1
- commit(), in §4.9
- commit a transaction, in §5.4
- committed, in §2.7.1
- committing, in §2.7.1
- compare two keys, in §2.4
- complete, in §2.7.2
- connected, in §2.1.1
- connection
  - definition of, in §2.1.1
  - dfn for transaction, in §2.7
- connection queue, in §2.8.1
- constructor(type), in §4.2
- constructor(type, eventInitDict), in §4.2
- containing only, in §2.9
- continue(), in §4.8
- continue(key), in §4.8
- continuePrimaryKey(key, primaryKey), in §4.8
- convert a key to a value, in §7.3
- convert a value to a key, in §7.4
- convert a value to a key range, in §2.9
- convert a value to a multiEntry key, in §7.4
- count()
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- count(query)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- count the records in a range, in §6.5
- created, in §2.7.1
- createIndex(name, keyPath), in §4.5
- createIndex(name, keyPath, options), in §4.5
- createObjectStore(name), in §4.4
- createObjectStore(name, options), in §4.4
- current number, in §2.11
- cursor, in §2.10
- database, in §2.1
- database access task source, in §4
- databases(), in §4.3
- db, in §4.9
- delete(), in §4.8
- delete a database, in §5.3
- deleteDatabase(name), in §4.3
- deleteIndex(name), in §4.5
- deleteObjectStore(name), in §4.4
- delete(query), in §4.5
- delete records from an object store, in §6.4
- direction
  - attribute for IDBCursor, in §4.8
  - dfn for cursor, in §2.10
- "done", in §4.1
- done flag, in §2.8
- effective key, in §2.10
- effective object store, in §2.10
- equal to, in §2.4
- error
  - attribute for IDBRequest, in §4.1
  - attribute for IDBTransaction, in §4.9
  - dfn for request, in §2.8
  - dfn for transaction, in §2.7
  - event for request, in §2.8
- evaluate a key path on a value, in §7.1
- extract a key from a value using a key path, in §7.1
- finished, in §2.7.1
- fire an error event, in §5.10
- fire a success event, in §5.9
- fire a version change event, in §4.2
- generate a key, in §2.11
- getAll()
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- getAllKeys()
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- getAllKeys(query)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- getAllKeys(query, count)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- getAll(query)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- getAll(query, count)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- getKey(query)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- get(query)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- got value flag, in §2.10
- greater than, in §2.4
- IDBCursor, in §4.8
- IDBCursorDirection, in §4.8
- IDBCursorWithValue, in §4.8
- IDBDatabase, in §4.4
- IDBDatabaseInfo, in §4.3
- IDBFactory, in §4.3
- IDBIndex, in §4.6
- IDBIndexParameters, in §4.5
- IDBKeyRange, in §4.7
- IDBObjectStore, in §4.5
- IDBObjectStoreParameters, in §4.4
- IDBOpenDBRequest, in §4.1
- IDBRequest, in §4.1
- IDBRequestReadyState, in §4.1
- IDBTransaction, in §4.9
- IDBTransactionMode, in §4.9
- IDBVersionChangeEvent, in §4.2
- IDBVersionChangeEventInit, in §4.2
- IDBVersionChangeEvent(type), in §4.2
- IDBVersionChangeEvent(type, eventInitDict), in §4.2
- identifier, in §2.5
- in, in §2.9
- inactive, in §2.7.1
- includes(key), in §4.7
- index
  - definition of, in §2.6
  - dfn for index-handle, in §2.6.1
- indexedDB, in §4.3
- index handle, in §2.6.1
- index(name), in §4.5
- indexNames, in §4.5
- index set, in §2.2.1
- inject a key into a value using a key path, in §7.2
- in-line keys, in §2.2
- iterate a cursor, in §6.7
- key
  - attribute for IDBCursor, in §4.8
  - definition of, in §2.4
  - dfn for cursor, in §2.10
- key generator, in §2.11
- key only flag, in §2.10
- key path
  - definition of, in §2.5
  - dfn for index, in §2.6
  - dfn for object-store, in §2.2
- keyPath
  - attribute for IDBIndex, in §4.6
  - attribute for IDBObjectStore, in §4.5
  - dict-member for IDBObjectStoreParameters, in §4.4
- key range, in §2.9
- keys, in §2.6
- less than, in §2.4
- lifetime, in §2.7.1
- list of records
  - dfn for index, in §2.6
  - dfn for object-store, in §2.2
- lower, in §4.7
- lower bound, in §2.9
- lowerBound(lower), in §4.7
- lowerBound(lower, open), in §4.7
- lowerOpen, in §4.7
- lower open flag, in §2.9
- mode
  - attribute for IDBTransaction, in §4.9
  - dfn for transaction, in §2.7
- multiEntry
  - attribute for IDBIndex, in §4.6
  - dict-member for IDBIndexParameters, in §4.5
- multiEntry flag, in §2.6
- name
  - attribute for IDBDatabase, in §4.4
  - attribute for IDBIndex, in §4.6
  - attribute for IDBObjectStore, in §4.5
  - definition of, in §2
  - dfn for database, in §2.1
  - dfn for index, in §2.6
  - dfn for index-handle, in §2.6.1
  - dfn for object-store, in §2.2
  - dfn for object-store-handle, in §2.2.1
  - dict-member for IDBDatabaseInfo, in §4.3
- newVersion
  - attribute for IDBVersionChangeEvent, in §4.2
  - dict-member for IDBVersionChangeEventInit, in §4.2
- "next", in §4.8
- "nextunique", in §4.8
- object store
  - definition of, in §2.2
  - dfn for object-store-handle, in §2.2.1
- objectStore, in §4.6
- object store handle
  - definition of, in §2.2.1
  - dfn for index-handle, in §2.6.1
- objectStore(name), in §4.9
- objectStoreNames
  - attribute for IDBDatabase, in §4.4
  - attribute for IDBTransaction, in §4.9
- object store position, in §2.10
- object store set, in §2.1.1
- oldVersion
  - attribute for IDBVersionChangeEvent, in §4.2
  - dict-member for IDBVersionChangeEventInit, in §4.2
- onabort
  - attribute for IDBDatabase, in §4.4
  - attribute for IDBTransaction, in §4.9
- onblocked, in §4.1
- onclose, in §4.4
- oncomplete, in §4.9
- onerror
  - attribute for IDBDatabase, in §4.4
  - attribute for IDBRequest, in §4.1
  - attribute for IDBTransaction, in §4.9
- only(value), in §4.7
- onsuccess, in §4.1
- onupgradeneeded, in §4.1
- onversionchange, in §4.4
- open a database, in §5.1
- openCursor()
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- openCursor(query)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- openCursor(query, direction)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- openKeyCursor()
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- openKeyCursor(query)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- openKeyCursor(query, direction)
  - method for IDBIndex, in §4.6
  - method for IDBObjectStore, in §4.5
- open(name), in §4.3
- open(name, version), in §4.3
- open request, in §2.8.1
- out-of-line keys, in §2.2
- "pending", in §4.1
- placed, in §2.8
- position, in §2.10
- possibly update the key generator, in §2.11
- "prev", in §4.8
- "prevunique", in §4.8
- primaryKey, in §4.8
- processed, in §2.8
- processed flag, in §2.8
- put(value), in §4.5
- put(value, key), in §4.5
- range, in §2.10
- "readonly", in §4.9
- read-only transaction, in §2.7
- "readwrite", in §4.9
- read/write transaction, in §2.7
- readyState, in §4.1
- record, in §2.2
- records, in §2.6
- referenced, in §2.6
- referenced value, in §2.6
- references, in §2.6
- request
  - attribute for IDBCursor, in §4.8
  - definition of, in §2.8
  - dfn for cursor, in §2.10
- request list, in §2.7
- result
  - attribute for IDBRequest, in §4.1
  - dfn for request, in §2.8
- retrieve a key from an object store, in §6.2
- retrieve a referenced value from an index, in §6.3
- retrieve a value from an index, in §6.3
- retrieve a value from an object store, in §6.2
- retrieve multiple keys from an object store, in §6.2
- retrieve multiple referenced values from an index, in §6.3
- retrieve multiple values from an index, in §6.3
- retrieve multiple values from an object store, in §6.2
- run an upgrade transaction, in §5.7
- scope, in §2.7
- sorted name list, in §2
- source
  - attribute for IDBCursor, in §4.8
  - attribute for IDBRequest, in §4.1
  - dfn for cursor, in §2.10
  - dfn for request, in §2.8
- start, in §2.7.1
- started, in §2.7.1
- state, in §2.7.1
- store a record into an object store, in §6.1
- subkeys, in §2.4
- success, in §2.8
- Transaction, in §2.7
- transaction
  - attribute for IDBObjectStore, in §4.5
  - attribute for IDBRequest, in §4.1
  - dfn for cursor, in §2.10
  - dfn for index-handle, in §2.6.1
  - dfn for object-store-handle, in §2.2.1
  - dfn for request, in §2.8
- transaction(storeNames), in §4.4
- transaction(storeNames, mode), in §4.4
- type, in §2.4
- unbounded key range, in §2.9
- unique
  - attribute for IDBIndex, in §4.6
  - dict-member for IDBIndexParameters, in §4.5
- unique flag, in §2.6
- update(value), in §4.8
- upgradeneeded, in §2.8.1
- upgrade transaction
  - definition of, in §2.7.3
  - dfn for database, in §2.1
- upper, in §4.7
- upper bound, in §2.9
- upperBound(upper), in §4.7
- upperBound(upper, open), in §4.7
- upperOpen, in §4.7
- upper open flag, in §2.9
- valid key path, in §2.5
- value
  - attribute for IDBCursorWithValue, in §4.8
  - definition of, in §2.3
  - dfn for cursor, in §2.10
  - dfn for key, in §2.4
- values, in §2.6
- version
  - attribute for IDBDatabase, in §4.4
  - dfn for connection, in §2.1.1
  - dfn for database, in §2.1
  - dict-member for IDBDatabaseInfo, in §4.3
- "versionchange", in §4.9
- versionchange, in §2.1.1

https://dom.spec.whatwg.org/#event Referenced in:

- 4.2. Event interfaces
- 5.9. Firing a success event
- 5.10. Firing an error event

https://dom.spec.whatwg.org/#dictdef-eventinit Referenced in:

- 4.2. Event interfaces

https://dom.spec.whatwg.org/#eventtarget Referenced in:

- 4.1. The IDBRequest interface
- 4.4. The IDBDatabase interface
- 4.9. The IDBTransaction interface

https://dom.spec.whatwg.org/#dom-event-bubbles Referenced in:

- 4.2. Event interfaces
- 4.3. The IDBFactory interface (2)
- 5.5. Aborting a transaction (2)
- 5.9. Firing a success event
- 5.10. Firing an error event

https://dom.spec.whatwg.org/#dom-event-cancelable Referenced in:

- 4.2. Event interfaces
- 4.3. The IDBFactory interface (2)
- 5.5. Aborting a transaction
- 5.9. Firing a success event
- 5.10. Firing an error event

https://dom.spec.whatwg.org/#canceled-flag Referenced in:

- 5.10. Firing an error event (2)

https://dom.spec.whatwg.org/#concept-event-create Referenced in:

- 4.2. Event interfaces
- 5.9. Firing a success event
- 5.10. Firing an error event

https://dom.spec.whatwg.org/#concept-event-dispatch Referenced in:

- 2.7.1. Transaction Lifecycle
- 4.2. Event interfaces
- 5.9. Firing a success event
- 5.10. Firing an error event

https://dom.spec.whatwg.org/#concept-event Referenced in:

- 2.7.1. Transaction Lifecycle

https://dom.spec.whatwg.org/#concept-event-fire Referenced in:

- 4.3. The IDBFactory interface (2) (3)
- 5.2. Closing a database
- 5.4. Committing a transaction
- 5.5. Aborting a transaction (2)

https://dom.spec.whatwg.org/#get-the-parent Referenced in:

- 2.1.1. Database Connection
- 2.7. Transactions
- 2.8. Requests
- 2.8.1. Open Requests

https://dom.spec.whatwg.org/#dom-event-preventdefault Referenced in:

- 5.10. Firing an error event

https://dom.spec.whatwg.org/#dom-event-type Referenced in:

- 4.2. Event interfaces
- 5.9. Firing a success event
- 5.10. Firing an error event

https://tc39.github.io/ecma262/#sec-algorithm-conventions Referenced in:

- 5.11. Clone a value (2)
- 6. Database operations
- 6.1. Object Store Storage Operation
- 6.2. Object Store Retrieval Operations (2)
- 6.3. Index Retrieval Operations (2)
- 6.7. Cursor Iteration Operation
- 7.1. Extract a key from a value (2) (3) (4) (5)
- 7.2. Inject a key into a value (2) (3) (4)
- 7.4. Convert a value to a key (2) (3) (4) (5) (6)

https://tc39.github.io/ecma262/#sec-algorithm-conventions Referenced in:

- 5.11. Clone a value (2)
- 6. Database operations
- 6.1. Object Store Storage Operation
- 6.2. Object Store Retrieval Operations (2)
- 6.3. Index Retrieval Operations (2)
- 6.7. Cursor Iteration Operation
- 7.1. Extract a key from a value (2) (3) (4) (5)
- 7.2. Inject a key into a value (2) (3) (4)
- 7.4. Convert a value to a key (2) (3) (4) (5) (6)

https://tc39.github.io/ecma262/#sec-completion-record-specification-type Referenced in:

- 7.1. Extract a key from a value (2)
- 7.3. Convert a key to a value (2) (3)
- 7.4. Convert a value to a key (2)

https://tc39.github.io/ecma262/#sec-array-objects Referenced in:

- 2. Constructs
- 2.3. Values
- 2.4. Keys
- 2.5. Key Path
- 4.5. The IDBObjectStore interface (2) (3)
- 4.6. The IDBIndex interface (2) (3)
- 4.8. The IDBCursor interface (2)
- 7.1. Extract a key from a value (2)
- 7.2. Inject a key into a value (2) (3) (4)
- 7.4. Convert a value to a key

https://tc39.github.io/ecma262/#array-exotic-objects Referenced in:

- 7.4. Convert a value to a key (2)
- 10. Revision History

https://tc39.github.io/ecma262/#sec-array.prototype.sort Referenced in:

- 2. Constructs

https://tc39.github.io/ecma262/#sec-arraybuffer-objects Referenced in:

- 2.4. Keys

https://tc39.github.io/ecma262/#sec-createdataproperty Referenced in:

- 7.1. Extract a key from a value
- 7.2. Inject a key into a value (2)
- 7.3. Convert a key to a value

https://tc39.github.io/ecma262/#current-realm Referenced in:

- 4.5. The IDBObjectStore interface (2) (3) (4)
- 4.6. The IDBIndex interface (2) (3) (4)
- 4.8. The IDBCursor interface (2) (3)

https://tc39.github.io/ecma262/#sec-date-objects Referenced in:

- 2.3. Values
- 2.4. Keys
- 4.8. The IDBCursor interface (2)
- 7.4. Convert a value to a key

https://tc39.github.io/ecma262/#sec-get-o-p Referenced in:

- 7.1. Extract a key from a value (2)
- 7.2. Inject a key into a value (2)
- 7.4. Convert a value to a key (2) (3) (4)

https://tc39.github.io/ecma262/#sec-hasownproperty Referenced in:

- 7.1. Extract a key from a value
- 7.2. Inject a key into a value (2)
- 7.4. Convert a value to a key

https://tc39.github.io/ecma262/#prod-IdentifierName Referenced in:

- 2.5. Key Path

https://tc39.github.io/ecma262/#sec-terms-and-definitions-number-type Referenced in:

- 2.4. Keys
- 2.11. Key Generators

https://tc39.github.io/ecma262/#sec-object-objects Referenced in:

- 2.3. Values
- 7.2. Inject a key into a value (2) (3) (4) (5)

https://tc39.github.io/ecma262/#realm Referenced in:

- 4.5. The IDBObjectStore interface
- 4.8. The IDBCursor interface

https://tc39.github.io/ecma262/#sec-list-and-record-specification-type Referenced in:

- 2.3. Values

https://tc39.github.io/ecma262/#sec-regexp-regular-expression-objects Referenced in:

- 9.4. Persistence risks (2)

https://tc39.github.io/ecma262/#sec-returnifabrupt Referenced in:

- 7.4. Convert a value to a key

https://tc39.github.io/ecma262/#sec-terms-and-definitions-string-type Referenced in:

- 2. Constructs (2)
- 2.3. Values
- 2.4. Keys
- 2.5. Key Path

https://tc39.github.io/ecma262/#sec-tolength Referenced in:

- 7.1. Extract a key from a value
- 7.4. Convert a value to a key

https://tc39.github.io/ecma262/#sec-tostring Referenced in:

- 7.1. Extract a key from a value

https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values Referenced in:

- 7.1. Extract a key from a value (2)
- 7.4. Convert a value to a key (2)

https://tc39.github.io/ecma262/#sec-native-error-types-used-in-this-standard-typeerror Referenced in:

- 4.3. The IDBFactory interface
- 4.4. The IDBDatabase interface
- 4.8. The IDBCursor interface

https://tc39.github.io/ecma262/#sec-typedarray-objects Referenced in:

- 2.4. Keys

https://w3c.github.io/FileAPI/#dfn-Blob Referenced in:

- 2.3. Values
- 2.5. Key Path
- 7.1. Extract a key from a value (2)

https://w3c.github.io/FileAPI/#dfn-file Referenced in:

- 2.3. Values
- 2.5. Key Path
- 7.1. Extract a key from a value (2)
- 10. Revision History

https://w3c.github.io/FileAPI/#dfn-lastModified Referenced in:

- 2.5. Key Path
- 7.1. Extract a key from a value

https://w3c.github.io/FileAPI/#dfn-name Referenced in:

- 2.5. Key Path
- 7.1. Extract a key from a value

https://w3c.github.io/FileAPI/#dfn-size Referenced in:

- 2.5. Key Path
- 7.1. Extract a key from a value

https://w3c.github.io/FileAPI/#dfn-type Referenced in:

- 2.5. Key Path
- 7.1. Extract a key from a value

https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#domstringlist Referenced in:

- 4.4. The IDBDatabase interface (2)
- 4.5. The IDBObjectStore interface (2)
- 4.9. The IDBTransaction interface (2) (3)

https://html.spec.whatwg.org/multipage/dom.html#document Referenced in:

- 2.1.1. Database Connection

https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler Referenced in:

- 4.1. The IDBRequest interface (2) (3) (4)
- 4.4. The IDBDatabase interface (2) (3) (4)
- 4.9. The IDBTransaction interface (2) (3)

https://html.spec.whatwg.org/multipage/canvas.html#imagedata Referenced in:

- 2.3. Values

https://html.spec.whatwg.org/multipage/structured-data.html#structureddeserialize Referenced in:

- 5.11. Clone a value
- 6. Database operations
- 6.2. Object Store Retrieval Operations (2)
- 6.3. Index Retrieval Operations (2)
- 6.7. Cursor Iteration Operation
- 7.1. Extract a key from a value
- 7.2. Inject a key into a value (2)

https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeforstorage Referenced in:

- 2.3. Values
- 2.5. Key Path
- 5.11. Clone a value
- 6. Database operations
- 6.1. Object Store Storage Operation
- 9.4. Persistence risks

https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope Referenced in:

- 4.3. The IDBFactory interface
- 10. Revision History

https://html.spec.whatwg.org/multipage/browsers.html#browsing-context Referenced in:

- 2.8.1. Open Requests

https://html.spec.whatwg.org/multipage/indices.html#event-close Referenced in:

- 4.4. The IDBDatabase interface
- 5.2. Closing a database (2)

https://html.spec.whatwg.org/multipage/origin.html#dom-document-domain Referenced in:

- 2.1.1. Database Connection

https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-idl-attributes Referenced in:

- 4.1. The IDBRequest interface

https://html.spec.whatwg.org/multipage/webappapis.html#event-loop Referenced in:

- 2.7. Transactions
- 2.7.1. Transaction Lifecycle (2)
- 2.8.1. Open Requests (2)
- 4.4. The IDBDatabase interface

https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel Referenced in:

- 4.3. The IDBFactory interface (2) (3)
- 5.4. Committing a transaction
- 5.6. Asynchronously executing a request

https://html.spec.whatwg.org/multipage/origin.html#concept-origin-opaque Referenced in:

- 4.3. The IDBFactory interface (2) (3)

https://html.spec.whatwg.org/multipage/origin.html#concept-origin Referenced in:

- 2.1. Database (2)
- 2.1.1. Database Connection
- 2.8.1. Open Requests
- 4.3. The IDBFactory interface (2) (3)
- 8.1. User tracking

https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task Referenced in:

- 2.7.1. Transaction Lifecycle
- 4.3. The IDBFactory interface (2)
- 4.5. The IDBObjectStore interface
- 5.1. Opening a database (2)
- 5.3. Deleting a database (2)
- 5.4. Committing a transaction
- 5.5. Aborting a transaction (2)
- 5.6. Asynchronously executing a request
- 5.7. Running an upgrade transaction

https://html.spec.whatwg.org/multipage/structured-data.html#serializable-objects Referenced in:

- 2.3. Values

https://html.spec.whatwg.org/multipage/webappapis.html#task-queue Referenced in:

- 2.8.1. Open Requests (2)

https://infra.spec.whatwg.org/#set-append Referenced in:

- 7.4. Convert a value to a key

https://infra.spec.whatwg.org/#assert Referenced in:

- 2.4. Keys
- 5.6. Asynchronously executing a request
- 5.11. Clone a value
- 6.7. Cursor Iteration Operation
- 7.1. Extract a key from a value (2) (3)
- 7.2. Inject a key into a value (2) (3) (4) (5) (6)
- 7.3. Convert a key to a value (2) (3) (4)

https://infra.spec.whatwg.org/#byte Referenced in:

- 2.4. Keys

https://infra.spec.whatwg.org/#byte-less-than Referenced in:

- 2.4. Keys (2)

https://infra.spec.whatwg.org/#byte-sequence Referenced in:

- 2.4. Keys

https://infra.spec.whatwg.org/#code-unit-less-than Referenced in:

- 2.4. Keys (2)

https://infra.spec.whatwg.org/#list-contain Referenced in:

- 7.4. Convert a value to a key

https://infra.spec.whatwg.org/#list-iterate Referenced in:

- 4.3. The IDBFactory interface
- 5.1. Opening a database
- 5.3. Deleting a database
- 5.5. Aborting a transaction
- 6.2. Object Store Retrieval Operations (2)
- 6.3. Index Retrieval Operations (2)
- 7.1. Extract a key from a value (2)
- 7.2. Inject a key into a value (2)

https://infra.spec.whatwg.org/#list-item Referenced in:

- 2.4. Keys
- 7.2. Inject a key into a value (2)
- 7.4. Convert a value to a key

https://infra.spec.whatwg.org/#byte-sequence-length Referenced in:

- 7.3. Convert a key to a value

https://infra.spec.whatwg.org/#list Referenced in:

- 2.4. Keys
- 4.3. The IDBFactory interface
- 6.2. Object Store Retrieval Operations (2)
- 6.3. Index Retrieval Operations (2)
- 7.1. Extract a key from a value
- 7.4. Convert a value to a key

https://infra.spec.whatwg.org/#ordered-set Referenced in:

- 4.3. The IDBFactory interface
- 5.1. Opening a database
- 5.3. Deleting a database
- 7.4. Convert a value to a key (2) (3)

https://infra.spec.whatwg.org/#list-size Referenced in:

- 2.4. Keys (2) (3) (4) (5) (6)
- 7.3. Convert a key to a value

https://infra.spec.whatwg.org/#strictly-split Referenced in:

- 7.1. Extract a key from a value
- 7.2. Inject a key into a value (2)

https://www.w3.org/2001/tag/doc/promises-guide/#a-new-promise Referenced in:

- 4.3. The IDBFactory interface

https://www.w3.org/2001/tag/doc/promises-guide/#a-promise-rejected-with Referenced in:

- 4.3. The IDBFactory interface

https://www.w3.org/2001/tag/doc/promises-guide/#reject-promise Referenced in:

- 4.3. The IDBFactory interface

https://www.w3.org/2001/tag/doc/promises-guide/#resolve-promise Referenced in:

- 4.3. The IDBFactory interface

https://heycam.github.io/webidl/#aborterror Referenced in:

- 3. Exceptions
- 4.9. The IDBTransaction interface (2)
- 5.1. Opening a database (2)
- 5.2. Closing a database
- 5.5. Aborting a transaction
- 5.7. Running an upgrade transaction
- 5.9. Firing a success event
- 5.10. Firing an error event (2)

https://heycam.github.io/webidl/#constrainterror Referenced in:

- 2.11. Key Generators
- 3. Exceptions
- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface (2) (3) (4) (5)
- 4.6. The IDBIndex interface
- 4.9. The IDBTransaction interface
- 6.1. Object Store Storage Operation (2) (3) (4)

https://heycam.github.io/webidl/#idl-DOMException Referenced in:

- 2.9. Key Range (2)
- 2.11. Key Generators
- 3. Exceptions (2)
- 4.1. The IDBRequest interface (2) (3) (4) (5) (6)
- 4.3. The IDBFactory interface (2) (3) (4) (5) (6) (7)
- 4.4. The IDBDatabase interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) (27) (28) (29) (30) (31) (32) (33) (34) (35) (36) (37) (38) (39) (40) (41) (42) (43) (44) (45) (46) (47) (48) (49) (50) (51) (52) (53) (54) (55) (56) (57) (58)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21)
- 4.7. The IDBKeyRange interface (2) (3) (4) (5) (6) (7)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) (27) (28) (29) (30) (31) (32) (33) (34) (35) (36) (37) (38) (39) (40) (41) (42)
- 4.9. The IDBTransaction interface (2) (3) (4) (5) (6) (7) (8) (9)
- 5.1. Opening a database (2) (3) (4)
- 5.2. Closing a database
- 5.3. Deleting a database
- 5.4. Committing a transaction
- 5.5. Aborting a transaction
- 5.7. Running an upgrade transaction
- 5.9. Firing a success event
- 5.10. Firing an error event
- 6.1. Object Store Storage Operation (2) (3) (4)

https://heycam.github.io/webidl/#idl-DOMString Referenced in:

- 2. Constructs
- 2.4. Keys
- 4.2. Event interfaces
- 4.3. The IDBFactory interface (2) (3)
- 4.4. The IDBDatabase interface (2) (3) (4) (5) (6) (7)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7)
- 4.6. The IDBIndex interface (2)
- 4.9. The IDBTransaction interface

https://heycam.github.io/webidl/#datacloneerror Referenced in:

- 3. Exceptions

https://heycam.github.io/webidl/#dataerror Referenced in:

- 2.9. Key Range (2)
- 3. Exceptions
- 4.3. The IDBFactory interface (2) (3)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7)
- 4.7. The IDBKeyRange interface (2) (3) (4) (5) (6) (7)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11)

https://heycam.github.io/webidl/#EnforceRange Referenced in:

- 4.3. The IDBFactory interface
- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface

https://heycam.github.io/webidl/#Exposed Referenced in:

- 4.1. The IDBRequest interface (2)
- 4.2. Event interfaces
- 4.3. The IDBFactory interface
- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface
- 4.6. The IDBIndex interface
- 4.7. The IDBKeyRange interface
- 4.8. The IDBCursor interface (2)
- 4.9. The IDBTransaction interface

https://heycam.github.io/webidl/#invalidaccesserror Referenced in:

- 3. Exceptions
- 4.4. The IDBDatabase interface (2)
- 4.5. The IDBObjectStore interface
- 4.8. The IDBCursor interface (2) (3)

https://heycam.github.io/webidl/#invalidstateerror Referenced in:

- 3. Exceptions
- 4.1. The IDBRequest interface (2) (3) (4)
- 4.4. The IDBDatabase interface (2) (3) (4) (5) (6)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9) (10)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18)
- 4.9. The IDBTransaction interface (2) (3)

https://heycam.github.io/webidl/#NewObject Referenced in:

- 4.3. The IDBFactory interface (2)
- 4.4. The IDBDatabase interface (2)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7)
- 4.7. The IDBKeyRange interface (2) (3) (4)
- 4.8. The IDBCursor interface (2)

https://heycam.github.io/webidl/#notfounderror Referenced in:

- 3. Exceptions
- 4.4. The IDBDatabase interface (2)
- 4.5. The IDBObjectStore interface (2)
- 4.9. The IDBTransaction interface

https://heycam.github.io/webidl/#quotaexceedederror Referenced in:

- 3. Exceptions
- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface
- 4.9. The IDBTransaction interface
- 5.1. Opening a database
- 5.3. Deleting a database
- 5.4. Committing a transaction

https://heycam.github.io/webidl/#readonlyerror Referenced in:

- 3. Exceptions
- 4.5. The IDBObjectStore interface (2) (3) (4)
- 4.8. The IDBCursor interface (2) (3)

https://heycam.github.io/webidl/#SameObject Referenced in:

- 4.3. The IDBFactory interface
- 4.5. The IDBObjectStore interface
- 4.6. The IDBIndex interface
- 4.8. The IDBCursor interface
- 4.9. The IDBTransaction interface

https://heycam.github.io/webidl/#securityerror Referenced in:

- 4.3. The IDBFactory interface (2) (3)

https://heycam.github.io/webidl/#syntaxerror Referenced in:

- 3. Exceptions
- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface

https://heycam.github.io/webidl/#transactioninactiveerror Referenced in:

- 3. Exceptions
- 4.4. The IDBDatabase interface (2)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9) (10)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7)

https://heycam.github.io/webidl/#unknownerror Referenced in:

- 3. Exceptions
- 4.3. The IDBFactory interface
- 4.9. The IDBTransaction interface
- 5.1. Opening a database
- 5.3. Deleting a database
- 5.4. Committing a transaction

https://heycam.github.io/webidl/#versionerror Referenced in:

- 3. Exceptions
- 5.1. Opening a database

https://heycam.github.io/webidl/#idl-boolean Referenced in:

- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface (2) (3)
- 4.6. The IDBIndex interface (2)
- 4.7. The IDBKeyRange interface (2) (3) (4) (5) (6) (7)

https://heycam.github.io/webidl/#dfn-buffer-source-type Referenced in:

- 7.4. Convert a value to a key

https://heycam.github.io/webidl/#idl-byte Referenced in:

- 2.4. Keys

https://heycam.github.io/webidl/#dfn-create-exception Referenced in:

- 5.1. Opening a database (2) (3)
- 5.2. Closing a database
- 5.5. Aborting a transaction
- 5.7. Running an upgrade transaction
- 5.9. Firing a success event
- 5.10. Firing an error event

https://heycam.github.io/webidl/#dfn-get-buffer-source-copy Referenced in:

- 7.4. Convert a value to a key

https://heycam.github.io/webidl/#idl-sequence Referenced in:

- 4.5. The IDBObjectStore interface
- 4.6. The IDBIndex interface
- 6.2. Object Store Retrieval Operations (2)
- 6.3. Index Retrieval Operations (2)

https://heycam.github.io/webidl/#idl-sequence Referenced in:

- 4.5. The IDBObjectStore interface
- 4.6. The IDBIndex interface
- 6.2. Object Store Retrieval Operations (2)
- 6.3. Index Retrieval Operations (2)

https://heycam.github.io/webidl/#idl-short Referenced in:

- 4.3. The IDBFactory interface

https://heycam.github.io/webidl/#dfn-throw Referenced in:

- 2.9. Key Range (2)
- 4.1. The IDBRequest interface (2)
- 4.3. The IDBFactory interface (2) (3) (4) (5)
- 4.4. The IDBDatabase interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) (27) (28) (29) (30) (31) (32) (33) (34) (35) (36) (37) (38) (39) (40) (41) (42) (43) (44) (45) (46)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18)
- 4.7. The IDBKeyRange interface (2) (3) (4) (5) (6) (7)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) (27) (28) (29) (30) (31) (32)
- 4.9. The IDBTransaction interface (2) (3) (4)

https://heycam.github.io/webidl/#idl-unrestricted-double Referenced in:

- 2.4. Keys

https://heycam.github.io/webidl/#idl-unsigned-long Referenced in:

- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface

https://heycam.github.io/webidl/#idl-unsigned-long-long Referenced in:

- 4.2. Event interfaces (2) (3) (4)
- 4.3. The IDBFactory interface (2)
- 4.4. The IDBDatabase interface

### Terms defined by reference

- [DOM] defines the following terms:
  - Event
  - EventInit
  - EventTarget
  - bubbles
  - cancelable
  - canceled flag
  - creating an event
  - dispatch
  - event
  - fire an event
  - get the parent
  - preventDefault()
  - type
- [ecma262] defines the following terms:
  - !
  - ?
  - abrupt completion
  - array
  - array exotic object
  - array.prototype.sort
  - arraybuffer
  - createdataproperty
  - current realm
  - date
  - get
  - hasownproperty
  - identifiername
  - number
  - object
  - realm
  - record
  - regexp
  - returnifabrupt
  - string
  - tolength
  - tostring
  - type
  - typeerror
  - uint8array
- [FileAPI] defines the following terms:
  - Blob
  - File
  - lastModified
  - name
  - size
  - type
- [HTML] defines the following terms:
  - DOMStringList
  - Document
  - EventHandler
  - ImageData
  - StructuredDeserialize
  - StructuredSerializeForStorage
  - WindowOrWorkerGlobalScope
  - browsing context
  - close
  - domain
  - event handler idl attribute
  - event loop
  - in parallel
  - opaque origin
  - origin
  - queue a task
  - serializable objects
  - task queues
- [INFRA] defines the following terms:
  - append (for set)
  - assert
  - byte
  - byte less than
  - byte sequence
  - code unit less than
  - contain
  - for each
  - item
  - length
  - list
  - set
  - size
  - strictly split a string
- [promises-guide] defines the following terms:
  - a new promise
  - a promise rejected with
  - reject
  - resolve
- [WEBIDL] defines the following terms:
  - AbortError
  - ConstraintError
  - DOMException
  - DOMString
  - DataCloneError
  - DataError
  - EnforceRange
  - Exposed
  - InvalidAccessError
  - InvalidStateError
  - NewObject
  - NotFoundError
  - QuotaExceededError
  - ReadOnlyError
  - SameObject
  - SecurityError
  - SyntaxError
  - TransactionInactiveError
  - UnknownError
  - VersionError
  - boolean
  - buffer source types
  - byte
  - created
  - get a copy of the buffer source
  - sequence<any>
  - sequence<domstring>
  - short
  - throw
  - unrestricted double
  - unsigned long
  - unsigned long long

## References

### Normative References

[DOM]
  Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMA-262]
  ECMAScript Language Specification. URL: https://tc39.github.io/ecma262/
[FileAPI]
  Marijn Kruisselbrink; Arun Ranganathan. File API. 31 May 2019. WD. URL: https://www.w3.org/TR/FileAPI/
[HTML]
  Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
  Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[PROMISES-GUIDE]
  Domenic Denicola. Writing Promise-Using Specifications. 9 November 2018. TAG Finding. URL: https://www.w3.org/2001/tag/doc/promises-guide
[RFC2119]
  S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[WEBIDL]
  Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

### Informative References

[Charmod-Norm]
  Addison Phillips; et al. Character Model for the World Wide Web: String Matching. 4 February 2019. NOTE. URL: https://www.w3.org/TR/charmod-norm/
[COOKIES]
  A. Barth. HTTP State Management Mechanism. April 2011. Proposed Standard. URL: https://httpwg.org/specs/rfc6265.html
[WEBSTORAGE]
  Ian Hickson. Web Storage (Second Edition). 19 April 2016. REC. URL: https://www.w3.org/TR/webstorage/

## IDL Index

    [Exposed=(Window,Worker)]
    interface IDBRequest : EventTarget {
      readonly attribute any result;
      readonly attribute DOMException? error;
      readonly attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;
      readonly attribute IDBTransaction? transaction;
      readonly attribute IDBRequestReadyState readyState;

      // Event handlers:
      attribute EventHandler onsuccess;
      attribute EventHandler onerror;
    };

    enum IDBRequestReadyState {
      "pending",
      "done"
    };

    [Exposed=(Window,Worker)]
    interface IDBOpenDBRequest : IDBRequest {
      // Event handlers:
      attribute EventHandler onblocked;
      attribute EventHandler onupgradeneeded;
    };

    [Exposed=(Window,Worker)]
    interface IDBVersionChangeEvent : Event {
      constructor(DOMString type, optional IDBVersionChangeEventInit eventInitDict = {});
      readonly attribute unsigned long long oldVersion;
      readonly attribute unsigned long long? newVersion;
    };

    dictionary IDBVersionChangeEventInit : EventInit {
      unsigned long long oldVersion = 0;
      unsigned long long? newVersion = null;
    };

    partial interface mixin WindowOrWorkerGlobalScope {
      [SameObject] readonly attribute IDBFactory indexedDB;
    };

    [Exposed=(Window,Worker)]
    interface IDBFactory {
      [NewObject] IDBOpenDBRequest open(DOMString name,
                                        optional [EnforceRange] unsigned long long version);
      [NewObject] IDBOpenDBRequest deleteDatabase(DOMString name);

      Promise<sequence<IDBDatabaseInfo>> databases();

      short cmp(any first, any second);
    };

    dictionary IDBDatabaseInfo {
      DOMString name;
      unsigned long long version;
    };

    [Exposed=(Window,Worker)]
    interface IDBDatabase : EventTarget {
      readonly attribute DOMString name;
      readonly attribute unsigned long long version;
      readonly attribute DOMStringList objectStoreNames;

      [NewObject] IDBTransaction transaction((DOMString or sequence<DOMString>) storeNames,
                                             optional IDBTransactionMode mode = "readonly");
      void close();

      [NewObject] IDBObjectStore createObjectStore(
        DOMString name,
        optional IDBObjectStoreParameters options = {});
      void deleteObjectStore(DOMString name);

      // Event handlers:
      attribute EventHandler onabort;
      attribute EventHandler onclose;
      attribute EventHandler onerror;
      attribute EventHandler onversionchange;
    };

    dictionary IDBObjectStoreParameters {
      (DOMString or sequence<DOMString>)? keyPath = null;
      boolean autoIncrement = false;
    };

    [Exposed=(Window,Worker)]
    interface IDBObjectStore {
      attribute DOMString name;
      readonly attribute any keyPath;
      readonly attribute DOMStringList indexNames;
      [SameObject] readonly attribute IDBTransaction transaction;
      readonly attribute boolean autoIncrement;

      [NewObject] IDBRequest put(any value, optional any key);
      [NewObject] IDBRequest add(any value, optional any key);
      [NewObject] IDBRequest delete(any query);
      [NewObject] IDBRequest clear();
      [NewObject] IDBRequest get(any query);
      [NewObject] IDBRequest getKey(any query);
      [NewObject] IDBRequest getAll(optional any query,
                                    optional [EnforceRange] unsigned long count);
      [NewObject] IDBRequest getAllKeys(optional any query,
                                        optional [EnforceRange] unsigned long count);
      [NewObject] IDBRequest count(optional any query);

      [NewObject] IDBRequest openCursor(optional any query,
                                        optional IDBCursorDirection direction = "next");
      [NewObject] IDBRequest openKeyCursor(optional any query,
                                           optional IDBCursorDirection direction = "next");

      IDBIndex index(DOMString name);

      [NewObject] IDBIndex createIndex(DOMString name,
                                       (DOMString or sequence<DOMString>) keyPath,
                                       optional IDBIndexParameters options = {});
      void deleteIndex(DOMString name);
    };

    dictionary IDBIndexParameters {
      boolean unique = false;
      boolean multiEntry = false;
    };

    [Exposed=(Window,Worker)]
    interface IDBIndex {
      attribute DOMString name;
      [SameObject] readonly attribute IDBObjectStore objectStore;
      readonly attribute any keyPath;
      readonly attribute boolean multiEntry;
      readonly attribute boolean unique;

      [NewObject] IDBRequest get(any query);
      [NewObject] IDBRequest getKey(any query);
      [NewObject] IDBRequest getAll(optional any query,
                                    optional [EnforceRange] unsigned long count);
      [NewObject] IDBRequest getAllKeys(optional any query,
                                        optional [EnforceRange] unsigned long count);
      [NewObject] IDBRequest count(optional any query);

      [NewObject] IDBRequest openCursor(optional any query,
                                        optional IDBCursorDirection direction = "next");
      [NewObject] IDBRequest openKeyCursor(optional any query,
                                           optional IDBCursorDirection direction = "next");
    };

    [Exposed=(Window,Worker)]
    interface IDBKeyRange {
      readonly attribute any lower;
      readonly attribute any upper;
      readonly attribute boolean lowerOpen;
      readonly attribute boolean upperOpen;

      // Static construction methods:
      [NewObject] static IDBKeyRange only(any value);
      [NewObject] static IDBKeyRange lowerBound(any lower, optional boolean open = false);
      [NewObject] static IDBKeyRange upperBound(any upper, optional boolean open = false);
      [NewObject] static IDBKeyRange bound(any lower,
                                           any upper,
                                           optional boolean lowerOpen = false,
                                           optional boolean upperOpen = false);

      boolean includes(any key);
    };

    [Exposed=(Window,Worker)]
    interface IDBCursor {
      readonly attribute (IDBObjectStore or IDBIndex) source;
      readonly attribute IDBCursorDirection direction;
      readonly attribute any key;
      readonly attribute any primaryKey;
      [SameObject] readonly attribute IDBRequest request;

      void advance([EnforceRange] unsigned long count);
      void continue(optional any key);
      void continuePrimaryKey(any key, any primaryKey);

      [NewObject] IDBRequest update(any value);
      [NewObject] IDBRequest delete();
    };

    enum IDBCursorDirection {
      "next",
      "nextunique",
      "prev",
      "prevunique"
    };

    [Exposed=(Window,Worker)]
    interface IDBCursorWithValue : IDBCursor {
      readonly attribute any value;
    };

    [Exposed=(Window,Worker)]
    interface IDBTransaction : EventTarget {
      readonly attribute DOMStringList objectStoreNames;
      readonly attribute IDBTransactionMode mode;
      [SameObject] readonly attribute IDBDatabase db;
      readonly attribute DOMException? error;

      IDBObjectStore objectStore(DOMString name);
      void commit();
      void abort();

      // Event handlers:
      attribute EventHandler onabort;
      attribute EventHandler oncomplete;
      attribute EventHandler onerror;
    };

    enum IDBTransactionMode {
      "readonly",
      "readwrite",
      "versionchange"
    };

#name Referenced in:

- 2. Constructs (2) (3)
- 2.1. Database
- 2.2. Object Store
- 2.6. Index

#sorted-name-list Referenced in:

- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface
- 4.9. The IDBTransaction interface (2)

#database Referenced in:

- 2.1. Database (2) (3) (4) (5) (6)
- 2.1.1. Database Connection (2) (3) (4) (5) (6) (7) (8) (9)
- 2.2. Object Store (2)
- 2.7. Transactions
- 2.7.1. Transaction Lifecycle (2)
- 2.7.2. Transaction Scheduling
- 2.7.3. Upgrade Transactions (2) (3) (4) (5) (6)
- 2.8. Requests
- 2.8.1. Open Requests
- 4.1. The IDBRequest interface (2) (3) (4)
- 4.3. The IDBFactory interface (2) (3) (4) (5) (6) (7) (8)
- 4.4. The IDBDatabase interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11)
- 4.5. The IDBObjectStore interface
- 4.9. The IDBTransaction interface (2)
- 5.1. Opening a database (2) (3)
- 5.2. Closing a database
- 5.3. Deleting a database (2)
- 5.4. Committing a transaction (2) (3)
- 5.5. Aborting a transaction (2)
- 5.7. Running an upgrade transaction (2) (3) (4)
- 5.8. Aborting an upgrade transaction (2) (3)
- 6. Database operations

#database-name Referenced in:

- 2.8.1. Open Requests
- 4.3. The IDBFactory interface
- 4.4. The IDBDatabase interface (2)
- 5.1. Opening a database (2)
- 5.3. Deleting a database

#database-version Referenced in:

- 2.1. Database
- 2.7.3. Upgrade Transactions (2)
- 4.3. The IDBFactory interface (2) (3)
- 4.4. The IDBDatabase interface (2) (3)
- 5.1. Opening a database (2) (3) (4) (5) (6)
- 5.3. Deleting a database (2) (3)
- 5.5. Aborting a transaction
- 5.7. Running an upgrade transaction (2)
- 5.8. Aborting an upgrade transaction (2)

#database-upgrade-transaction Referenced in:

- 4.4. The IDBDatabase interface (2)
- 5.4. Committing a transaction
- 5.5. Aborting a transaction
- 5.7. Running an upgrade transaction

#connection Referenced in:

- 1. Introduction (2)
- 2.1.1. Database Connection (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18)
- 2.7. Transactions
- 2.7.3. Upgrade Transactions (2) (3) (4) (5) (6)
- 2.8.1. Open Requests (2)
- 4.3. The IDBFactory interface (2) (3) (4) (5) (6)
- 4.4. The IDBDatabase interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14)
- 4.9. The IDBTransaction interface
- 5.1. Opening a database (2) (3) (4)
- 5.2. Closing a database (2) (3) (4) (5)
- 5.3. Deleting a database (2) (3)
- 5.5. Aborting a transaction
- 5.7. Running an upgrade transaction (2)
- 5.8. Aborting an upgrade transaction

#connection-version Referenced in:

- 2.1.1. Database Connection
- 4.4. The IDBDatabase interface
- 5.1. Opening a database
- 5.8. Aborting an upgrade transaction

#connection-close-pending-flag Referenced in:

- 2.1.1. Database Connection
- 4.4. The IDBDatabase interface (2) (3)
- 5.1. Opening a database
- 5.2. Closing a database (2) (3)
- 5.3. Deleting a database

#connection-closed Referenced in:

- 2.8.1. Open Requests
- 4.4. The IDBDatabase interface (2) (3) (4)
- 5.1. Opening a database (2)
- 5.2. Closing a database
- 5.3. Deleting a database

#connection-object-store-set Referenced in:

- 4.4. The IDBDatabase interface (2)
- 4.9. The IDBTransaction interface
- 5.8. Aborting an upgrade transaction

#eventdef-connection-versionchange Referenced in:

- 1. Introduction (2) (3)
- 4.3. The IDBFactory interface (2) (3)
- 4.4. The IDBDatabase interface (2)
- 5.1. Opening a database (2)
- 5.3. Deleting a database (2)

#object-store Referenced in:

- 2.1. Database
- 2.1.1. Database Connection
- 2.2. Object Store (2) (3) (4) (5) (6) (7)
- 2.2.1. Object Store Handle (2) (3)
- 2.6. Index (2) (3) (4) (5) (6) (7)
- 2.7. Transactions
- 2.7.1. Transaction Lifecycle (2)
- 2.7.2. Transaction Scheduling (2) (3) (4) (5) (6) (7)
- 2.7.3. Upgrade Transactions (2)
- 2.9. Key Range
- 2.10. Cursor (2) (3) (4) (5) (6)
- 2.11. Key Generators (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14)
- 4.4. The IDBDatabase interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9)
- 4.9. The IDBTransaction interface (2) (3) (4) (5)
- 5.1. Opening a database
- 5.5. Aborting a transaction (2)
- 5.7. Running an upgrade transaction
- 5.8. Aborting an upgrade transaction (2) (3) (4)
- 6. Database operations
- 6.7. Cursor Iteration Operation (2) (3)
- 7.2. Inject a key into a value

#object-store-list-of-records Referenced in:

- 6.1. Object Store Storage Operation
- 6.2. Object Store Retrieval Operations (2) (3) (4)
- 6.4. Object Store Deletion Operation

#object-store-record Referenced in:

- 2.2. Object Store
- 2.4. Keys (2)
- 2.6. Index (2) (3) (4) (5) (6) (7) (8) (9) (10) (11)
- 2.10. Cursor (2) (3)
- 2.11. Key Generators (2) (3) (4) (5) (6) (7)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) (25) (26) (27)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7) (8)
- 6.1. Object Store Storage Operation (2) (3) (4) (5)
- 6.2. Object Store Retrieval Operations (2) (3) (4)
- 6.3. Index Retrieval Operations (2) (3)
- 6.4. Object Store Deletion Operation
- 6.6. Object Store Clear Operation
- 6.7. Cursor Iteration Operation (2)

#object-store-name Referenced in:

- 2.2.1. Object Store Handle
- 4.4. The IDBDatabase interface (2) (3) (4) (5) (6) (7) (8)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8)
- 4.9. The IDBTransaction interface (2) (3)
- 5.8. Aborting an upgrade transaction

#object-store-key-path Referenced in:

- 2.2. Object Store
- 2.11. Key Generators (2) (3) (4) (5) (6) (7) (8) (9)
- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface (2) (3) (4)
- 4.6. The IDBIndex interface
- 4.8. The IDBCursor interface
- 6.1. Object Store Storage Operation
- 7.2. Inject a key into a value

#object-store-in-line-keys Referenced in:

- 2.11. Key Generators
- 4.5. The IDBObjectStore interface (2) (3)
- 4.8. The IDBCursor interface (2)
- 6.1. Object Store Storage Operation

#object-store-out-of-line-keys Referenced in:

- 2.11. Key Generators
- 4.5. The IDBObjectStore interface

#object-store-handle Referenced in:

- 2.2.1. Object Store Handle (2) (3) (4) (5) (6)
- 2.6.1. Index Handle
- 4.4. The IDBDatabase interface (2)
- 4.5. The IDBObjectStore interface
- 4.9. The IDBTransaction interface
- 5.5. Aborting a transaction
- 5.8. Aborting an upgrade transaction

#object-store-handle-object-store Referenced in:

- 2.2.1. Object Store Handle (2)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16)
- 5.8. Aborting an upgrade transaction (2) (3)

#object-store-handle-transaction Referenced in:

- 2.6.1. Index Handle
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15)

#object-store-handle-index-set Referenced in:

- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface (2) (3) (4)
- 5.8. Aborting an upgrade transaction

#object-store-handle-name Referenced in:

- 4.5. The IDBObjectStore interface
- 5.8. Aborting an upgrade transaction

#value Referenced in:

- 2.2. Object Store (2)
- 2.3. Values (2)
- 2.5. Key Path
- 2.6. Index (2)
- 2.10. Cursor (2) (3)
- 4.5. The IDBObjectStore interface (2) (3) (4)
- 4.6. The IDBIndex interface (2) (3) (4)
- 6.2. Object Store Retrieval Operations (2)
- 6.3. Index Retrieval Operations
- 6.7. Cursor Iteration Operation

#key Referenced in:

- 2.2. Object Store (2)
- 2.4. Keys (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16)
- 2.5. Key Path
- 2.6. Index (2) (3)
- 2.9. Key Range (2) (3) (4) (5) (6) (7) (8)
- 2.10. Cursor (2) (3) (4)
- 2.11. Key Generators (2) (3) (4) (5) (6) (7)
- 4.3. The IDBFactory interface (2)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16)
- 4.8. The IDBCursor interface (2)
- 6.1. Object Store Storage Operation (2)
- 6.2. Object Store Retrieval Operations (2) (3) (4)
- 6.7. Cursor Iteration Operation (2) (3) (4)
- 7. ECMAScript binding
- 7.1. Extract a key from a value
- 7.4. Convert a value to a key (2) (3) (4) (5) (6)

#key-type Referenced in:

- 2.4. Keys (2) (3)
- 2.11. Key Generators (2) (3) (4)
- 7.3. Convert a key to a value
- 7.4. Convert a value to a key (2) (3) (4)

#key-value Referenced in:

- 2.4. Keys (2) (3)
- 2.11. Key Generators (2)
- 7.3. Convert a key to a value
- 7.4. Convert a value to a key (2) (3) (4) (5) (6)

#array-key Referenced in:

- 2.4. Keys (2)
- 2.6. Index (2)
- 6.1. Object Store Storage Operation (2) (3) (4) (5) (6) (7)
- 7.4. Convert a value to a key (2) (3)

#subkeys Referenced in:

- 2.6. Index
- 6.1. Object Store Storage Operation (2) (3) (4)
- 7.4. Convert a value to a key

#compare-two-keys Referenced in:

- 2.4. Keys (2) (3) (4)
- 4.3. The IDBFactory interface

#greater-than Referenced in:

- 2.2. Object Store
- 2.9. Key Range (2)
- 2.10. Cursor
- 4.7. The IDBKeyRange interface
- 4.8. The IDBCursor interface (2) (3)
- 6.1. Object Store Storage Operation (2) (3)
- 6.7. Cursor Iteration Operation (2) (3) (4) (5) (6) (7) (8) (9) (10)

#less-than Referenced in:

- 2.9. Key Range
- 2.10. Cursor
- 4.8. The IDBCursor interface (2) (3)
- 6.7. Cursor Iteration Operation (2) (3) (4) (5) (6) (7) (8)

#equal-to Referenced in:

- 2.9. Key Range (2) (3)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7)
- 6.1. Object Store Storage Operation (2) (3) (4)
- 6.7. Cursor Iteration Operation (2) (3) (4) (5) (6) (7) (8) (9) (10) (11)
- 7.4. Convert a value to a key

#key-path Referenced in:

- 2.5. Key Path
- 4.5. The IDBObjectStore interface
- 4.6. The IDBIndex interface (2)
- 7. ECMAScript binding
- 7.1. Extract a key from a value
- 7.2. Inject a key into a value

#valid-key-path Referenced in:

- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface

#identifier Referenced in:

- 2.5. Key Path

#index-concept Referenced in:

- 2.2.1. Object Store Handle
- 2.6. Index (2) (3) (4) (5)
- 2.6.1. Index Handle (2) (3)
- 2.7.1. Transaction Lifecycle
- 2.7.3. Upgrade Transactions (2)
- 2.9. Key Range
- 2.10. Cursor (2) (3) (4) (5) (6)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6)
- 4.8. The IDBCursor interface (2)
- 5.5. Aborting a transaction (2)
- 5.8. Aborting an upgrade transaction (2) (3) (4)
- 6. Database operations
- 6.6. Object Store Clear Operation
- 6.7. Cursor Iteration Operation (2) (3) (4) (5) (6) (7) (8)

#index-referenced Referenced in:

- 2.6. Index (2) (3) (4) (5)
- 2.10. Cursor
- 4.5. The IDBObjectStore interface (2)
- 6.1. Object Store Storage Operation
- 6.3. Index Retrieval Operations
- 6.4. Object Store Deletion Operation
- 6.6. Object Store Clear Operation

#index-list-of-records Referenced in:

- 6.1. Object Store Storage Operation (2)
- 6.3. Index Retrieval Operations (2) (3) (4)
- 6.4. Object Store Deletion Operation

#index-records Referenced in:

- 2.6. Index
- 6.3. Index Retrieval Operations (2) (3)

#index-values Referenced in:

- 6.3. Index Retrieval Operations

#index-keys Referenced in:

- 2.6. Index
- 6.3. Index Retrieval Operations (2) (3) (4)

#index-key-path Referenced in:

- 2.6. Index (2) (3)
- 4.5. The IDBObjectStore interface (2)
- 6.1. Object Store Storage Operation

#index-referenced-value Referenced in:

- 2.6. Index (2)
- 6.3. Index Retrieval Operations (2)
- 6.7. Cursor Iteration Operation

#index-name Referenced in:

- 2.6.1. Index Handle
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8)
- 5.8. Aborting an upgrade transaction

#index-unique-flag Referenced in:

- 2.10. Cursor (2)
- 4.5. The IDBObjectStore interface (2) (3)
- 4.6. The IDBIndex interface (2)
- 6.1. Object Store Storage Operation (2)

#index-multientry-flag Referenced in:

- 2.6. Index (2)
- 4.5. The IDBObjectStore interface
- 4.6. The IDBIndex interface (2)
- 6.1. Object Store Storage Operation (2) (3) (4) (5)

#index-handle Referenced in:

- 2.6.1. Index Handle (2) (3) (4) (5)
- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface
- 5.5. Aborting a transaction
- 5.8. Aborting an upgrade transaction

#index-handle-index Referenced in:

- 2.6.1. Index Handle
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11)
- 5.8. Aborting an upgrade transaction (2)

#index-handle-object-store-handle Referenced in:

- 4.6. The IDBIndex interface

#index-handle-transaction Referenced in:

- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8)

#index-handle-name Referenced in:

- 4.6. The IDBIndex interface
- 5.8. Aborting an upgrade transaction

#transaction-concept Referenced in:

- 2.1.1. Database Connection
- 2.2.1. Object Store Handle (2) (3)
- 2.6.1. Index Handle (2) (3)
- 2.7. Transactions (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14)
- 2.7.1. Transaction Lifecycle (2) (3) (4) (5) (6)
- 2.7.2. Transaction Scheduling (2) (3)
- 2.7.3. Upgrade Transactions (2) (3)
- 2.8. Requests
- 2.10. Cursor
- 2.11. Key Generators (2)
- 4.4. The IDBDatabase interface (2) (3) (4)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9)
- 4.6. The IDBIndex interface (2) (3) (4)
- 4.8. The IDBCursor interface (2) (3)
- 4.9. The IDBTransaction interface (2) (3) (4) (5) (6) (7) (8) (9)
- 5.5. Aborting a transaction
- 5.6. Asynchronously executing a request (2)
- 5.7. Running an upgrade transaction (2) (3)
- 5.8. Aborting an upgrade transaction (2)
- 5.9. Firing a success event
- 5.10. Firing an error event
- 5.11. Clone a value

#transaction-connection Referenced in:

- 2.7. Transactions
- 4.9. The IDBTransaction interface (2)
- 5.4. Committing a transaction
- 5.5. Aborting a transaction

#transaction-scope Referenced in:

- 2.7. Transactions (2)
- 2.7.1. Transaction Lifecycle (2)
- 2.7.2. Transaction Scheduling (2) (3) (4) (5) (6)
- 2.11. Key Generators
- 4.9. The IDBTransaction interface (2) (3) (4)
- 5.7. Running an upgrade transaction

#transaction-mode Referenced in:

- 2.7. Transactions (2) (3) (4)
- 2.7.1. Transaction Lifecycle (2) (3)
- 2.7.3. Upgrade Transactions
- 4.9. The IDBTransaction interface (2)

#transaction-cleanup-event-loop Referenced in:

- 2.7.1. Transaction Lifecycle (2) (3)
- 4.4. The IDBDatabase interface

#transaction-request-list Referenced in:

- 5.4. Committing a transaction
- 5.5. Aborting a transaction
- 5.6. Asynchronously executing a request (2) (3)
- 5.9. Firing a success event
- 5.10. Firing an error event

#transaction-error Referenced in:

- 4.9. The IDBTransaction interface
- 5.5. Aborting a transaction

#transaction-read-only-transaction Referenced in:

- 2.7. Transactions
- 2.7.2. Transaction Scheduling (2) (3) (4) (5) (6) (7)
- 4.5. The IDBObjectStore interface (2) (3) (4)
- 4.8. The IDBCursor interface (2) (3)

#transaction-read-write-transaction Referenced in:

- 2.7.2. Transaction Scheduling (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12)

#transaction-state Referenced in:

- 2.7.1. Transaction Lifecycle (2) (3) (4) (5) (6)
- 4.4. The IDBDatabase interface (2)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8)
- 4.8. The IDBCursor interface (2) (3) (4) (5)
- 4.9. The IDBTransaction interface (2) (3) (4)
- 5.4. Committing a transaction (2) (3)
- 5.5. Aborting a transaction
- 5.6. Asynchronously executing a request (2)
- 5.7. Running an upgrade transaction (2) (3)
- 5.9. Firing a success event (2) (3) (4)
- 5.10. Firing an error event (2) (3) (4)
- 5.11. Clone a value (2) (3)

#transaction-active Referenced in:

- 2.7.1. Transaction Lifecycle (2) (3) (4)
- 2.10. Cursor
- 4.4. The IDBDatabase interface (2)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9) (10)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7) (8)
- 4.9. The IDBTransaction interface
- 5.6. Asynchronously executing a request
- 5.7. Running an upgrade transaction
- 5.9. Firing a success event (2)
- 5.10. Firing an error event (2)
- 5.11. Clone a value (2)

#transaction-inactive Referenced in:

- 2.7.1. Transaction Lifecycle (2)
- 4.9. The IDBTransaction interface
- 5.7. Running an upgrade transaction (2)
- 5.9. Firing a success event (2)
- 5.10. Firing an error event (2)
- 5.11. Clone a value (2)

#transaction-committing Referenced in:

- 2.7.1. Transaction Lifecycle
- 4.9. The IDBTransaction interface
- 5.4. Committing a transaction (2)
- 5.5. Aborting a transaction
- 5.6. Asynchronously executing a request

#transaction-finished Referenced in:

- 2.7.1. Transaction Lifecycle (2)
- 2.7.2. Transaction Scheduling (2)
- 2.7.3. Upgrade Transactions
- 4.5. The IDBObjectStore interface (2) (3) (4) (5)
- 4.6. The IDBIndex interface (2)
- 4.9. The IDBTransaction interface (2)
- 5.4. Committing a transaction
- 5.5. Aborting a transaction
- 5.7. Running an upgrade transaction

#transaction-lifetime Referenced in:

- 4.4. The IDBDatabase interface
- 5.7. Running an upgrade transaction

#transaction-created Referenced in:

- 2.7.1. Transaction Lifecycle
- 2.7.2. Transaction Scheduling (2)
- 4.4. The IDBDatabase interface
- 5.2. Closing a database (2) (3) (4)

#transaction-start Referenced in:

- 2.7.1. Transaction Lifecycle (2) (3) (4)
- 2.7.2. Transaction Scheduling (2)

#transaction-abort Referenced in:

- 2.7. Transactions
- 2.7.1. Transaction Lifecycle (2) (3)
- 2.7.2. Transaction Scheduling
- 4.5. The IDBObjectStore interface (2)
- 4.9. The IDBTransaction interface
- 5.6. Asynchronously executing a request
- 5.7. Running an upgrade transaction

#transaction-commit Referenced in:

- 2.7.1. Transaction Lifecycle (2) (3) (4)
- 2.7.2. Transaction Scheduling
- 4.9. The IDBTransaction interface

#cleanup-indexed-database-transactions Referenced in:

- 10. Revision History

#eventdef-transaction-complete Referenced in:

- 4.9. The IDBTransaction interface (2)
- 5.4. Committing a transaction (2)

#eventdef-transaction-abort Referenced in:

- 4.4. The IDBDatabase interface (2)
- 4.9. The IDBTransaction interface
- 5.5. Aborting a transaction

#upgrade-transaction Referenced in:

- 2.1. Database (2)
- 2.1.1. Database Connection
- 2.2. Object Store
- 2.2.1. Object Store Handle (2)
- 2.6.1. Index Handle
- 2.7.3. Upgrade Transactions (2) (3) (4) (5) (6) (7) (8)
- 2.8. Requests
- 4.1. The IDBRequest interface
- 4.3. The IDBFactory interface
- 4.4. The IDBDatabase interface (2) (3) (4) (5) (6) (7)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14)
- 4.6. The IDBIndex interface (2) (3)
- 4.9. The IDBTransaction interface (2) (3) (4)
- 5.1. Opening a database
- 5.4. Committing a transaction (2)
- 5.5. Aborting a transaction (2) (3) (4)
- 5.7. Running an upgrade transaction (2)
- 5.8. Aborting an upgrade transaction

#request Referenced in:

- 2.7. Transactions
- 2.7.1. Transaction Lifecycle (2) (3) (4) (5) (6) (7) (8) (9) (10) (11)
- 2.7.2. Transaction Scheduling
- 2.8. Requests (2) (3) (4) (5) (6) (7) (8) (9) (10)
- 2.8.1. Open Requests
- 2.10. Cursor
- 4.1. The IDBRequest interface
- 4.3. The IDBFactory interface
- 4.5. The IDBObjectStore interface (2) (3)
- 4.9. The IDBTransaction interface (2) (3) (4) (5) (6)
- 5.4. Committing a transaction
- 5.6. Asynchronously executing a request (2)
- 5.10. Firing an error event (2)

#request-processed-flag Referenced in:

- 2.8. Requests
- 4.3. The IDBFactory interface
- 4.8. The IDBCursor interface (2) (3)
- 5.5. Aborting a transaction (2)
- 5.6. Asynchronously executing a request
- 5.7. Running an upgrade transaction

#request-processed Referenced in:

- 2.7.1. Transaction Lifecycle
- 5.4. Committing a transaction
- 5.6. Asynchronously executing a request

#request-done-flag Referenced in:

- 2.8. Requests (2) (3) (4) (5)
- 4.1. The IDBRequest interface (2) (3)
- 4.3. The IDBFactory interface (2) (3) (4)
- 4.8. The IDBCursor interface (2) (3)
- 5.5. Aborting a transaction (2)
- 5.6. Asynchronously executing a request
- 5.7. Running an upgrade transaction

#request-source Referenced in:

- 2.8.1. Open Requests
- 4.1. The IDBRequest interface (2)
- 5.6. Asynchronously executing a request

#request-result Referenced in:

- 2.8. Requests (2)
- 4.1. The IDBRequest interface (2)
- 4.3. The IDBFactory interface (2) (3)
- 5.5. Aborting a transaction (2)
- 5.6. Asynchronously executing a request (2)
- 5.7. Running an upgrade transaction

#request-error Referenced in:

- 2.8. Requests (2)
- 4.1. The IDBRequest interface (2)
- 4.3. The IDBFactory interface (2)
- 4.9. The IDBTransaction interface
- 5.5. Aborting a transaction
- 5.6. Asynchronously executing a request (2)
- 5.10. Firing an error event (2)

#request-transaction Referenced in:

- 2.8. Requests
- 2.8.1. Open Requests
- 4.1. The IDBRequest interface
- 5.4. Committing a transaction
- 5.5. Aborting a transaction
- 5.7. Running an upgrade transaction

#request-placed Referenced in:

- 2.7.1. Transaction Lifecycle

#eventdef-request-success Referenced in:

- 2.7.1. Transaction Lifecycle
- 2.8.1. Open Requests
- 4.1. The IDBRequest interface
- 4.3. The IDBFactory interface (2) (3)
- 4.8. The IDBCursor interface
- 4.9. The IDBTransaction interface (2) (3) (4)

#eventdef-request-error Referenced in:

- 2.7.1. Transaction Lifecycle
- 2.8.1. Open Requests
- 4.1. The IDBRequest interface
- 4.3. The IDBFactory interface (2)
- 4.4. The IDBDatabase interface (2)
- 4.9. The IDBTransaction interface (2)
- 5.5. Aborting a transaction (2)

#request-open-request Referenced in:

- 2.8. Requests
- 2.8.1. Open Requests (2) (3) (4) (5) (6) (7)
- 4.1. The IDBRequest interface (2) (3)
- 4.3. The IDBFactory interface (2)
- 5.5. Aborting a transaction

#eventdef-request-blocked Referenced in:

- 1. Introduction (2)
- 4.1. The IDBRequest interface (2)
- 5.1. Opening a database
- 5.3. Deleting a database

#eventdef-request-upgradeneeded Referenced in:

- 1. Introduction
- 2.2. Object Store
- 2.7. Transactions
- 2.7.3. Upgrade Transactions (2)
- 2.8. Requests
- 2.8.1. Open Requests
- 4.1. The IDBRequest interface (2)
- 5.7. Running an upgrade transaction

#request-connection-queue Referenced in:

- 2.8.1. Open Requests (2)
- 5.1. Opening a database
- 5.3. Deleting a database

#key-range Referenced in:

- 2.9. Key Range (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12)
- 4.7. The IDBKeyRange interface (2) (3) (4) (5)

#key-range-lower-bound Referenced in:

- 2.9. Key Range (2) (3) (4) (5) (6) (7)
- 4.7. The IDBKeyRange interface (2) (3) (4) (5)

#key-range-upper-bound Referenced in:

- 2.9. Key Range (2) (3) (4) (5) (6) (7)
- 4.7. The IDBKeyRange interface (2) (3) (4) (5)

#key-range-lower-open-flag Referenced in:

- 2.9. Key Range (2) (3)
- 4.7. The IDBKeyRange interface (2) (3) (4) (5)

#key-range-upper-open-flag Referenced in:

- 2.9. Key Range (2) (3)
- 4.7. The IDBKeyRange interface (2) (3) (4) (5)

#containing-only Referenced in:

- 2.9. Key Range
- 4.7. The IDBKeyRange interface

#in Referenced in:

- 2.9. Key Range
- 4.7. The IDBKeyRange interface
- 6.2. Object Store Retrieval Operations (2) (3) (4)
- 6.3. Index Retrieval Operations (2) (3) (4)
- 6.4. Object Store Deletion Operation (2)
- 6.5. Record Counting Operation
- 6.7. Cursor Iteration Operation (2) (3) (4)

#unbounded-key-range Referenced in:

- 2.9. Key Range (2)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5)
- 4.6. The IDBIndex interface (2) (3) (4) (5)

#convert-a-value-to-a-key-range Referenced in:

- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7)

#cursor Referenced in:

- 2.8. Requests
- 2.10. Cursor (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6)
- 4.8. The IDBCursor interface (2) (3) (4) (5)

#cursor-transaction Referenced in:

- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2) (3) (4) (5)

#cursor-range Referenced in:

- 2.10. Cursor (2)
- 4.5. The IDBObjectStore interface (2) (3) (4)
- 4.6. The IDBIndex interface (2) (3) (4)
- 6.7. Cursor Iteration Operation

#cursor-source Referenced in:

- 2.10. Cursor (2) (3) (4) (5) (6) (7) (8) (9)
- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11)
- 6.7. Cursor Iteration Operation

#cursor-direction Referenced in:

- 2.10. Cursor
- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7) (8) (9)
- 6.7. Cursor Iteration Operation

#cursor-position Referenced in:

- 2.10. Cursor (2) (3)
- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6)
- 6.7. Cursor Iteration Operation (2)

#cursor-object-store-position Referenced in:

- 2.10. Cursor (2)
- 4.8. The IDBCursor interface (2)
- 6.7. Cursor Iteration Operation (2) (3)

#cursor-key Referenced in:

- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2) (3)
- 6.7. Cursor Iteration Operation (2)

#cursor-value Referenced in:

- 2.10. Cursor
- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2) (3)
- 6.7. Cursor Iteration Operation (2)

#cursor-got-value-flag Referenced in:

- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11)
- 6.7. Cursor Iteration Operation

#cursor-effective-object-store Referenced in:

- 2.10. Cursor
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6) (7) (8) (9) (10)

#cursor-effective-key Referenced in:

- 2.10. Cursor
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6)

#cursor-request Referenced in:

- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2) (3) (4) (5)

#cursor-key-only-flag Referenced in:

- 4.5. The IDBObjectStore interface (2) (3)
- 4.6. The IDBIndex interface (2) (3)
- 4.8. The IDBCursor interface (2) (3)
- 6.7. Cursor Iteration Operation (2)

#key-generator Referenced in:

- 2.2. Object Store (2)
- 2.11. Key Generators (2) (3) (4) (5) (6) (7) (8) (9) (10) (11)
- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface (2) (3) (4)
- 6.1. Object Store Storage Operation
- 7.2. Inject a key into a value

#key-generator-current-number Referenced in:

- 2.11. Key Generators (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18)

#generate-a-key Referenced in:

- 6.1. Object Store Storage Operation

#possibly-update-the-key-generator Referenced in:

- 6.1. Object Store Storage Operation

#idbrequest Referenced in:

- 4. API (2)
- 4.1. The IDBRequest interface (2) (3) (4)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12)
- 4.8. The IDBCursor interface (2) (3) (4) (5) (6)

#enumdef-idbrequestreadystate Referenced in:

- 4.1. The IDBRequest interface

#dom-idbrequestreadystate-pending Referenced in:

- 4.1. The IDBRequest interface (2)

#dom-idbrequestreadystate-done Referenced in:

- 4.1. The IDBRequest interface (2)

#dom-idbrequest-result Referenced in:

- 4.1. The IDBRequest interface (2)
- 4.3. The IDBFactory interface (2) (3)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7)
- 4.8. The IDBCursor interface (2) (3)

#dom-idbrequest-error Referenced in:

- 4.1. The IDBRequest interface (2)
- 4.5. The IDBObjectStore interface

#dom-idbrequest-source Referenced in:

- 4.1. The IDBRequest interface (2)

#dom-idbrequest-transaction Referenced in:

- 4.1. The IDBRequest interface (2)

#dom-idbrequest-readystate Referenced in:

- 4.1. The IDBRequest interface (2)

#dom-idbrequest-onsuccess Referenced in:

- 4.1. The IDBRequest interface

#dom-idbrequest-onerror Referenced in:

- 4.1. The IDBRequest interface

#idbopendbrequest Referenced in:

- 4.3. The IDBFactory interface (2) (3) (4)

#dom-idbopendbrequest-onblocked Referenced in:

- 4.1. The IDBRequest interface

#dom-idbopendbrequest-onupgradeneeded Referenced in:

- 4.1. The IDBRequest interface

#idbversionchangeevent Referenced in:

- 4.2. Event interfaces
- 4.3. The IDBFactory interface

#dictdef-idbversionchangeeventinit Referenced in:

- 4.2. Event interfaces

#dom-idbversionchangeevent-oldversion Referenced in:

- 4.2. Event interfaces (2)
- 4.3. The IDBFactory interface

#dom-idbversionchangeevent-newversion Referenced in:

- 4.2. Event interfaces (2)
- 4.3. The IDBFactory interface

#fire-a-version-change-event Referenced in:

- 4.3. The IDBFactory interface
- 5.1. Opening a database (2)
- 5.3. Deleting a database (2)
- 5.7. Running an upgrade transaction

#dom-windoworworkerglobalscope-indexeddb Referenced in:

- 4.3. The IDBFactory interface

#idbfactory Referenced in:

- 4.3. The IDBFactory interface (2) (3)

#dictdef-idbdatabaseinfo Referenced in:

- 4.3. The IDBFactory interface (2)

#dom-idbdatabaseinfo-name Referenced in:

- 4.3. The IDBFactory interface

#dom-idbdatabaseinfo-version Referenced in:

- 4.3. The IDBFactory interface

#dom-idbfactory-open Referenced in:

- 4.1. The IDBRequest interface
- 4.3. The IDBFactory interface (2) (3)

#dom-idbfactory-deletedatabase Referenced in:

- 4.3. The IDBFactory interface (2)

#dom-idbfactory-databases Referenced in:

- 4.3. The IDBFactory interface (2) (3)
- 10. Revision History

#dom-idbfactory-cmp Referenced in:

- 4.3. The IDBFactory interface (2)

#idbdatabase Referenced in:

- 4.1. The IDBRequest interface
- 4.4. The IDBDatabase interface (2) (3) (4) (5) (6) (7)
- 4.9. The IDBTransaction interface
- 5.8. Aborting an upgrade transaction (2) (3)

#dictdef-idbobjectstoreparameters Referenced in:

- 4.4. The IDBDatabase interface

#dom-idbobjectstoreparameters-keypath Referenced in:

- 4.4. The IDBDatabase interface

#dom-idbobjectstoreparameters-autoincrement Referenced in:

- 4.4. The IDBDatabase interface

#dom-idbdatabase-name Referenced in:

- 4.4. The IDBDatabase interface (2)
- 5.8. Aborting an upgrade transaction

#dom-idbdatabase-version Referenced in:

- 4.4. The IDBDatabase interface (2)
- 5.8. Aborting an upgrade transaction

#dom-idbdatabase-objectstorenames Referenced in:

- 4.4. The IDBDatabase interface (2) (3) (4)
- 5.8. Aborting an upgrade transaction

#dom-idbdatabase-createobjectstore Referenced in:

- 4.4. The IDBDatabase interface (2) (3)

#dom-idbdatabase-deleteobjectstore Referenced in:

- 4.4. The IDBDatabase interface (2)

#dom-idbdatabase-transaction Referenced in:

- 2.7.1. Transaction Lifecycle
- 2.7.3. Upgrade Transactions
- 4.4. The IDBDatabase interface (2)

#dom-idbdatabase-close Referenced in:

- 1. Introduction
- 4.4. The IDBDatabase interface (2) (3)
- 5.2. Closing a database

#dom-idbdatabase-onabort Referenced in:

- 4.4. The IDBDatabase interface

#dom-idbdatabase-onclose Referenced in:

- 4.4. The IDBDatabase interface

#dom-idbdatabase-onerror Referenced in:

- 4.4. The IDBDatabase interface

#dom-idbdatabase-onversionchange Referenced in:

- 4.4. The IDBDatabase interface

#idbobjectstore Referenced in:

- 4.1. The IDBRequest interface (2)
- 4.4. The IDBDatabase interface (2) (3)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2)
- 4.9. The IDBTransaction interface (2) (3) (4) (5)
- 5.8. Aborting an upgrade transaction (2) (3)

#dictdef-idbindexparameters Referenced in:

- 4.5. The IDBObjectStore interface

#dom-idbindexparameters-unique Referenced in:

- 4.5. The IDBObjectStore interface

#dom-idbindexparameters-multientry Referenced in:

- 4.5. The IDBObjectStore interface

#dom-idbobjectstore-name Referenced in:

- 4.5. The IDBObjectStore interface (2) (3) (4)
- 5.8. Aborting an upgrade transaction (2)

#dom-idbobjectstore-keypath Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-indexnames Referenced in:

- 4.5. The IDBObjectStore interface (2) (3) (4)
- 5.8. Aborting an upgrade transaction (2)

#dom-idbobjectstore-transaction Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-autoincrement Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-put Referenced in:

- 4.5. The IDBObjectStore interface (2) (3)

#dom-idbobjectstore-add Referenced in:

- 4.5. The IDBObjectStore interface (2) (3)

#add-or-put Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-delete Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-clear Referenced in:

- 2.11. Key Generators (2)
- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-get Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-getkey Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-getall Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-getallkeys Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-count Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-opencursor Referenced in:

- 4.5. The IDBObjectStore interface (2) (3)

#dom-idbobjectstore-openkeycursor Referenced in:

- 4.5. The IDBObjectStore interface (2)

#dom-idbobjectstore-createindex Referenced in:

- 4.5. The IDBObjectStore interface (2) (3) (4) (5)

#dom-idbobjectstore-index Referenced in:

- 4.5. The IDBObjectStore interface
- 5.8. Aborting an upgrade transaction

#dom-idbobjectstore-deleteindex Referenced in:

- 4.5. The IDBObjectStore interface (2)

#idbindex Referenced in:

- 4.1. The IDBRequest interface (2)
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2)
- 5.8. Aborting an upgrade transaction (2)

#dom-idbindex-name Referenced in:

- 4.6. The IDBIndex interface (2) (3) (4)
- 5.8. Aborting an upgrade transaction (2)

#dom-idbindex-objectstore Referenced in:

- 4.6. The IDBIndex interface (2)

#dom-idbindex-keypath Referenced in:

- 4.6. The IDBIndex interface

#dom-idbindex-multientry Referenced in:

- 4.6. The IDBIndex interface

#dom-idbindex-unique Referenced in:

- 4.6. The IDBIndex interface

#dom-idbindex-get Referenced in:

- 4.6. The IDBIndex interface (2)

#dom-idbindex-getkey Referenced in:

- 4.6. The IDBIndex interface (2)

#dom-idbindex-getall Referenced in:

- 4.6. The IDBIndex interface (2)

#dom-idbindex-getallkeys Referenced in:

- 4.6. The IDBIndex interface (2)

#dom-idbindex-count Referenced in:

- 4.6. The IDBIndex interface (2)

#dom-idbindex-opencursor Referenced in:

- 4.6. The IDBIndex interface (2) (3)

#dom-idbindex-openkeycursor Referenced in:

- 4.6. The IDBIndex interface (2)

#idbkeyrange Referenced in:

- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7)
- 4.7. The IDBKeyRange interface (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14)

#dom-idbkeyrange-lower Referenced in:

- 4.7. The IDBKeyRange interface (2)

#dom-idbkeyrange-upper Referenced in:

- 4.7. The IDBKeyRange interface (2)

#dom-idbkeyrange-loweropen Referenced in:

- 4.7. The IDBKeyRange interface (2)

#dom-idbkeyrange-upperopen Referenced in:

- 4.7. The IDBKeyRange interface (2)

#dom-idbkeyrange-only Referenced in:

- 4.7. The IDBKeyRange interface (2)

#dom-idbkeyrange-lowerbound Referenced in:

- 4.7. The IDBKeyRange interface (2)

#dom-idbkeyrange-upperbound Referenced in:

- 4.7. The IDBKeyRange interface (2)

#dom-idbkeyrange-bound Referenced in:

- 4.7. The IDBKeyRange interface (2)

#dom-idbkeyrange-includes Referenced in:

- 4.7. The IDBKeyRange interface (2)
- 10. Revision History

#idbcursor Referenced in:

- 4.1. The IDBRequest interface (2)
- 4.5. The IDBObjectStore interface
- 4.6. The IDBIndex interface
- 4.8. The IDBCursor interface (2) (3) (4)

#enumdef-idbcursordirection Referenced in:

- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface

#dom-idbcursordirection-next Referenced in:

- 2.10. Cursor (2)
- 4.8. The IDBCursor interface (2) (3) (4) (5)
- 6.7. Cursor Iteration Operation (2)

#dom-idbcursordirection-nextunique Referenced in:

- 2.10. Cursor
- 4.8. The IDBCursor interface (2)
- 6.7. Cursor Iteration Operation (2)

#dom-idbcursordirection-prev Referenced in:

- 2.10. Cursor (2)
- 4.8. The IDBCursor interface (2) (3) (4) (5)
- 6.7. Cursor Iteration Operation (2)

#dom-idbcursordirection-prevunique Referenced in:

- 2.10. Cursor
- 4.8. The IDBCursor interface (2)
- 6.7. Cursor Iteration Operation (2)

#dom-idbcursor-source Referenced in:

- 4.8. The IDBCursor interface (2)

#dom-idbcursor-direction Referenced in:

- 4.8. The IDBCursor interface (2)

#dom-idbcursor-key Referenced in:

- 4.8. The IDBCursor interface (2)

#dom-idbcursor-primarykey Referenced in:

- 4.8. The IDBCursor interface (2)

#dom-idbcursor-request Referenced in:

- 4.8. The IDBCursor interface (2) (3)
- 10. Revision History

#dom-idbcursor-advance Referenced in:

- 4.8. The IDBCursor interface (2) (3)

#dom-idbcursor-continue Referenced in:

- 4.8. The IDBCursor interface (2) (3) (4)

#dom-idbcursor-continueprimarykey Referenced in:

- 4.8. The IDBCursor interface (2) (3)

#dom-idbcursor-update Referenced in:

- 4.8. The IDBCursor interface (2)

#dom-idbcursor-delete Referenced in:

- 4.8. The IDBCursor interface (2)

#idbcursorwithvalue Referenced in:

- 4.5. The IDBObjectStore interface
- 4.6. The IDBIndex interface
- 4.8. The IDBCursor interface

#dom-idbcursorwithvalue-value Referenced in:

- 4.8. The IDBCursor interface (2)

#idbtransaction Referenced in:

- 4.1. The IDBRequest interface (2)
- 4.4. The IDBDatabase interface (2)
- 4.5. The IDBObjectStore interface
- 4.9. The IDBTransaction interface (2) (3) (4)
- 5.8. Aborting an upgrade transaction

#enumdef-idbtransactionmode Referenced in:

- 4.4. The IDBDatabase interface
- 4.9. The IDBTransaction interface

#dom-idbtransactionmode-readonly Referenced in:

- 2.7. Transactions (2)
- 4.4. The IDBDatabase interface (2)
- 4.9. The IDBTransaction interface

#dom-idbtransactionmode-readwrite Referenced in:

- 2.7. Transactions (2) (3)
- 4.4. The IDBDatabase interface (2)
- 4.9. The IDBTransaction interface

#dom-idbtransactionmode-versionchange Referenced in:

- 2.7. Transactions
- 2.7.3. Upgrade Transactions
- 4.9. The IDBTransaction interface

#dom-idbtransaction-objectstorenames Referenced in:

- 4.9. The IDBTransaction interface (2)

#dom-idbtransaction-mode Referenced in:

- 4.9. The IDBTransaction interface (2)

#dom-idbtransaction-db Referenced in:

- 4.9. The IDBTransaction interface (2)

#dom-idbtransaction-error Referenced in:

- 4.9. The IDBTransaction interface (2)
- 5.10. Firing an error event

#dom-idbtransaction-objectstore Referenced in:

- 4.9. The IDBTransaction interface (2)
- 5.8. Aborting an upgrade transaction

#dom-idbtransaction-abort Referenced in:

- 2.7.1. Transaction Lifecycle
- 4.9. The IDBTransaction interface (2)

#dom-idbtransaction-commit Referenced in:

- 2.7.1. Transaction Lifecycle
- 4.9. The IDBTransaction interface (2) (3) (4)
- 10. Revision History

#dom-idbtransaction-onabort Referenced in:

- 4.9. The IDBTransaction interface

#dom-idbtransaction-oncomplete Referenced in:

- 4.9. The IDBTransaction interface

#dom-idbtransaction-onerror Referenced in:

- 4.9. The IDBTransaction interface

#open-a-database Referenced in:

- 2.7.3. Upgrade Transactions
- 4.3. The IDBFactory interface

#close-a-database-connection Referenced in:

- 2.1.1. Database Connection (2)
- 4.4. The IDBDatabase interface
- 5.1. Opening a database

#delete-a-database Referenced in:

- 4.3. The IDBFactory interface
- 5.2. Closing a database

#commit-a-transaction Referenced in:

- 4.9. The IDBTransaction interface
- 5.7. Running an upgrade transaction
- 5.9. Firing a success event
- 5.10. Firing an error event

#abort-a-transaction Referenced in:

- 2.7.1. Transaction Lifecycle
- 4.4. The IDBDatabase interface
- 4.5. The IDBObjectStore interface
- 4.9. The IDBTransaction interface
- 5.2. Closing a database
- 5.4. Committing a transaction
- 5.6. Asynchronously executing a request (2)
- 5.7. Running an upgrade transaction (2)
- 5.8. Aborting an upgrade transaction
- 5.9. Firing a success event
- 5.10. Firing an error event (2)

#asynchronously-execute-a-request Referenced in:

- 2.8. Requests
- 4.5. The IDBObjectStore interface (2) (3) (4) (5) (6) (7) (8) (9) (10)
- 4.6. The IDBIndex interface (2) (3) (4) (5) (6) (7)
- 4.8. The IDBCursor interface (2) (3) (4) (5)
- 5.5. Aborting a transaction
- 6. Database operations

#run-an-upgrade-transaction Referenced in:

- 2.7.3. Upgrade Transactions
- 4.2. Event interfaces
- 5.1. Opening a database
- 5.2. Closing a database

#abort-an-upgrade-transaction Referenced in:

- 2.1.1. Database Connection
- 5.5. Aborting a transaction

#fire-a-success-event Referenced in:

- 4.3. The IDBFactory interface (2)
- 5.6. Asynchronously executing a request

#fire-an-error-event Referenced in:

- 4.3. The IDBFactory interface (2)
- 5.6. Asynchronously executing a request

#clone Referenced in:

- 4.5. The IDBObjectStore interface
- 4.8. The IDBCursor interface

#store-a-record-into-an-object-store Referenced in:

- 4.5. The IDBObjectStore interface
- 4.8. The IDBCursor interface (2)

#retrieve-a-value-from-an-object-store Referenced in:

- 4.5. The IDBObjectStore interface

#retrieve-multiple-values-from-an-object-store Referenced in:

- 4.5. The IDBObjectStore interface

#retrieve-a-key-from-an-object-store Referenced in:

- 4.5. The IDBObjectStore interface

#retrieve-multiple-keys-from-an-object-store Referenced in:

- 4.5. The IDBObjectStore interface

#retrieve-a-referenced-value-from-an-index Referenced in:

- 4.6. The IDBIndex interface

#retrieve-multiple-referenced-values-from-an-index Referenced in:

- 4.6. The IDBIndex interface

#retrieve-a-value-from-an-index Referenced in:

- 4.6. The IDBIndex interface

#retrieve-multiple-values-from-an-index Referenced in:

- 4.6. The IDBIndex interface

#delete-records-from-an-object-store Referenced in:

- 4.5. The IDBObjectStore interface
- 4.8. The IDBCursor interface
- 6.1. Object Store Storage Operation

#count-the-records-in-a-range Referenced in:

- 4.5. The IDBObjectStore interface
- 4.6. The IDBIndex interface

#clear-an-object-store Referenced in:

- 4.5. The IDBObjectStore interface

#iterate-a-cursor Referenced in:

- 4.5. The IDBObjectStore interface (2)
- 4.6. The IDBIndex interface (2)
- 4.8. The IDBCursor interface (2) (3)

#extract-a-key-from-a-value-using-a-key-path Referenced in:

- 2.6. Index
- 4.5. The IDBObjectStore interface
- 4.8. The IDBCursor interface
- 6.1. Object Store Storage Operation

#evaluate-a-key-path-on-a-value Referenced in:

- 7.1. Extract a key from a value (2)

#check-that-a-key-could-be-injected-into-a-value Referenced in:

- 4.5. The IDBObjectStore interface
- 7.2. Inject a key into a value

#inject-a-key-into-a-value-using-a-key-path Referenced in:

- 6.1. Object Store Storage Operation

#convert-a-key-to-a-value Referenced in:

- 4.7. The IDBKeyRange interface (2)
- 4.8. The IDBCursor interface (2)
- 6.2. Object Store Retrieval Operations (2)
- 6.3. Index Retrieval Operations (2)
- 7.2. Inject a key into a value
- 7.3. Convert a key to a value

#convert-a-value-to-a-key Referenced in:

- 2.4. Keys
- 2.9. Key Range
- 4.3. The IDBFactory interface (2)
- 4.5. The IDBObjectStore interface
- 4.7. The IDBKeyRange interface (2) (3) (4) (5) (6)
- 4.8. The IDBCursor interface (2) (3)
- 7.1. Extract a key from a value
- 7.4. Convert a value to a key (2) (3) (4)

#convert-a-value-to-a-multientry-key Referenced in:

- 7.1. Extract a key from a value