async execute(callback, options = { preload: [] }) {
    // Transactions in IndexedDB are autocommited when a callback does not
    // perform any additional operation.
    // The way Promises are implemented in Firefox (see https://bugzilla.mozilla.org/show_bug.cgi?id=1193394)
    // prevents using within an opened transaction.
    // To avoid managing asynchronocity in the specified `callback`, we preload
    // a list of record in order to execute the `callback` synchronously.
    // See also:
    // - http://stackoverflow.com/a/28388805/330911
    // - http://stackoverflow.com/a/10405196
    // - https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
    let result;
    await this.prepare(
      "records",
      (store, abort) => {
        const runCallback = (preloaded = []) => {
          // Expose a consistent API for every adapter instead of raw store methods.
          const proxy = transactionProxy(this, store, preloaded);
          // The callback is executed synchronously within the same transaction.
          try {
            const returned = callback(proxy);
            if (returned instanceof Promise) {
              // XXX: investigate how to provide documentation details in error.
              throw new Error(
                "execute() callback should not return a Promise."
              );
            }
            // Bring to scope that will be returned (once promise awaited).
            result = returned;
          } catch (e) {
            // The callback has thrown an error explicitly. Abort transaction cleanly.
            abort(e);
          }
        };

        // No option to preload records, go straight to `callback`.
        if (!options.preload.length) {
          return runCallback();
        }

        // Preload specified records using a list request.
        const filters = { id: options.preload };
        createListRequest(this.cid, store, filters, records => {
          // Store obtained records by id.
          const preloaded = records.reduce((acc, record) => {
            acc[record.id] = omitKeys(record, ["_cid"]);
            return acc;
          }, {});
          runCallback(preloaded);
        });
      },
      { mode: "readwrite" }
    );
    return result;
  }
/**
   * Executes the set of synchronous CRUD operations described in the provided
   * callback within an IndexedDB transaction, for current db store.
   *
   * The callback will be provided an object exposing the following synchronous
   * CRUD operation methods: get, create, update, delete.
   *
   * Important note: because limitations in IndexedDB implementations, no
   * asynchronous code should be performed within the provided callback; the
   * promise will therefore be rejected if the callback returns a Promise.
   *
   * Options:
   * - {Array} preload: The list of record IDs to fetch and make available to
   *   the transaction object get() method (default: [])
   *
   * @example
   * const db = new IDB("example");
   * const result = await db.execute(transaction => {
   *   transaction.create({id: 1, title: "foo"});
   *   transaction.update({id: 2, title: "bar"});
   *   transaction.delete(3);
   *   return "foo";
   * });
   *
   * @override
   * @param  {Function} callback The operation description callback.
   * @param  {Object}   options  The options object.
   * @return {Promise}
   */
Executes the set of synchronous CRUD operations described in the provided
callback within an IndexedDB transaction, for current db store.

The callback will be provided an object exposing the following synchronous
CRUD operation methods: get, create, update, delete.

Important note: because limitations in IndexedDB implementations, no
asynchronous code should be performed within the provided callback; the
promise will therefore be rejected if the callback returns a Promise.

- {Array} preload: The list of record IDs to fetch and make available to
the transaction object get() method (default: [])



@override
@param  {Function} callback The operation description callback.
@param  {Object}   options  The options object.
@return {Promise}
Executes the set of synchronous CRUD operations described in the provided callback within an IndexedDB transaction for current db store . The callback will be provided an object exposing the following synchronous CRUD operation methods : get create update delete . Important note : because limitations in IndexedDB implementations no asynchronous code should be performed within the provided callback ; the promise will therefore be rejected if the callback returns a Promise . - { Array } preload : The list of record IDs to fetch and make available to the transaction object get () method ( default : [] ) @override @param { Function } callback The operation description callback . @param { Object } options The options object . @return { Promise }
async execute(callback, options = { preload: [] }) {
    let result;
    await this.prepare(
      "records",
      (store, abort) => {
        const runCallback = (preloaded = []) => {
          const proxy = transactionProxy(this, store, preloaded);
          try {
            const returned = callback(proxy);
            if (returned instanceof Promise) {
              throw new Error(
                "execute() callback should not return a Promise."
              );
            }
            result = returned;
          } catch (e) {
            abort(e);
          }
        };
        if (!options.preload.length) {
          return runCallback();
        }
        const filters = { id: options.preload };
        createListRequest(this.cid, store, filters, records => {
          const preloaded = records.reduce((acc, record) => {
            acc[record.id] = omitKeys(record, ["_cid"]);
            return acc;
          }, {});
          runCallback(preloaded);
        });
      },
      { mode: "readwrite" }
    );
    return result;
  }
async execute ( callback , options = { preload : [ ] } ) { let result ; await this . prepare ( "records" , ( store , abort ) => { const runCallback = ( preloaded = [ ] ) => { const proxy = transactionProxy ( this , store , preloaded ) ; try { const returned = callback ( proxy ) ; if ( returned instanceof Promise ) { throw new Error ( "execute() callback should not return a Promise." ) ; } result = returned ; } catch ( e ) { abort ( e ) ; } } ; if ( ! options . preload . length ) { return runCallback ( ) ; } const filters = { id : options . preload } ; createListRequest ( this . cid , store , filters , records => { const preloaded = records . reduce ( ( acc , record ) => { acc [ record . id ] = omitKeys ( record , [ "_cid" ] ) ; return acc ; } , { } ) ; runCallback ( preloaded ) ; } ) ; } , { mode : "readwrite" } ) ; return result ; }
Executes the set of synchronous CRUD operations described in the provided
 callback within an IndexedDB transaction, for current db store.
Executes the set of synchronous CRUD operations described in the provided callback within an IndexedDB transaction for current db store .
// Transactions in IndexedDB are autocommited when a callback does not // perform any additional operation. // The way Promises are implemented in Firefox (see https://bugzilla.mozilla.org/show_bug.cgi?id=1193394) // prevents using within an opened transaction. // To avoid managing asynchronocity in the specified `callback`, we preload // a list of record in order to execute the `callback` synchronously. // See also: // - http://stackoverflow.com/a/28388805/330911 // - http://stackoverflow.com/a/10405196 // - https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ // Expose a consistent API for every adapter instead of raw store methods. // The callback is executed synchronously within the same transaction. // XXX: investigate how to provide documentation details in error. // Bring to scope that will be returned (once promise awaited). // The callback has thrown an error explicitly. Abort transaction cleanly. // No option to preload records, go straight to `callback`. // Preload specified records using a list request. // Store obtained records by id.