2
votes

Working on a Chrome Extension, which needs to integrate with IndexedDB. Trying to figure out how to use Dexie.JS. Found a bunch of samples. Those don't look too complicated. There is one specific example particularly interesting for exploring IndexedDB with Dexie at https://github.com/dfahlander/Dexie.js/blob/master/samples/open-existing-db/dump-databases.html

However, when I run the one above - the "dump utility," it does not see IndexedDB databases, telling me: There are databases at the current origin.

From the developer tools Application tab, under Storage, I see my IndexedDB database.

Is this some sort of a permissions issue? Can any indexedDB database be accessed by any tab/user?

What should I be looking at?

Thank you

1
Own pages of an extension have their own origin. Content scripts use a web page origin. - wOxxOm

1 Answers

2
votes

In chrome/opera, there is a non-standard API webkitGetDatabaseNames() that Dexie.js uses to retrieve the list of database names on current origin. For other browsers, Dexie emulates this API by keeping an up-to-date database of database-names for each origin, so:

For chromium browsers, Dexie.getDatabaseNames() will list all databases at current origin, but for non-chromium browsers, only databases created with Dexie will be shown.

If you need to dump the contents of each database, have a look at this issue, that basically gives:

interface TableDump {
    table: string
    rows: any[]
}

function export(db: Dexie): TableDump[] {
    return db.transaction('r', db.tables, ()=>{
        return Promise.all(
            db.tables.map(table => table.toArray()
                .then(rows => ({table: table.name, rows: rows})));
    });
}

function import(data: TableDump[], db: Dexie) {
    return db.transaction('rw', db.tables, () => {
        return Promise.all(data.map (t =>
            db.table(t.table).clear()
              .then(()=>db.table(t.table).bulkAdd(t.rows)));
    });
}

Combine the functions with JSON.stringify() and JSON.parse() to fully serialize the data.

const db = new Dexie('mydb');
db.version(1).stores({friends: '++id,name,age'});

(async ()=>{
    // Export
    const allData = await export (db);
    const serialized = JSON.stringify(allData);

    // Import
    const jsonToImport = '[{"table": "friends", "rows": [{id:1,name:"foo",age:33}]}]';
    const dataToImport = JSON.parse(jsonToImport);
    await import(dataToImport, db);
})();