dexie / dexie.js Goto Github PK
View Code? Open in Web Editor NEWA Minimalistic Wrapper for IndexedDB
Home Page: https://dexie.org
License: Apache License 2.0
A Minimalistic Wrapper for IndexedDB
Home Page: https://dexie.org
License: Apache License 2.0
When trying to use Dexie on Safari 8 that now has IndexedDB support, you get an error saying Dexie specification of currently installed DB version is missing
.
Have you had the change to test Dexie on Mac OS X/iOS?
When reproducting issue #30, a database-global error catcher did not catch DOMException that index was not found.
Expected behavior is that if any db operation fails and isnt catched using the Promise.catch() method, then it should bubble up to db.on('error') so that you could be certain that all errors are logged somewhere even if you forget to catch your operations or transactions. This should happen not only for error events but also for exceptions.
In this case, a DOMException was thrown in the Dexie internal code that could be catched and logged, but if adding db.on('error', function (){...}) and removing the .catch() clause, the error callback were never called.
First off, thanks for this great library!
I have a use case where I (for dev purposes) want to have a button to delete all databases. Thanks to Dexie.getDatabaseNames()
I can get all names, and I can call Dexie.delete()
, but all I get are promises that never resolves/rejects because I have open connections to these databases around my application.
Since Dexie returns all instances, would it be possible to have some internal tracking of all open connections to allow this to work? Something like a Dexie.deleteAllDatabases()
which would first iterate over all open connections, close them and then delete them?
I found an issue in how Dexie deals with contexts within hooks.
Trying to use this code:
db.table.hook("creating", this._onCreate.bind(this, "Series"));
It causes the _onCreate function to lose access to the context needed for .onsuccess. This is causing me to create an anonymous function to call my own function.
var self = this;
db.season.hook("creating", function (primKey, obj, trans) {
this.onsuccess = self._onCreate.bind(self, "Season", primKey, obj, trans)
});
The documentation speaks of a db.syncable.setFilter()
method, but I'm unable to find it. I went in the code history to the day the documentation was last modified and I'm not able to find any trace of it. What am I missing?
So I can deploy with a minified fixed version. Thanks!
Is there any way to perform asynchronous operations when hooking into a table read? I have certain objectStores that contain objects with fields that are just IDs referring to objects in other objectStores. I was hoping I could use the reading hook to automatically dereference those fields, which would require further database reads. As far as I can tell, the function in the reading hook must only contain synchronous operations.
I can do the dereferencing somewhere other than a read hook, of course, but there seemed like a nice place for it.
Itβs probably not as frequent a use case as running it on browsers, but it would be nice if Dexie.js was truly cross-platform.
For example, if sorting strings in a different locale than the browser/environment default, there is no way to tell sortBy() to use string.localeCompare instead of relational operators. Of course, you can just chain a new promise that does the sort and resolves as necessary, but having the capability built in seems handy.
Hi
I think you have an awesome library, but I'm not sure about certain things. Where can I ask questions? will you be setting up a Google group for discussions or some other means?
Thanks
Marc
The documentation speaks about: db.syncable.delete(url).
However it seems to me it does not exist in the code.
I want to use this to be able todo an full resync from scratch.
What is the best aproach to do that?
Hello
I have a table whose primary key is a compound index. When calling Table.put
, the action fails when setByKeyPath
is called because the idbstore.keyPath
resolves to a DOMStringList
and not an Array.
I'm guessing the possible solutions would be to:
Array
like structures (object that contain a length
property)DOMStringList
idbstore.keyPath
, rely on this.schema.primKey.keyPath
.
Hello.
I tried to query the database using a compound index and anyOf, but it threw a few exceptions. The first being that the key passed to continue was the same as the current key. Which is a simple fix, because Dexie is comparing the key values using === which doesn't work on array keys. The second problem was that the bound keys had the lower key being larger then the higher key. Probably another simple fix.
Would you be for/against changing the Markdown to non-standard markdown for syntax highlighting? I don't mind doing it but want to check if it's OK to do so.
Before:-
After:-
Before:-
// code is just indented by 4 spaces
After:-
```js
// code is not indented but headed & tailed by three backticks,
// the head including the language name, js
```
Using the NPM package, I end up with a BOM in the middle of my JS build output. While browserify possibly removes the BOM (browserify/browserify#313), unless there was a regression, I am using es6ify and reactify transforms that might mess with this.
Its my understanding that a BOM is not recommended in UTF-8, and it would be a lot painless, if removed.
I currently have a problem with Dexie when I try it out with our existing indexedDb (already created in my browser by earlier code). The db seems to be blocked and the code never gets to the resolve parts in the promises parts.
Is this usecase (existing db with some indices) not supported?
It works with a small toy db built from scratch with Dexie with code in the same project.
The latest version available on npm is 0.9.9. Could you please publish the latest version?
Safari on iPad Air (iOS 8.1.2)
Dexie.open() results in the error "Error: NotFoundError: DOM IDBDatabase Exception 8"
Example:
<script src='/js/vendor/Dexie.js'></script>
<script>
var idb = new Dexie('hockey');
idb.version(1)
.stores({
players: '&key, teamId, nationality'
});
idb.open()
.catch(function(error) {
alert(error.toString()); // Error: NotFoundError: DOM IDBDatabase Exception 8
});
</script>
IndexedDB is supported in iOS8. If a test page is created using the following example: http://www.raymondcamden.com/2014/09/25/IndexedDB-on-iOS-8-Broken-Bad ... this will function correctly, with IndexedDB successfully opening and storing data.
Happy to provide further details if required.
Hi, first got to say its a pleasure to work with yours library.
I think there is a issue with clear method it returns error when used with bind method, example:
var db = new Dexie('cleartest');
db.version(1).stores({
foo: '&id',
bar: '&id',
});
db.open();
db.foo.clear().then(db.bar.clear).catch(alert);
it errors with:
"TypeError: undefined is not an object (evaluating 'this.hook')"
Need to implement the or() method in Collection class.
Hi,
Am not sure if am doing anything stupid, but I see quite a bit of diff in performance while comparing these two:
https://gist.github.com/anonymous/18701cafb01b270488e0
https://gist.github.com/anonymous/240a8a4ddb97e8d9ed81
while on the desktop browser the difference is about 1sec, on mobile its more the 1 min (5sec vs 85sec) have you got any ideas? maybe be you some benchmarks etc? (mobile - using android chrome browser, on default android browser its slow too).
For an project i am creating an AngularJS wrapper for Dexie.
Are there other people who have done the same?
Or are there people who would like to have this?
(Also posted on google groups)
Tried making this as a jsfiddle, but couldn't get it to work, so here goes. Take the following code and put it in an HTML file:
<!DOCTYPE html>
<html>
<head></head>
<body>
<script src="https://raw.githubusercontent.com/dfahlander/Dexie.js/master/src/Dexie.js"></script>
<script>
var db = new Dexie("testdb");
db.version(1).stores({ table1: "id" });
db.on('error', function(err) { console.log(err); });
db.open().then(function () {
console.log("before");
throw "FOO";
console.log("after");
});
</script>
</body>
</html>
To be honest, I'm not entirely sure what is supposed to happen. If I comment out the on error handler, I expect to get FOO thrown at me. With the on error handler, I'm not so sure. But actually what happens in both cases is that I get "before" in the console and nothing else?
Tested with Firefox and Chromium. As you'd imagine, it's hard to develop stuff when messages on silly errors are suppressed.
I'm currently testing some of my code which uses the Dexie.js library in a Jasmine testing environment. When reloading the test page I randomly get the error "Uncaught Error: Dexie specification of currently installed DB version is missing" with the underlying DOM error "Version change transaction was aborted in upgradeneeded event handler.". The error randomly appears on page reload, but most of the time on every second reload.
I had a very hard time to reproduce the error but came up with a fiddle which at least in my Chrome browser sometimes produces the same error message on page reload:
http://jsfiddle.net/dasboe/vL66vxqw/
In the fiddel I run this code before each test:
db = new Dexie('test');
db.version(1).stores({
store1: 'id',
store2: 'id'
});
db.delete().then(function() {
return db.open();
}).then(done);
I'm pretty sure this is part of the problem but I can't tell if there is something I'm doing wrong or it's a problem on Dexies side.
In case the previous version's store was removed, and the upgrade function needs to copy items from it, it wont have access to the old store to do that. The use case is that an architecture has changed and objects from one store needs to be copied to another or splitted to several other stores.
There is also a bug in IE that prohibits reading from an object store before deleting the store. If fixing this enhancement we would also need to work around that IE bug by closing and reopening the database towards an intermediate version that would delete the old stores.
I'm evaluating Dexie.js for my client side DB needs and it seems very nice, but as a lazy reader I missed that I needed to open the database before anything happens. If I don't open it, no error is given anywhere but promises just don't trigger, which I wondered for a while.
I see that the rationale for the open to work the way it does is the queuing, which indeed is a nice feature to have (although I've still not fully grasped what's their role in comparison to transactions). However, having such a strong "internal state" that is easy to overlook is often a bit smelly. I think eg. the stores-method could return a new object to avoid the "stateness".
Our project uses Bluebird, and it would be quite nice to use its functionality with Dexie.
Would you be amenable to something like this at https://github.com/dfahlander/Dexie.js/blob/master/src/Dexie.js#L2156:
var Promise = Promise || (function () { }
This would automatically work with anything that provides Promise.
The addons directory is ignored in bower.json, and I'm planning to use Dexie.Observable.
A simple solution would be to remove the ignore line for addons, but I'm not submitting a pull request in case you intend to package these addons separately on bower.
Hi!
We're having some issues with running tests that use IndexedDB through Dexie. About a third of the test runs, we get timeouts from Mocka on promises returned by Dexie. It doesn't seem to help to increase the timeout, it's as if there's a deadlock somewhere. Does that ring any bell? Are we doing something we shouldn't? We're currently not explicitly closing the databases we're using, is that a problem?
We're running karma 0.12.22, and both Firefox and Chrome to run the tests.
For my projects i'm using grunt to build all javascript into one large file. However when i use bower install dexie it will use the minified source.
"main": "dist/latest/Dexie.min.js",
I would like to suggest to change this line (bower.json) into the not minified version.
My error when trying to build with grunt is:
Running "ngAnnotate:dist" (ngAnnotate) task
Generating ".tmp/concat/scripts/vendor.js" from ".tmp/concat/scripts/vendor.js"...ERROR
>> error: couldn't process source due to parse error
>> Line 43462: Unexpected token in
Warning: Task "ngAnnotate:dist" failed. Use --force to continue.
I have reproduced this error on an other dexie project.
I realize that Dexie has it's own promise implementation to work around the fact that an IndexedDB transaction is commited at the end of a tick. But it really bit me when it turned out that this code:
var promise = createDexiePromise();
console.log('1');
promise.then(function () {
console.log('2');
console.log('a');
promise.then(function () {
console.log('b');
});
console.log('c');
});
console.log('3');
Prints out:
1
3
2
a
b (this shouldn't come before c)
c
Instead of:
1
3
2
a
c
b
If Dexie needs to internally work with its promises in a way where the then
handler is called synchronously I think it would be best to add something like a thenSync
method, and let then
work as it does in other promise implementations.
I may be understanding something wrong, but I can't seem to find a clean way to hook into database modification operations (at least "creating", "deleting") so that I could easily get called back when the operation/transaction has been completed. Ie if I read the database during the creating/deleting or even creating.onsuccess/deleting.onsuccess, the database is still in the state that it was prior to the modification. If there's a "canonical" way on how it should be done, a hint in the documentation of the hooks would be great.
The rationale for such a hook is that I want to decouple the parts changing the DB and displaying the DB by just reacting to the state changes of the database. This is probably quite a common use case.
Detected by @landlockedsurfer, and added as a unit test "Table not in transaction 2" in tests-transaction.js.
"...While working on a project I noticed that the new test case in this pull request is not working as I would have expected. I.e. the transaction is processed fine, although the test adds an object to a table that is not listed in Dexie.transaction()."
asyncTest("Table not in transaction 2", function () {
return db.transaction('rw', db.users, function () {
db.pets.add({kind: "dog"});
}).then(function () {
ok(false, "Transaction should not commit because I made an error");
}).catch(function (err) {
ok(true, "Got error since we tried using a table not in transaction: " + err);
}).finally(start);
});
This is the biggest issue with Dexie. SRSLY. I've been in search of Dexie for quite a while, but didn't know that it existed. Instead, I've spent many hours evaluating the alternatives mentioned here:
https://github.com/dfahlander/Dexie.js/wiki/Dexie.js#other-competing-indexeddb-wrappers
How can we solve this problem?
Thank you for this great creation.
Hello,
First of all the Dexie.js is awesome, really enjoyed playing with it. Found a bug while trying to do an upgrade event. our upgrade version is lower than indexed Db version. version Dexie created was in multiples of 10
Example :
var db = new Dexie("DexieDBWrapper");
db.version(1).stores({friends: "++id,name,age"});
db.open();
Expected version : 1
Resulted version : 10
code :
var req = autoSchema ? indexedDB.open(dbName) : indexedDB.open(dbName, Math.round(db.verno * 10));
Is this intentional. if so curious to know why.
BTW Great job with Dexie wrapper !!!! Loving it.
Thanks
Hello,
First, thank you for Dexie.js, this is really a nice way to use IndexedDB!
At the moment it's possible to exec an asynchronous action in the table hooks (for example with a promise). But if a hook modifies the object (obj), it is actually not persisted because when the object is later fetched it bears no trace of the modification.
db.some_store.hook('creating', function(primKey, obj, trans) {
execAPromise();
});
Could there be a way to tell to wait until the async action is finalized?
Maybe something like the following:
db.some_store.hook('creating', function(primKey, obj, trans, done) {
execAPromise().then(done);
});
But it's not Promise-oriented at all :-(
Any ideas about it?
Thank you
hi, just wanted to check wether i am doing something wrong to get such "unstable" results.
i have played with dexie on top of Chrome and FFOS, as well as the webview on Android 4.1.2 up to 4.4 Kitkat, and on all of them the results of a query like below was different each time or so.
db.phones.where('name').startsWithIgnoreCase('moto'));
it seems to increase the occurrence, and even not responding at all when the OR
clause is included in the query chain.
db.phones.where('name').startsWithIgnoreCase('moto')).or('age').below('10'));
the only creepy thing i have done was creating a lot of indexes...(14) too much ?
var dbi = new Dexie("MyDB");
dbi.version(1).stores({
phones: "++id, additionalFeatures, android, availability, battery, camera, connectivity, description, display, hardware, id, images, name, sizeAndWeight, storage"
});
When using Integer indexes anyOf is handled incorrectly. E.g.
items.where('id').anyOf([2, 11]) throws: Failed to execute 'bound' on 'IDBKeyRange': The lower key is greater than the upper key.
This is probably due to wrong sorting of integer keys.
Related to the "dexie is not widely known" issue, getting a package registered on http://bower.io/search/ would probably be a good step. Thanks!
<<
The group [email protected] does not allow posting through email.
Most people would use email as an interface to the mailing list
I wonder why it's the default...
Also, if there is a way to make "receive mail for every post" as the default rather than "don't receive any emails" that would help since the default is not easily noticed and it's easy to sign up and never get any emails and assume there hasn't been any discussions.
In my protocol implementation i check first if there is an valid login. If it aint there i skip the sync in the following way:
var sync = function (context, url, options, baseRevision, syncedRevision, changes, partial, applyRemoteChanges, onChangesAccepted, onSuccess, onError) {
if (!isLoggedIn()) {
console.log("Not logged in!, calling onError");
onError("not logged in retry after five", 5000);
return;
}
// Skipped rest off code which is based on the AjaxSyncProtocol.js
}
after five seconds i see the status going to "SYNCING".
Nothing happens anymore after that.
My expectation was that it would try to sync again.
Or did i miss something?
Parts of my console.log:
Sync Status changed: CONNECTING
Not logged in!, calling onError
Sync Status changed: ERROR_WILL_RETRY
<after 5 seconds>
Sync Status changed: SYNCING
A a note for the docs (https://github.com/dfahlander/Dexie.js/wiki/Dexie.Syncable.js):
from the docs: db.syncable.on('statusChanged', function (url, newStatus)
I had to switch the order off the parameters url, newStatus
db.syncable.on('statusChanged', function (newStatus, syncUrl) {
$log.debug("Sync Status changed: ", syncUrl, Dexie.Syncable.StatusTexts[newStatus]);
});
In some race conditions it is possible that there will be created an seconde entry in the _syncNodes. This happend to me when i was firing an disconnect and a connect right after each other.
Example:
On the login page i tell that sync should be disconnected. However when running from an app it should take the saved credentials and perform an login.
db.syncable.disconnect(url);
// some more code
if (isCordovaApp) {
// do login
db.syncable.connect(provider,url);
}
This way i have seen more then one entry for the same url in the _syncNodes objectStore. I have fixed this in my code by changing the order and using the promises returned.
My biggest problem is that after running the resync it sometimes returns all the current object store contents as type 1 or type 3 to the backend in the next sync. When looking closely at it, i noticed that there where 2 sync connections instead off 1.
As you know i have created an resync option in the folowing steps:
I have added an log line in every step to see that everything goes in the right order. And that goes perfectly by using the promises of Dexie.
However since the last release the changes table is not cleaned right. Remember that delete just all entries? The current code deletes all changes entries before _syncNode.myrevision:
return db._changes.where("rev").below(oldestNode.myRevision).delete()
My problem is that step 2 (Removing the tables) will have an higher revision number. So all the deletes will be send to the server when connecting again!
This is not always the case, so i think it goes together with the multiple synchronisation issue.
What is the best way to check if there are changes waiting for an sync?
I think this could be an nice option for the syncable class.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.