Closed jboulmal closed 7 years ago
The module is primary for browsers, but should in theory work on node if using indexeddbShim which now shims indexedDB on node using sqlite.
If you mean to build it, it is compatible with node 4 and node 6. I don't see any reason why it shouldn't be compatible with node 7 as well though.
I use node v6.5.0 when building.
$ node --version
v6.5.0
While trying Dexie.js
with IndexedDBShim. we got some errors :
{ MissingAPIError: indexedDB API not found. If using IE10+, make sure to run your code on a server URL (not locally). If using old Safari versions, make sure to include indexedDB polyfill.
at new e (~/dist/StorageManager.js:28:6136)
Error
at getErrorWithStack (~/node_modules/dexie/dist/dexie.js:309:12)
at new DexieError (~/node_modules/dexie/dist/dexie.js:420:19)
at ~/node_modules/dexie/dist/dexie.js:1971:35
at executePromiseTask (~/node_modules/dexie/dist/dexie.js:930:9)
at new Promise (~/node_modules/dexie/dist/dexie.js:723:5)
at Dexie.open (~/node_modules/dexie/dist/dexie.js:1957:45)
While trying Dexie.js with IndexedDBShim. we got some errors :
this is because dexie by default assumes there will be a global window
object (ie that global.window
will be defined), so you have to set
require("indexeddbshim").setGlobalVars(global);
global.window = global
Node's global
is shared across modules.
There is some information in IndexedDBShim's README about it https://github.com/axemclion/IndexedDBShim/blob/master/README.md#node-set-up
Thanks for the support. It has been solved a while ago as you suggested above. I forgot to close the issue. Cheers!
Happy that this was solved. However, Dexie does not rely on window to be defined though. You can provide the indexedDB api without putting it onto window.
var Dexie = require('dexie');
Dexie.dependencies.indexedDB = indexedDB;
Dexie.dependencies.IDBKeyRange = IDBKeyRange;
Also possible to set it per instance:
var db = new Dexie('dbname', {
indexedDB: indexedDB,
IDBKeyRange: IDBKeyRange
});
Also described in http://dexie.org/docs/Dexie/Dexie
Thanks for the your last suggestions @dfahlander. However, I got an error :
Dexie.dependencies.IDBKeyRange = IDBKeyRange;
^
ReferenceError: IDBKeyRange is not defined
Here is snippet of the code :
...........
import Dexie from 'dexie';
import indexedDB from 'indexeddbshim';
Dexie.dependencies.indexedDB = indexedDB;
Dexie.dependencies.IDBKeyRange = IDBKeyRange;
// global.window= global;
// setGlobalVars(global.window);
// window.shimIndexedDB.__useShim();
// cwindow.shimIndexedDB.__debug(true);
let storageName = 'cache';
const db = new Dexie(storageName, {
indexedDB: indexedDB,
IDBKeyRange: IDBKeyRange
// indexedDB: window.indexedDB, // or the shim's version
// IDBKeyRange: window.IDBKeyRange // or the shim's version.
});
IDBKeyRange must be extracted from the indexedDB module. Don't know what it exports, but in principle :
import {indexedDB, IDBKeyRange} from 'indexeddbshim';
Pinging @brettz9 for some help. Brett, is it possible to import {IDBKeyRange} along with indexedDB from indexeddbshim in node?
I have tried, I got again the window
is not defined error message!
Are you getting the error from Dexie or from the shim?
IDBKeyRange must be extracted from the indexedDB module. Don't know what it exports, but in principle :
import {indexedDB, IDBKeyRange} from 'indexeddbshim';
That would be a nice update imo, I think at the moment we might have to do something like:
var { Dexie } = require("dexie");
var setGlobalVars = require("indexeddbshim");
var thing = {};
setGlobalVars(thing);
var { indexedDB, IDBKeyRange } = thing;
var db = new Dexie("dbname", {
indexedDB: indexedDB,
IDBKeyRange: IDBKeyRange
});
We can't easily use indexeddbshim
's internal modules directly either because there is a build step.
Happy that this was solved. However, Dexie does not rely on window to be defined though.
@dfahlander Ah my mistake, thanks for correcting me!
Note: you'll have to use the master branch of indexeddbshim
at the moment, because the latest release doesn't support Node.
@dfahlander Are you getting the error from Dexie or from the shim?
The error is from the shim not Dexie. However, I don't have errors! If I define window as global in Node as the following:
let Dexie = require("dexie");
let setGlobalVars = require("indexeddbshim");
global.window= global;
setGlobalVars(global.window);
window.shimIndexedDB.__useShim();
cwindow.shimIndexedDB.__debug(true);
let storageName = 'cache';
const db = new Dexie(storageName, {
indexedDB: window.indexedDB, // or the shim's version
IDBKeyRange: window.IDBKeyRange // or the shim's version.
});
@erikvold I'll try your code!
Will try to take a look as I have a chance--trying to wrap up a current PR first...
This is now being reported as fixed (per changes in master
) at https://github.com/axemclion/IndexedDBShim/issues/259 .
Regarding the ideal export syntax for IndexedDBShim, I sympathize with that and added issue https://github.com/axemclion/IndexedDBShim/issues/283 . Note, however, that our current approach allows us to define the properties as non-enumerable, etc. as is expected by W3C tests.
I was struggling with this as well.
This is what worked for me.
const db = (name => {
require('indexeddbshim')(global);
let Dexie = require('dexie');
global.shimIndexedDB.__useShim();
global.shimIndexedDB.__setConfig({checkOrigin: false});
return new Dexie(name, {
indexedDB: global.indexedDB,
IDBKeyRange: global.IDBKeyRange
});
})('cache');
This did not require me to define window as global, also i was getting origin errors when doing a db.open so i had to disable shimIndexedDB's checkOrigin
A quick cut/paste example, based on the responses above:
const setGlobalVars = require('indexeddbshim')
const Dexie = require('dexie')
//
// Configure Dexie to use the IndexedDB shim.
//
// The intermediary shim object is required so we can pull out the objects
// we need to configure Dexie without needing to pollute the global namespace.
//
// checkOrigin:false is required to avoid SecurityError Cannot open
// an IndexedDB database from an opaque origin.
//
const shim = {}
setGlobalVars(shim, {checkOrigin: false})
const { indexedDB, IDBKeyRange } = shim
Dexie.dependencies.indexedDB = indexedDB
Dexie.dependencies.IDBKeyRange = IDBKeyRange
// Test Dexie
const db = new Dexie('hellodb')
db.version(1).stores({
tasks: '++id,date,description,done'
})
db.tasks.bulkPut([
{date: Date.now(), description: 'First item', done: 0},
{data: Date.now(), description: 'Second item', done: 1},
{data: Date.now(), description: 'Third item', done: 0}
]).then(() => {
db.tasks.where('done').above(0).toArray().then((tasks) => {
console.log(`Completed tasks: ${JSON.stringify(tasks, 0, 2)}`)
})
}).catch((e) => {
console.error(`Error: ${e}`)
})
I'm trying to use Jest to test some database stuff using TypeScript. Can't get the shim thing working in TypeScript. So what I did was have a regular .js file with the configuration code and export it as a function called configureDexieForNode
. And then I call that function in my Jest tests in a beforeAll
method. It works! But how do I reset Dexie in the afterAll
so it works in the browser? How to get it back to its regular/normal state when not in the testing environment?
const setGlobalVars = require('indexeddbshim')
const Dexie = require('dexie')
export function configureDexieForNode() {
const shim = {}
setGlobalVars(shim, {
checkOrigin: false
})
const {
indexedDB,
IDBKeyRange
} = shim
Dexie.dependencies.indexedDB = indexedDB
Dexie.dependencies.IDBKeyRange = IDBKeyRange
}
@jmagaram Your function configureDexieForNode() should not run in beforeAll, but once, globally per node process, and never for browser. There's no such thing as resetting it back to normal since we're talking about two different environments requiring different setups. I think you could go for calling configureDexieForNode() using Jest's global setup configuration.
Hello, Thank you for this awesome work! This is question rather than an issue. Is this Module compatible with the latest version of Node ? Thanks