Re: [IndexedDB] Events and requests
If one handler changes the state who knows what will happen. I guess the order in which handers are called is significant. That's one advantage to using a function like "all" to compose callbacks - its very clear what order they get called in. You could call it 'sequence' to make it even clearer (that they are called one at a time left to right, not in parallel). You could make the callback an optional parameter, and use it if supplied, and return an object (for the existing API if none is supplied). Cheers, Keean. On 11 January 2011 09:31, Axel Rauschmayer wrote: > Looks great, I just tried to stay as close to the current API as possible. > > A single handler should definitely be enough. Can, say, a cursor be read > multiple times (if there are several success handlers)? Doesn’t that make > things more complicated? > > On Jan 11, 2011, at 10:22 , Keean Schupke wrote: > > Comments inline: > > On 11 January 2011 07:11, Axel Rauschmayer wrote: > >> Coming back to the initial message in this thread (at the very bottom): >> => General rule of thumb: clearly separate input data and output data. >> >> Using JavaScript dynamic nature, things could look as follows: >> >> indexedDB.open('AddressBook', 'Address Book', { >> success: function(evt) { >> }, >> error: function(evt) { >> } >> }); >> > > Personally I prefer a single callback passed an object. > > indexedDB.open('AddressBook', 'Address Book', function(event) { > switch(event.status) { > case EVENT_SUCCESS: > break; > case EVENT_ERROR: > break; > } > }); > > As it allows callbacks to be composed more easily. > > - The last argument is thus the request and clearly input. >> >> - If multiple success handlers are needed, success could be an array of >> functions (same for error handlers). >> > > multiple handlers can be passes using a composition function: > > // can be defined in the library > var all = function(flist) { >return function(event) { >for (int i = 0; i < flist.length; i++) { >flist[i](event); >} > }; > }; > > indexedDB.open('AddressBook', 'Address Book', all([fn1, fn2, fn3])); > > > Cheers, > Keean. > > > >> - I would eliminiate readyState and move abort() to IDBEvent (=output and >> an interface to the DB client). >> >> - With subclasses of IDBEvent one has the choice of eliminating them by >> making their fields additional parameters of success() and error(). >> event.result is a prime candidate for this! >> >> - This above way eliminates the need of manipulating the request *after* >> (a reference to) it has been placed in the event queue. >> >> Questions: >> >> - Is it really necessary to make IDBEvent a subclass of Event and thus >> drag the DOM (which seems to be universally hated) into IndexedDB? >> >> - Are there any other asynchronous DB APIs for dynamic languages that one >> could learn from (especially from mistakes that they have made)? They must >> have design principles and rationales one might be able to use. WebDatabase >> (minus schema plus cursor) looks nice. >> >> On Jan 10, 2011, at 23:40 , Keean Schupke wrote: >> >> Hi, >> >> I did say it was for fun! If you think it should be suggested somewhere I >> am happy to do so. Note that I renamed 'onsuccess' to 'bind' to show how it >> works as a monad, there is no need to do this (although I prefer to it to >> explicitly show it is a Monad). >> >> The definition of unit is simply: >> >> var unit = function(v) { >> return { >> onsuccess: function(f) {f(v);} >> }; >> }; >> >> And then you can compose callbacks using 'onsuccess'... >> >> you might like to keep onsuccess, and use "result" instead of "unit"... So >> simply using the above definition you can compose callbacks: >> >> var y = >> db.transaction(["foo"]).objectStore("foo").getM(mykey1).onsuccess(function(result1) >> { >> >> >> db.transaction(["foo"]).objectStore("foo").getM(mykey2).onsuccess(function(result2) >> { >> result(result1 + result2); >> }); >> }); >> >> >> Cheers, >> Keean. >> >> >> On 10 January 2011 22:31, Jonas Sicking wrote: >> >>> This seems like something better suggeseted to the lists at ECMA where >>> javascript (or rather ECMAScript) is being standardized. I hardly >>> think that a database API like indexedDB is the place to redefine how >>> javascript should handle asynchronous programming. >>> >>> / Jonas >>> >>> On Mon, Jan 10, 2011 at 2:26 PM, Keean Schupke wrote: >>> > Just to correct my cut and paste error, that was of course supposed to >>> be: >>> > var y = do { >>> > result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey1); >>> > result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); >>> > unit(result1 + result2); >>> > } >>> > >>> > Cheers, >>> > Keean. >>> > On 10 January 2011 22:24, Keean Schupke wrote: >>> >> >>> >> Okay, sorry, the original change seemed sensible, I guess I didn't see >>> how >>> >> you got
Re: [IndexedDB] Events and requests
Looks great, I just tried to stay as close to the current API as possible. A single handler should definitely be enough. Can, say, a cursor be read multiple times (if there are several success handlers)? Doesn’t that make things more complicated? On Jan 11, 2011, at 10:22 , Keean Schupke wrote: > Comments inline: > > On 11 January 2011 07:11, Axel Rauschmayer wrote: > Coming back to the initial message in this thread (at the very bottom): > => General rule of thumb: clearly separate input data and output data. > > Using JavaScript dynamic nature, things could look as follows: > > indexedDB.open('AddressBook', 'Address Book', { > success: function(evt) { > }, > error: function(evt) { > } > }); > > Personally I prefer a single callback passed an object. > > indexedDB.open('AddressBook', 'Address Book', function(event) { > switch(event.status) { > case EVENT_SUCCESS: > break; > case EVENT_ERROR: > break; > } > }); > > As it allows callbacks to be composed more easily. > > - The last argument is thus the request and clearly input. > > - If multiple success handlers are needed, success could be an array of > functions (same for error handlers). > > multiple handlers can be passes using a composition function: > > // can be defined in the library > var all = function(flist) { >return function(event) { >for (int i = 0; i < flist.length; i++) { >flist[i](event); >} > }; > }; > > indexedDB.open('AddressBook', 'Address Book', all([fn1, fn2, fn3])); > > > Cheers, > Keean. > > > > - I would eliminiate readyState and move abort() to IDBEvent (=output and an > interface to the DB client). > > - With subclasses of IDBEvent one has the choice of eliminating them by > making their fields additional parameters of success() and error(). > event.result is a prime candidate for this! > > - This above way eliminates the need of manipulating the request *after* (a > reference to) it has been placed in the event queue. > > Questions: > > - Is it really necessary to make IDBEvent a subclass of Event and thus drag > the DOM (which seems to be universally hated) into IndexedDB? > > - Are there any other asynchronous DB APIs for dynamic languages that one > could learn from (especially from mistakes that they have made)? They must > have design principles and rationales one might be able to use. WebDatabase > (minus schema plus cursor) looks nice. > > On Jan 10, 2011, at 23:40 , Keean Schupke wrote: > >> Hi, >> >> I did say it was for fun! If you think it should be suggested somewhere I >> am happy to do so. Note that I renamed 'onsuccess' to 'bind' to show how it >> works as a monad, there is no need to do this (although I prefer to it to >> explicitly show it is a Monad). >> >> The definition of unit is simply: >> >> var unit = function(v) { >> return { >> onsuccess: function(f) {f(v);} >> }; >> }; >> >> And then you can compose callbacks using 'onsuccess'... >> >> you might like to keep onsuccess, and use "result" instead of "unit"... So >> simply using the above definition you can compose callbacks: >> >> var y = >> db.transaction(["foo"]).objectStore("foo").getM(mykey1).onsuccess(function(result1) >> { >> >> db.transaction(["foo"]).objectStore("foo").getM(mykey2).onsuccess(function(result2) >> { >> result(result1 + result2); >> }); >> }); >> >> >> Cheers, >> Keean. >> >> >> On 10 January 2011 22:31, Jonas Sicking wrote: >> This seems like something better suggeseted to the lists at ECMA where >> javascript (or rather ECMAScript) is being standardized. I hardly >> think that a database API like indexedDB is the place to redefine how >> javascript should handle asynchronous programming. >> >> / Jonas >> >> On Mon, Jan 10, 2011 at 2:26 PM, Keean Schupke wrote: >> > Just to correct my cut and paste error, that was of course supposed to be: >> > var y = do { >> > result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey1); >> > result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); >> > unit(result1 + result2); >> > } >> > >> > Cheers, >> > Keean. >> > On 10 January 2011 22:24, Keean Schupke wrote: >> >> >> >> Okay, sorry, the original change seemed sensible, I guess I didn't see how >> >> you got from there to promises. >> >> >> >> Here's some fun to think about as an alternative though: >> >> >> >> Interestingly the pattern of multiple callbacks, providing each callback >> >> is passed zero or one parameter forms a Monad. >> >> So for example if 'unit' is the constructor for the object returned from >> >> "get" then onsuccess it 'bind' and I can show that these obey the 3 monad >> >> laws. Allowing composability of callbacks. So you effectively have: >> >> var x = db.transaction(["foo"]).objectStore("foo").getM(mykey); >> >> var y = >> >> db.transaction(["foo"]).objectStore("foo").getM(mykey1).b
Re: [IndexedDB] Events and requests
Comments inline: On 11 January 2011 07:11, Axel Rauschmayer wrote: > Coming back to the initial message in this thread (at the very bottom): > => General rule of thumb: clearly separate input data and output data. > > Using JavaScript dynamic nature, things could look as follows: > > indexedDB.open('AddressBook', 'Address Book', { > success: function(evt) { > }, > error: function(evt) { > } > }); > Personally I prefer a single callback passed an object. indexedDB.open('AddressBook', 'Address Book', function(event) { switch(event.status) { case EVENT_SUCCESS: break; case EVENT_ERROR: break; } }); As it allows callbacks to be composed more easily. - The last argument is thus the request and clearly input. > > - If multiple success handlers are needed, success could be an array of > functions (same for error handlers). > multiple handlers can be passes using a composition function: // can be defined in the library var all = function(flist) { return function(event) { for (int i = 0; i < flist.length; i++) { flist[i](event); } }; }; indexedDB.open('AddressBook', 'Address Book', all([fn1, fn2, fn3])); Cheers, Keean. > - I would eliminiate readyState and move abort() to IDBEvent (=output and > an interface to the DB client). > > - With subclasses of IDBEvent one has the choice of eliminating them by > making their fields additional parameters of success() and error(). > event.result is a prime candidate for this! > > - This above way eliminates the need of manipulating the request *after* (a > reference to) it has been placed in the event queue. > > Questions: > > - Is it really necessary to make IDBEvent a subclass of Event and thus drag > the DOM (which seems to be universally hated) into IndexedDB? > > - Are there any other asynchronous DB APIs for dynamic languages that one > could learn from (especially from mistakes that they have made)? They must > have design principles and rationales one might be able to use. WebDatabase > (minus schema plus cursor) looks nice. > > On Jan 10, 2011, at 23:40 , Keean Schupke wrote: > > Hi, > > I did say it was for fun! If you think it should be suggested somewhere I > am happy to do so. Note that I renamed 'onsuccess' to 'bind' to show how it > works as a monad, there is no need to do this (although I prefer to it to > explicitly show it is a Monad). > > The definition of unit is simply: > > var unit = function(v) { > return { > onsuccess: function(f) {f(v);} > }; > }; > > And then you can compose callbacks using 'onsuccess'... > > you might like to keep onsuccess, and use "result" instead of "unit"... So > simply using the above definition you can compose callbacks: > > var y = > db.transaction(["foo"]).objectStore("foo").getM(mykey1).onsuccess(function(result1) > { > > > db.transaction(["foo"]).objectStore("foo").getM(mykey2).onsuccess(function(result2) > { > result(result1 + result2); > }); > }); > > > Cheers, > Keean. > > > On 10 January 2011 22:31, Jonas Sicking wrote: > >> This seems like something better suggeseted to the lists at ECMA where >> javascript (or rather ECMAScript) is being standardized. I hardly >> think that a database API like indexedDB is the place to redefine how >> javascript should handle asynchronous programming. >> >> / Jonas >> >> On Mon, Jan 10, 2011 at 2:26 PM, Keean Schupke wrote: >> > Just to correct my cut and paste error, that was of course supposed to >> be: >> > var y = do { >> > result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey1); >> > result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); >> > unit(result1 + result2); >> > } >> > >> > Cheers, >> > Keean. >> > On 10 January 2011 22:24, Keean Schupke wrote: >> >> >> >> Okay, sorry, the original change seemed sensible, I guess I didn't see >> how >> >> you got from there to promises. >> >> >> >> Here's some fun to think about as an alternative though: >> >> >> >> Interestingly the pattern of multiple callbacks, providing each >> callback >> >> is passed zero or one parameter forms a Monad. >> >> So for example if 'unit' is the constructor for the object returned >> from >> >> "get" then onsuccess it 'bind' and I can show that these obey the 3 >> monad >> >> laws. Allowing composability of callbacks. So you effectively have: >> >> var x = db.transaction(["foo"]).objectStore("foo").getM(mykey); >> >> var y = >> >> >> db.transaction(["foo"]).objectStore("foo").getM(mykey1).bind(function(result1) >> >> { >> >> >> >> >> >> db.transaction(["foo"]).objectStore("foo").getM(mykey2).bind(function(result2) >> >> { >> >> unit(result1 + result2); >> >> }); >> >> }); >> >> The two objects returned "x" and "y" are both the same kind of object. >> y >> >> represents the sum or concatination of the results of the lookups >> "mykey1" >> >> and "mykey2". You would use it identically to using the res
Re: [IndexedDB] Events and requests
Coming back to the initial message in this thread (at the very bottom): => General rule of thumb: clearly separate input data and output data. Using JavaScript dynamic nature, things could look as follows: indexedDB.open('AddressBook', 'Address Book', { success: function(evt) { }, error: function(evt) { } }); - The last argument is thus the request and clearly input. - If multiple success handlers are needed, success could be an array of functions (same for error handlers). - I would eliminiate readyState and move abort() to IDBEvent (=output and an interface to the DB client). - With subclasses of IDBEvent one has the choice of eliminating them by making their fields additional parameters of success() and error(). event.result is a prime candidate for this! - This above way eliminates the need of manipulating the request *after* (a reference to) it has been placed in the event queue. Questions: - Is it really necessary to make IDBEvent a subclass of Event and thus drag the DOM (which seems to be universally hated) into IndexedDB? - Are there any other asynchronous DB APIs for dynamic languages that one could learn from (especially from mistakes that they have made)? They must have design principles and rationales one might be able to use. WebDatabase (minus schema plus cursor) looks nice. On Jan 10, 2011, at 23:40 , Keean Schupke wrote: > Hi, > > I did say it was for fun! If you think it should be suggested somewhere I am > happy to do so. Note that I renamed 'onsuccess' to 'bind' to show how it > works as a monad, there is no need to do this (although I prefer to it to > explicitly show it is a Monad). > > The definition of unit is simply: > > var unit = function(v) { > return { > onsuccess: function(f) {f(v);} > }; > }; > > And then you can compose callbacks using 'onsuccess'... > > you might like to keep onsuccess, and use "result" instead of "unit"... So > simply using the above definition you can compose callbacks: > > var y = > db.transaction(["foo"]).objectStore("foo").getM(mykey1).onsuccess(function(result1) > { > > db.transaction(["foo"]).objectStore("foo").getM(mykey2).onsuccess(function(result2) > { > result(result1 + result2); > }); > }); > > > Cheers, > Keean. > > > On 10 January 2011 22:31, Jonas Sicking wrote: > This seems like something better suggeseted to the lists at ECMA where > javascript (or rather ECMAScript) is being standardized. I hardly > think that a database API like indexedDB is the place to redefine how > javascript should handle asynchronous programming. > > / Jonas > > On Mon, Jan 10, 2011 at 2:26 PM, Keean Schupke wrote: > > Just to correct my cut and paste error, that was of course supposed to be: > > var y = do { > > result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey1); > > result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); > > unit(result1 + result2); > > } > > > > Cheers, > > Keean. > > On 10 January 2011 22:24, Keean Schupke wrote: > >> > >> Okay, sorry, the original change seemed sensible, I guess I didn't see how > >> you got from there to promises. > >> > >> Here's some fun to think about as an alternative though: > >> > >> Interestingly the pattern of multiple callbacks, providing each callback > >> is passed zero or one parameter forms a Monad. > >> So for example if 'unit' is the constructor for the object returned from > >> "get" then onsuccess it 'bind' and I can show that these obey the 3 monad > >> laws. Allowing composability of callbacks. So you effectively have: > >> var x = db.transaction(["foo"]).objectStore("foo").getM(mykey); > >> var y = > >> db.transaction(["foo"]).objectStore("foo").getM(mykey1).bind(function(result1) > >> { > >> > >> > >> db.transaction(["foo"]).objectStore("foo").getM(mykey2).bind(function(result2) > >> { > >> unit(result1 + result2); > >> }); > >> }); > >> The two objects returned "x" and "y" are both the same kind of object. y > >> represents the sum or concatination of the results of the lookups "mykey1" > >> and "mykey2". You would use it identically to using the result of a single > >> lookup: > >> x.bind(function(result) {... display the result of a single lookup ...}); > >> y.bind(function(result) {... display the result of both lookups ...}); > >> > >> If we could then have some syntactic sugar for this like haskell's do > >> notation we could write: > >> var y = do { > >> db.transaction(["foo"]).objectStore("foo").getM(mykey1); > >> result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); > >> result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); > >> unit(result1 + result2); > >> } > >> Which would be a very neat way of chaining callbacks... > >> > >> Cheers, > >> Keean. > >> > >> On 10 January 2011 22:00, Keean Schupke wrote: > >>> > >>> Whats wrong with callbacks? To me this seems an unnecessary complication. > >>> Presumably
Re: [IndexedDB] Events and requests
Hi, I did say it was for fun! If you think it should be suggested somewhere I am happy to do so. Note that I renamed 'onsuccess' to 'bind' to show how it works as a monad, there is no need to do this (although I prefer to it to explicitly show it is a Monad). The definition of unit is simply: var unit = function(v) { return { onsuccess: function(f) {f(v);} }; }; And then you can compose callbacks using 'onsuccess'... you might like to keep onsuccess, and use "result" instead of "unit"... So simply using the above definition you can compose callbacks: var y = db.transaction(["foo"]).objectStore("foo").getM(mykey1).onsuccess(function(result1) { db.transaction(["foo"]).objectStore("foo").getM(mykey2).onsuccess(function(result2) { result(result1 + result2); }); }); Cheers, Keean. On 10 January 2011 22:31, Jonas Sicking wrote: > This seems like something better suggeseted to the lists at ECMA where > javascript (or rather ECMAScript) is being standardized. I hardly > think that a database API like indexedDB is the place to redefine how > javascript should handle asynchronous programming. > > / Jonas > > On Mon, Jan 10, 2011 at 2:26 PM, Keean Schupke wrote: > > Just to correct my cut and paste error, that was of course supposed to > be: > > var y = do { > > result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey1); > > result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); > > unit(result1 + result2); > > } > > > > Cheers, > > Keean. > > On 10 January 2011 22:24, Keean Schupke wrote: > >> > >> Okay, sorry, the original change seemed sensible, I guess I didn't see > how > >> you got from there to promises. > >> > >> Here's some fun to think about as an alternative though: > >> > >> Interestingly the pattern of multiple callbacks, providing each callback > >> is passed zero or one parameter forms a Monad. > >> So for example if 'unit' is the constructor for the object returned from > >> "get" then onsuccess it 'bind' and I can show that these obey the 3 > monad > >> laws. Allowing composability of callbacks. So you effectively have: > >> var x = db.transaction(["foo"]).objectStore("foo").getM(mykey); > >> var y = > >> > db.transaction(["foo"]).objectStore("foo").getM(mykey1).bind(function(result1) > >> { > >> > >> > > db.transaction(["foo"]).objectStore("foo").getM(mykey2).bind(function(result2) > >> { > >> unit(result1 + result2); > >> }); > >> }); > >> The two objects returned "x" and "y" are both the same kind of object. y > >> represents the sum or concatination of the results of the lookups > "mykey1" > >> and "mykey2". You would use it identically to using the result of a > single > >> lookup: > >> x.bind(function(result) {... display the result of a single lookup > ...}); > >> y.bind(function(result) {... display the result of both lookups ...}); > >> > >> If we could then have some syntactic sugar for this like haskell's do > >> notation we could write: > >> var y = do { > >> db.transaction(["foo"]).objectStore("foo").getM(mykey1); > >> result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); > >> result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); > >> unit(result1 + result2); > >> } > >> Which would be a very neat way of chaining callbacks... > >> > >> Cheers, > >> Keean. > >> > >> On 10 January 2011 22:00, Keean Schupke wrote: > >>> > >>> Whats wrong with callbacks? To me this seems an unnecessary > complication. > >>> Presumably you would do: > >>> var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); > >>> var result = promise.get(); > >>> if (!result) { > >>> promise.onsuccess(function(res) {...X...}); > >>> } else { > >>> ...Y... > >>> } > >>> > >>> So you end up having to duplicate code at X and Y to do the same thing > >>> directly or in the context of a callback. Or you define a function to > >>> process the result: > >>> var f = function(res) {...X...}; > >>> var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); > >>> var result = promise.get(); > >>> if (!result) { > >>> promise.onsuccess(f); > >>> } else { > >>> f(result) > >>> }; > >>> But in which case what advantage does all this extra clutter offer > over: > >>> > >>> > db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess(function(res) > >>> {...X...}); > >>> > >>> I am just wondering whether the change is worth the added complexity? > >>> > >>> Cheers, > >>> Keean. > >>> > >>> On 10 January 2011 21:31, Jonas Sicking wrote: > > I did some outreach to developers and while I didn't get a lot of > feedback, what I got was positive to this change. > > The basic use-case that was brought up was implementing a promises > which, as I understand it, works similar to the request model I'm > proposing. I.e. you build up these "promise" objects which represent a > result which may or may not have arrived yet. At some
Re: [IndexedDB] Events and requests
This seems like something better suggeseted to the lists at ECMA where javascript (or rather ECMAScript) is being standardized. I hardly think that a database API like indexedDB is the place to redefine how javascript should handle asynchronous programming. / Jonas On Mon, Jan 10, 2011 at 2:26 PM, Keean Schupke wrote: > Just to correct my cut and paste error, that was of course supposed to be: > var y = do { > result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey1); > result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); > unit(result1 + result2); > } > > Cheers, > Keean. > On 10 January 2011 22:24, Keean Schupke wrote: >> >> Okay, sorry, the original change seemed sensible, I guess I didn't see how >> you got from there to promises. >> >> Here's some fun to think about as an alternative though: >> >> Interestingly the pattern of multiple callbacks, providing each callback >> is passed zero or one parameter forms a Monad. >> So for example if 'unit' is the constructor for the object returned from >> "get" then onsuccess it 'bind' and I can show that these obey the 3 monad >> laws. Allowing composability of callbacks. So you effectively have: >> var x = db.transaction(["foo"]).objectStore("foo").getM(mykey); >> var y = >> db.transaction(["foo"]).objectStore("foo").getM(mykey1).bind(function(result1) >> { >> >> db.transaction(["foo"]).objectStore("foo").getM(mykey2).bind(function(result2) >> { >> unit(result1 + result2); >> }); >> }); >> The two objects returned "x" and "y" are both the same kind of object. y >> represents the sum or concatination of the results of the lookups "mykey1" >> and "mykey2". You would use it identically to using the result of a single >> lookup: >> x.bind(function(result) {... display the result of a single lookup ...}); >> y.bind(function(result) {... display the result of both lookups ...}); >> >> If we could then have some syntactic sugar for this like haskell's do >> notation we could write: >> var y = do { >> db.transaction(["foo"]).objectStore("foo").getM(mykey1); >> result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); >> result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); >> unit(result1 + result2); >> } >> Which would be a very neat way of chaining callbacks... >> >> Cheers, >> Keean. >> >> On 10 January 2011 22:00, Keean Schupke wrote: >>> >>> Whats wrong with callbacks? To me this seems an unnecessary complication. >>> Presumably you would do: >>> var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); >>> var result = promise.get(); >>> if (!result) { >>> promise.onsuccess(function(res) {...X...}); >>> } else { >>> ...Y... >>> } >>> >>> So you end up having to duplicate code at X and Y to do the same thing >>> directly or in the context of a callback. Or you define a function to >>> process the result: >>> var f = function(res) {...X...}; >>> var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); >>> var result = promise.get(); >>> if (!result) { >>> promise.onsuccess(f); >>> } else { >>> f(result) >>> }; >>> But in which case what advantage does all this extra clutter offer over: >>> >>> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess(function(res) >>> {...X...}); >>> >>> I am just wondering whether the change is worth the added complexity? >>> >>> Cheers, >>> Keean. >>> >>> On 10 January 2011 21:31, Jonas Sicking wrote: I did some outreach to developers and while I didn't get a lot of feedback, what I got was positive to this change. The basic use-case that was brought up was implementing a promises which, as I understand it, works similar to the request model I'm proposing. I.e. you build up these "promise" objects which represent a result which may or may not have arrived yet. At some point you can either read the value out, or if it hasn't arrived yet, register a callback for when the value arrives. It was pointed out that this is still possible with how the spec is now, but it will probably result in that developers will come up with conventions to set the result on the request themselves. This wouldn't be terribly bad, but also seems nice if we can help them. / Jonas On Mon, Jan 10, 2011 at 8:13 AM, ben turner wrote: > FWIW Jonas' proposed changes have been implemented and will be > included in Firefox 4 Beta 9, due out in a few days. > > -Ben > > On Fri, Dec 10, 2010 at 12:47 PM, Jonas Sicking > wrote: >> I've been reaching out to get feedback, but no success yet. Will >> re-poke. >> >> / Jonas >> >> On Fri, Dec 10, 2010 at 4:33 AM, Jeremy Orlow >> wrote: >>> Any additional thoughts on this? If no one else cares, then we can >>> go with >>> Jonas' proposal (and we should file a bug). >>> J >>> >>> On Th
Re: [IndexedDB] Events and requests
Just to correct my cut and paste error, that was of course supposed to be: var y = do { result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey1); result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); unit(result1 + result2); } Cheers, Keean. On 10 January 2011 22:24, Keean Schupke wrote: > Okay, sorry, the original change seemed sensible, I guess I didn't see how > you got from there to promises. > > > Here's some fun to think about as an alternative though: > > > Interestingly the pattern of multiple callbacks, providing each callback is > passed zero or one parameter forms a Monad. > > So for example if 'unit' is the constructor for the object returned from > "get" then onsuccess it 'bind' and I can show that these obey the 3 monad > laws. Allowing composability of callbacks. So you effectively have: > > var x = db.transaction(["foo"]).objectStore("foo").getM(mykey); > > var y = > db.transaction(["foo"]).objectStore("foo").getM(mykey1).bind(function(result1) > { > > > db.transaction(["foo"]).objectStore("foo").getM(mykey2).bind(function(result2) > { > unit(result1 + result2); > }); > }); > > The two objects returned "x" and "y" are both the same kind of object. y > represents the sum or concatination of the results of the lookups "mykey1" > and "mykey2". You would use it identically to using the result of a single > lookup: > > x.bind(function(result) {... display the result of a single lookup ...}); > > y.bind(function(result) {... display the result of both lookups ...}); > > > If we could then have some syntactic sugar for this like haskell's do > notation we could write: > > var y = do { > db.transaction(["foo"]).objectStore("foo").getM(mykey1); > result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); > result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); > unit(result1 + result2); > } > > Which would be a very neat way of chaining callbacks... > > > Cheers, > Keean. > > > On 10 January 2011 22:00, Keean Schupke wrote: > >> Whats wrong with callbacks? To me this seems an unnecessary complication. >> >> Presumably you would do: >> >> var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); >> var result = promise.get(); >> if (!result) { >> promise.onsuccess(function(res) {...X...}); >> } else { >> ...Y... >> } >> >> >> So you end up having to duplicate code at X and Y to do the same thing >> directly or in the context of a callback. Or you define a function to >> process the result: >> >> var f = function(res) {...X...}; >> var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); >> var result = promise.get(); >> if (!result) { >> promise.onsuccess(f); >> } else { >> f(result) >> }; >> >> But in which case what advantage does all this extra clutter offer over: >> >> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess(function(res) >> {...X...}); >> >> >> I am just wondering whether the change is worth the added complexity? >> >> >> Cheers, >> Keean. >> >> >> On 10 January 2011 21:31, Jonas Sicking wrote: >> >>> I did some outreach to developers and while I didn't get a lot of >>> feedback, what I got was positive to this change. >>> >>> The basic use-case that was brought up was implementing a promises >>> which, as I understand it, works similar to the request model I'm >>> proposing. I.e. you build up these "promise" objects which represent a >>> result which may or may not have arrived yet. At some point you can >>> either read the value out, or if it hasn't arrived yet, register a >>> callback for when the value arrives. >>> >>> It was pointed out that this is still possible with how the spec is >>> now, but it will probably result in that developers will come up with >>> conventions to set the result on the request themselves. This wouldn't >>> be terribly bad, but also seems nice if we can help them. >>> >>> / Jonas >>> >>> On Mon, Jan 10, 2011 at 8:13 AM, ben turner >>> wrote: >>> > FWIW Jonas' proposed changes have been implemented and will be >>> > included in Firefox 4 Beta 9, due out in a few days. >>> > >>> > -Ben >>> > >>> > On Fri, Dec 10, 2010 at 12:47 PM, Jonas Sicking >>> wrote: >>> >> I've been reaching out to get feedback, but no success yet. Will >>> re-poke. >>> >> >>> >> / Jonas >>> >> >>> >> On Fri, Dec 10, 2010 at 4:33 AM, Jeremy Orlow >>> wrote: >>> >>> Any additional thoughts on this? If no one else cares, then we can >>> go with >>> >>> Jonas' proposal (and we should file a bug). >>> >>> J >>> >>> >>> >>> On Thu, Nov 11, 2010 at 12:06 PM, Jeremy Orlow >>> wrote: >>> >>> On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking >>> wrote: >>> > >>> > Hi All, >>> > >>> > One of the things we briefly discussed at the summit was that we >>> > should make IDBErrorEvents have a .transaction. This since we are >>> > allowing you to place new requests from within error handlers, but >>> we >>> > c
Re: [IndexedDB] Events and requests
Okay, sorry, the original change seemed sensible, I guess I didn't see how you got from there to promises. Here's some fun to think about as an alternative though: Interestingly the pattern of multiple callbacks, providing each callback is passed zero or one parameter forms a Monad. So for example if 'unit' is the constructor for the object returned from "get" then onsuccess it 'bind' and I can show that these obey the 3 monad laws. Allowing composability of callbacks. So you effectively have: var x = db.transaction(["foo"]).objectStore("foo").getM(mykey); var y = db.transaction(["foo"]).objectStore("foo").getM(mykey1).bind(function(result1) { db.transaction(["foo"]).objectStore("foo").getM(mykey2).bind(function(result2) { unit(result1 + result2); }); }); The two objects returned "x" and "y" are both the same kind of object. y represents the sum or concatination of the results of the lookups "mykey1" and "mykey2". You would use it identically to using the result of a single lookup: x.bind(function(result) {... display the result of a single lookup ...}); y.bind(function(result) {... display the result of both lookups ...}); If we could then have some syntactic sugar for this like haskell's do notation we could write: var y = do { db.transaction(["foo"]).objectStore("foo").getM(mykey1); result1 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); result2 <- db.transaction(["foo"]).objectStore("foo").getM(mykey2); unit(result1 + result2); } Which would be a very neat way of chaining callbacks... Cheers, Keean. On 10 January 2011 22:00, Keean Schupke wrote: > Whats wrong with callbacks? To me this seems an unnecessary complication. > > Presumably you would do: > > var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); > var result = promise.get(); > if (!result) { > promise.onsuccess(function(res) {...X...}); > } else { > ...Y... > } > > > So you end up having to duplicate code at X and Y to do the same thing > directly or in the context of a callback. Or you define a function to > process the result: > > var f = function(res) {...X...}; > var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); > var result = promise.get(); > if (!result) { > promise.onsuccess(f); > } else { > f(result) > }; > > But in which case what advantage does all this extra clutter offer over: > > db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess(function(res) > {...X...}); > > > I am just wondering whether the change is worth the added complexity? > > > Cheers, > Keean. > > > On 10 January 2011 21:31, Jonas Sicking wrote: > >> I did some outreach to developers and while I didn't get a lot of >> feedback, what I got was positive to this change. >> >> The basic use-case that was brought up was implementing a promises >> which, as I understand it, works similar to the request model I'm >> proposing. I.e. you build up these "promise" objects which represent a >> result which may or may not have arrived yet. At some point you can >> either read the value out, or if it hasn't arrived yet, register a >> callback for when the value arrives. >> >> It was pointed out that this is still possible with how the spec is >> now, but it will probably result in that developers will come up with >> conventions to set the result on the request themselves. This wouldn't >> be terribly bad, but also seems nice if we can help them. >> >> / Jonas >> >> On Mon, Jan 10, 2011 at 8:13 AM, ben turner >> wrote: >> > FWIW Jonas' proposed changes have been implemented and will be >> > included in Firefox 4 Beta 9, due out in a few days. >> > >> > -Ben >> > >> > On Fri, Dec 10, 2010 at 12:47 PM, Jonas Sicking >> wrote: >> >> I've been reaching out to get feedback, but no success yet. Will >> re-poke. >> >> >> >> / Jonas >> >> >> >> On Fri, Dec 10, 2010 at 4:33 AM, Jeremy Orlow >> wrote: >> >>> Any additional thoughts on this? If no one else cares, then we can go >> with >> >>> Jonas' proposal (and we should file a bug). >> >>> J >> >>> >> >>> On Thu, Nov 11, 2010 at 12:06 PM, Jeremy Orlow >> wrote: >> >> On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking >> wrote: >> > >> > Hi All, >> > >> > One of the things we briefly discussed at the summit was that we >> > should make IDBErrorEvents have a .transaction. This since we are >> > allowing you to place new requests from within error handlers, but >> we >> > currently provide no way to get from an error handler to any useful >> > objects. Instead developers will have to use closures to get to the >> > transaction or other object stores. >> > >> > Another thing that is somewhat strange is that we only make the >> result >> > available through the success event. There is no way after that to >> get >> > it from the request. So instead we use special event interfaces with >> > supply access to source, transaction and result. >> > >> >
Re: [IndexedDB] Events and requests
NOTE: I'm not proposing we do any major modifications like switching from an event based system (aka callbacks) to using promises. All I'm suggesting we do is adopt the proposal I made in the initial email in this thread. However I am saying that one of the reasons for adopting that proposal is that it allows *libraries* to more easily build a promise system on top of our API. Or integrate indexedDB in their already-existing promises implementation. / Jonas On Mon, Jan 10, 2011 at 2:00 PM, Keean Schupke wrote: > Whats wrong with callbacks? To me this seems an unnecessary complication. > Presumably you would do: > var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); > var result = promise.get(); > if (!result) { > promise.onsuccess(function(res) {...X...}); > } else { > ...Y... > } > > So you end up having to duplicate code at X and Y to do the same thing > directly or in the context of a callback. Or you define a function to > process the result: > var f = function(res) {...X...}; > var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); > var result = promise.get(); > if (!result) { > promise.onsuccess(f); > } else { > f(result) > }; > But in which case what advantage does all this extra clutter offer over: > db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess(function(res) > {...X...}); > > I am just wondering whether the change is worth the added complexity? > > Cheers, > Keean. > > On 10 January 2011 21:31, Jonas Sicking wrote: >> >> I did some outreach to developers and while I didn't get a lot of >> feedback, what I got was positive to this change. >> >> The basic use-case that was brought up was implementing a promises >> which, as I understand it, works similar to the request model I'm >> proposing. I.e. you build up these "promise" objects which represent a >> result which may or may not have arrived yet. At some point you can >> either read the value out, or if it hasn't arrived yet, register a >> callback for when the value arrives. >> >> It was pointed out that this is still possible with how the spec is >> now, but it will probably result in that developers will come up with >> conventions to set the result on the request themselves. This wouldn't >> be terribly bad, but also seems nice if we can help them. >> >> / Jonas >> >> On Mon, Jan 10, 2011 at 8:13 AM, ben turner >> wrote: >> > FWIW Jonas' proposed changes have been implemented and will be >> > included in Firefox 4 Beta 9, due out in a few days. >> > >> > -Ben >> > >> > On Fri, Dec 10, 2010 at 12:47 PM, Jonas Sicking >> > wrote: >> >> I've been reaching out to get feedback, but no success yet. Will >> >> re-poke. >> >> >> >> / Jonas >> >> >> >> On Fri, Dec 10, 2010 at 4:33 AM, Jeremy Orlow >> >> wrote: >> >>> Any additional thoughts on this? If no one else cares, then we can go >> >>> with >> >>> Jonas' proposal (and we should file a bug). >> >>> J >> >>> >> >>> On Thu, Nov 11, 2010 at 12:06 PM, Jeremy Orlow >> >>> wrote: >> >> On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking >> wrote: >> > >> > Hi All, >> > >> > One of the things we briefly discussed at the summit was that we >> > should make IDBErrorEvents have a .transaction. This since we are >> > allowing you to place new requests from within error handlers, but >> > we >> > currently provide no way to get from an error handler to any useful >> > objects. Instead developers will have to use closures to get to the >> > transaction or other object stores. >> > >> > Another thing that is somewhat strange is that we only make the >> > result >> > available through the success event. There is no way after that to >> > get >> > it from the request. So instead we use special event interfaces with >> > supply access to source, transaction and result. >> > >> > Compare this to how XMLHttpRequests work. Here the result and error >> > code is available on the request object itself. The 'load' event, >> > which is equivalent to our 'success' event didn't supply any >> > information until we recently added progress event support. But >> > still >> > it only supplies information about the progress, not the actual >> > value >> > itself. >> > >> > One thing we could do is to move >> > >> > .source >> > .transaction >> > .result >> > .error >> > >> > to IDBRequest. Then make "success" and "error" events be simple >> > events >> > which only implement the Event interface. I.e. we could get rid of >> > the >> > IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent >> > interfaces. >> > >> > We'd still have to keep IDBVersionChangeEvent, but it can inherit >> > Event directly. >> > >> > The request created from IDBFactory.open would return a IDBRequest >> > where .transaction and .source is null. We already fire a IDBEvent >> >
Re: [IndexedDB] Events and requests
Whats wrong with callbacks? To me this seems an unnecessary complication. Presumably you would do: var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); var result = promise.get(); if (!result) { promise.onsuccess(function(res) {...X...}); } else { ...Y... } So you end up having to duplicate code at X and Y to do the same thing directly or in the context of a callback. Or you define a function to process the result: var f = function(res) {...X...}; var promise = db.transaction(["foo"]).objectStore("foo").get(mykey); var result = promise.get(); if (!result) { promise.onsuccess(f); } else { f(result) }; But in which case what advantage does all this extra clutter offer over: db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess(function(res) {...X...}); I am just wondering whether the change is worth the added complexity? Cheers, Keean. On 10 January 2011 21:31, Jonas Sicking wrote: > I did some outreach to developers and while I didn't get a lot of > feedback, what I got was positive to this change. > > The basic use-case that was brought up was implementing a promises > which, as I understand it, works similar to the request model I'm > proposing. I.e. you build up these "promise" objects which represent a > result which may or may not have arrived yet. At some point you can > either read the value out, or if it hasn't arrived yet, register a > callback for when the value arrives. > > It was pointed out that this is still possible with how the spec is > now, but it will probably result in that developers will come up with > conventions to set the result on the request themselves. This wouldn't > be terribly bad, but also seems nice if we can help them. > > / Jonas > > On Mon, Jan 10, 2011 at 8:13 AM, ben turner > wrote: > > FWIW Jonas' proposed changes have been implemented and will be > > included in Firefox 4 Beta 9, due out in a few days. > > > > -Ben > > > > On Fri, Dec 10, 2010 at 12:47 PM, Jonas Sicking > wrote: > >> I've been reaching out to get feedback, but no success yet. Will > re-poke. > >> > >> / Jonas > >> > >> On Fri, Dec 10, 2010 at 4:33 AM, Jeremy Orlow > wrote: > >>> Any additional thoughts on this? If no one else cares, then we can go > with > >>> Jonas' proposal (and we should file a bug). > >>> J > >>> > >>> On Thu, Nov 11, 2010 at 12:06 PM, Jeremy Orlow > wrote: > > On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking > wrote: > > > > Hi All, > > > > One of the things we briefly discussed at the summit was that we > > should make IDBErrorEvents have a .transaction. This since we are > > allowing you to place new requests from within error handlers, but we > > currently provide no way to get from an error handler to any useful > > objects. Instead developers will have to use closures to get to the > > transaction or other object stores. > > > > Another thing that is somewhat strange is that we only make the > result > > available through the success event. There is no way after that to > get > > it from the request. So instead we use special event interfaces with > > supply access to source, transaction and result. > > > > Compare this to how XMLHttpRequests work. Here the result and error > > code is available on the request object itself. The 'load' event, > > which is equivalent to our 'success' event didn't supply any > > information until we recently added progress event support. But still > > it only supplies information about the progress, not the actual value > > itself. > > > > One thing we could do is to move > > > > .source > > .transaction > > .result > > .error > > > > to IDBRequest. Then make "success" and "error" events be simple > events > > which only implement the Event interface. I.e. we could get rid of > the > > IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent > > interfaces. > > > > We'd still have to keep IDBVersionChangeEvent, but it can inherit > > Event directly. > > > > The request created from IDBFactory.open would return a IDBRequest > > where .transaction and .source is null. We already fire a IDBEvent > > where .source is null (actually, the spec currently doesn't define > > what the source should be I see now). > > > > > > The only major downside with this setup that I can see is that the > > current syntax: > > > > db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = > > function(e) { > > alert(e.result); > > } > > > > would turn into the slightly more verbose > > > > db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = > > function(e) { > > alert(e.target.result); > > } > > > > (And note that with the error handling that we have discussed, the > > above code snippets are actually plausible (apart from the ale
Re: [IndexedDB] Events and requests
Promises/futures would be great, yes! Cleaner than the current solution. They are the right metaphor for this kind of thing. http://en.wikipedia.org/wiki/Futures_and_promises On Jan 10, 2011, at 22:31 , Jonas Sicking wrote: > I did some outreach to developers and while I didn't get a lot of > feedback, what I got was positive to this change. > > The basic use-case that was brought up was implementing a promises > which, as I understand it, works similar to the request model I'm > proposing. I.e. you build up these "promise" objects which represent a > result which may or may not have arrived yet. At some point you can > either read the value out, or if it hasn't arrived yet, register a > callback for when the value arrives. > > It was pointed out that this is still possible with how the spec is > now, but it will probably result in that developers will come up with > conventions to set the result on the request themselves. This wouldn't > be terribly bad, but also seems nice if we can help them. > > / Jonas > > On Mon, Jan 10, 2011 at 8:13 AM, ben turner wrote: >> FWIW Jonas' proposed changes have been implemented and will be >> included in Firefox 4 Beta 9, due out in a few days. >> >> -Ben >> >> On Fri, Dec 10, 2010 at 12:47 PM, Jonas Sicking wrote: >>> I've been reaching out to get feedback, but no success yet. Will re-poke. >>> >>> / Jonas >>> >>> On Fri, Dec 10, 2010 at 4:33 AM, Jeremy Orlow wrote: Any additional thoughts on this? If no one else cares, then we can go with Jonas' proposal (and we should file a bug). J On Thu, Nov 11, 2010 at 12:06 PM, Jeremy Orlow wrote: > > On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking wrote: >> >> Hi All, >> >> One of the things we briefly discussed at the summit was that we >> should make IDBErrorEvents have a .transaction. This since we are >> allowing you to place new requests from within error handlers, but we >> currently provide no way to get from an error handler to any useful >> objects. Instead developers will have to use closures to get to the >> transaction or other object stores. >> >> Another thing that is somewhat strange is that we only make the result >> available through the success event. There is no way after that to get >> it from the request. So instead we use special event interfaces with >> supply access to source, transaction and result. >> >> Compare this to how XMLHttpRequests work. Here the result and error >> code is available on the request object itself. The 'load' event, >> which is equivalent to our 'success' event didn't supply any >> information until we recently added progress event support. But still >> it only supplies information about the progress, not the actual value >> itself. >> >> One thing we could do is to move >> >> .source >> .transaction >> .result >> .error >> >> to IDBRequest. Then make "success" and "error" events be simple events >> which only implement the Event interface. I.e. we could get rid of the >> IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent >> interfaces. >> >> We'd still have to keep IDBVersionChangeEvent, but it can inherit >> Event directly. >> >> The request created from IDBFactory.open would return a IDBRequest >> where .transaction and .source is null. We already fire a IDBEvent >> where .source is null (actually, the spec currently doesn't define >> what the source should be I see now). >> >> >> The only major downside with this setup that I can see is that the >> current syntax: >> >> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = >> function(e) { >> alert(e.result); >> } >> >> would turn into the slightly more verbose >> >> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = >> function(e) { >> alert(e.target.result); >> } >> >> (And note that with the error handling that we have discussed, the >> above code snippets are actually plausible (apart from the alert() of >> course)). >> >> The upside that I can see is that we behave more like XMLHttpRequest. >> It seems that people currently follow a coding pattern where they >> place a request and at some later point hand the request to another >> piece of code. At that point the code can either get the result from >> the .result property, or install a onload handler and wait for the >> result if it isn't yet available. >> >> However I only have anecdotal evidence that this is a common coding >> pattern, so not much to go on. > > Here's a counter proposal: Let's add .transaction, .source, and .result > to IDBEvent and just specify them to be null when there is no transaction, > source, and/or result. We then remove readyState from
Re: [IndexedDB] Events and requests
I did some outreach to developers and while I didn't get a lot of feedback, what I got was positive to this change. The basic use-case that was brought up was implementing a promises which, as I understand it, works similar to the request model I'm proposing. I.e. you build up these "promise" objects which represent a result which may or may not have arrived yet. At some point you can either read the value out, or if it hasn't arrived yet, register a callback for when the value arrives. It was pointed out that this is still possible with how the spec is now, but it will probably result in that developers will come up with conventions to set the result on the request themselves. This wouldn't be terribly bad, but also seems nice if we can help them. / Jonas On Mon, Jan 10, 2011 at 8:13 AM, ben turner wrote: > FWIW Jonas' proposed changes have been implemented and will be > included in Firefox 4 Beta 9, due out in a few days. > > -Ben > > On Fri, Dec 10, 2010 at 12:47 PM, Jonas Sicking wrote: >> I've been reaching out to get feedback, but no success yet. Will re-poke. >> >> / Jonas >> >> On Fri, Dec 10, 2010 at 4:33 AM, Jeremy Orlow wrote: >>> Any additional thoughts on this? If no one else cares, then we can go with >>> Jonas' proposal (and we should file a bug). >>> J >>> >>> On Thu, Nov 11, 2010 at 12:06 PM, Jeremy Orlow wrote: On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking wrote: > > Hi All, > > One of the things we briefly discussed at the summit was that we > should make IDBErrorEvents have a .transaction. This since we are > allowing you to place new requests from within error handlers, but we > currently provide no way to get from an error handler to any useful > objects. Instead developers will have to use closures to get to the > transaction or other object stores. > > Another thing that is somewhat strange is that we only make the result > available through the success event. There is no way after that to get > it from the request. So instead we use special event interfaces with > supply access to source, transaction and result. > > Compare this to how XMLHttpRequests work. Here the result and error > code is available on the request object itself. The 'load' event, > which is equivalent to our 'success' event didn't supply any > information until we recently added progress event support. But still > it only supplies information about the progress, not the actual value > itself. > > One thing we could do is to move > > .source > .transaction > .result > .error > > to IDBRequest. Then make "success" and "error" events be simple events > which only implement the Event interface. I.e. we could get rid of the > IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent > interfaces. > > We'd still have to keep IDBVersionChangeEvent, but it can inherit > Event directly. > > The request created from IDBFactory.open would return a IDBRequest > where .transaction and .source is null. We already fire a IDBEvent > where .source is null (actually, the spec currently doesn't define > what the source should be I see now). > > > The only major downside with this setup that I can see is that the > current syntax: > > db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = > function(e) { > alert(e.result); > } > > would turn into the slightly more verbose > > db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = > function(e) { > alert(e.target.result); > } > > (And note that with the error handling that we have discussed, the > above code snippets are actually plausible (apart from the alert() of > course)). > > The upside that I can see is that we behave more like XMLHttpRequest. > It seems that people currently follow a coding pattern where they > place a request and at some later point hand the request to another > piece of code. At that point the code can either get the result from > the .result property, or install a onload handler and wait for the > result if it isn't yet available. > > However I only have anecdotal evidence that this is a common coding > pattern, so not much to go on. Here's a counter proposal: Let's add .transaction, .source, and .result to IDBEvent and just specify them to be null when there is no transaction, source, and/or result. We then remove readyState from IDBResult as it serves no purpose. What I'm proposing would result in an API that's much more similar to what we have at the moment, but would be a bit different than XHR. It is definitely good to have similar patterns for developers to follow, but I feel as thought the model of IndexedDB is already pretty different from XHR. For example, m
Re: [IndexedDB] Events and requests
FWIW Jonas' proposed changes have been implemented and will be included in Firefox 4 Beta 9, due out in a few days. -Ben On Fri, Dec 10, 2010 at 12:47 PM, Jonas Sicking wrote: > I've been reaching out to get feedback, but no success yet. Will re-poke. > > / Jonas > > On Fri, Dec 10, 2010 at 4:33 AM, Jeremy Orlow wrote: >> Any additional thoughts on this? If no one else cares, then we can go with >> Jonas' proposal (and we should file a bug). >> J >> >> On Thu, Nov 11, 2010 at 12:06 PM, Jeremy Orlow wrote: >>> >>> On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking wrote: Hi All, One of the things we briefly discussed at the summit was that we should make IDBErrorEvents have a .transaction. This since we are allowing you to place new requests from within error handlers, but we currently provide no way to get from an error handler to any useful objects. Instead developers will have to use closures to get to the transaction or other object stores. Another thing that is somewhat strange is that we only make the result available through the success event. There is no way after that to get it from the request. So instead we use special event interfaces with supply access to source, transaction and result. Compare this to how XMLHttpRequests work. Here the result and error code is available on the request object itself. The 'load' event, which is equivalent to our 'success' event didn't supply any information until we recently added progress event support. But still it only supplies information about the progress, not the actual value itself. One thing we could do is to move .source .transaction .result .error to IDBRequest. Then make "success" and "error" events be simple events which only implement the Event interface. I.e. we could get rid of the IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent interfaces. We'd still have to keep IDBVersionChangeEvent, but it can inherit Event directly. The request created from IDBFactory.open would return a IDBRequest where .transaction and .source is null. We already fire a IDBEvent where .source is null (actually, the spec currently doesn't define what the source should be I see now). The only major downside with this setup that I can see is that the current syntax: db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = function(e) { alert(e.result); } would turn into the slightly more verbose db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = function(e) { alert(e.target.result); } (And note that with the error handling that we have discussed, the above code snippets are actually plausible (apart from the alert() of course)). The upside that I can see is that we behave more like XMLHttpRequest. It seems that people currently follow a coding pattern where they place a request and at some later point hand the request to another piece of code. At that point the code can either get the result from the .result property, or install a onload handler and wait for the result if it isn't yet available. However I only have anecdotal evidence that this is a common coding pattern, so not much to go on. >>> >>> Here's a counter proposal: Let's add .transaction, .source, and .result >>> to IDBEvent and just specify them to be null when there is no transaction, >>> source, and/or result. We then remove readyState from IDBResult as it >>> serves no purpose. >>> What I'm proposing would result in an API that's much more similar to what >>> we have at the moment, but would be a bit different than XHR. It is >>> definitely good to have similar patterns for developers to follow, but I >>> feel as thought the model of IndexedDB is already pretty different from XHR. >>> For example, method calls are supplied parameters and return an IDBRequest >>> object vs you using new to create the XHR object and then making method >>> calls to set it up and then making a method call to start it. In fact, if >>> you think about it, there's really not that much XHR and IndexedDB have in >>> common except that they use event handlers. >>> As for your proposal, let me think about it for a bit and forward it on to >>> some people I know who are playing with IndexedDB already. >>> J >> > >
Re: [IndexedDB] Events and requests
I've been reaching out to get feedback, but no success yet. Will re-poke. / Jonas On Fri, Dec 10, 2010 at 4:33 AM, Jeremy Orlow wrote: > Any additional thoughts on this? If no one else cares, then we can go with > Jonas' proposal (and we should file a bug). > J > > On Thu, Nov 11, 2010 at 12:06 PM, Jeremy Orlow wrote: >> >> On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking wrote: >>> >>> Hi All, >>> >>> One of the things we briefly discussed at the summit was that we >>> should make IDBErrorEvents have a .transaction. This since we are >>> allowing you to place new requests from within error handlers, but we >>> currently provide no way to get from an error handler to any useful >>> objects. Instead developers will have to use closures to get to the >>> transaction or other object stores. >>> >>> Another thing that is somewhat strange is that we only make the result >>> available through the success event. There is no way after that to get >>> it from the request. So instead we use special event interfaces with >>> supply access to source, transaction and result. >>> >>> Compare this to how XMLHttpRequests work. Here the result and error >>> code is available on the request object itself. The 'load' event, >>> which is equivalent to our 'success' event didn't supply any >>> information until we recently added progress event support. But still >>> it only supplies information about the progress, not the actual value >>> itself. >>> >>> One thing we could do is to move >>> >>> .source >>> .transaction >>> .result >>> .error >>> >>> to IDBRequest. Then make "success" and "error" events be simple events >>> which only implement the Event interface. I.e. we could get rid of the >>> IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent >>> interfaces. >>> >>> We'd still have to keep IDBVersionChangeEvent, but it can inherit >>> Event directly. >>> >>> The request created from IDBFactory.open would return a IDBRequest >>> where .transaction and .source is null. We already fire a IDBEvent >>> where .source is null (actually, the spec currently doesn't define >>> what the source should be I see now). >>> >>> >>> The only major downside with this setup that I can see is that the >>> current syntax: >>> >>> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = >>> function(e) { >>> alert(e.result); >>> } >>> >>> would turn into the slightly more verbose >>> >>> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = >>> function(e) { >>> alert(e.target.result); >>> } >>> >>> (And note that with the error handling that we have discussed, the >>> above code snippets are actually plausible (apart from the alert() of >>> course)). >>> >>> The upside that I can see is that we behave more like XMLHttpRequest. >>> It seems that people currently follow a coding pattern where they >>> place a request and at some later point hand the request to another >>> piece of code. At that point the code can either get the result from >>> the .result property, or install a onload handler and wait for the >>> result if it isn't yet available. >>> >>> However I only have anecdotal evidence that this is a common coding >>> pattern, so not much to go on. >> >> Here's a counter proposal: Let's add .transaction, .source, and .result >> to IDBEvent and just specify them to be null when there is no transaction, >> source, and/or result. We then remove readyState from IDBResult as it >> serves no purpose. >> What I'm proposing would result in an API that's much more similar to what >> we have at the moment, but would be a bit different than XHR. It is >> definitely good to have similar patterns for developers to follow, but I >> feel as thought the model of IndexedDB is already pretty different from XHR. >> For example, method calls are supplied parameters and return an IDBRequest >> object vs you using new to create the XHR object and then making method >> calls to set it up and then making a method call to start it. In fact, if >> you think about it, there's really not that much XHR and IndexedDB have in >> common except that they use event handlers. >> As for your proposal, let me think about it for a bit and forward it on to >> some people I know who are playing with IndexedDB already. >> J >
Re: [IndexedDB] Events and requests
Any additional thoughts on this? If no one else cares, then we can go with Jonas' proposal (and we should file a bug). J On Thu, Nov 11, 2010 at 12:06 PM, Jeremy Orlow wrote: > On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking wrote: > >> Hi All, >> >> One of the things we briefly discussed at the summit was that we >> should make IDBErrorEvents have a .transaction. This since we are >> allowing you to place new requests from within error handlers, but we >> currently provide no way to get from an error handler to any useful >> objects. Instead developers will have to use closures to get to the >> transaction or other object stores. >> >> Another thing that is somewhat strange is that we only make the result >> available through the success event. There is no way after that to get >> it from the request. So instead we use special event interfaces with >> supply access to source, transaction and result. >> >> Compare this to how XMLHttpRequests work. Here the result and error >> code is available on the request object itself. The 'load' event, >> which is equivalent to our 'success' event didn't supply any >> information until we recently added progress event support. But still >> it only supplies information about the progress, not the actual value >> itself. >> >> One thing we could do is to move >> >> .source >> .transaction >> .result >> .error >> >> to IDBRequest. Then make "success" and "error" events be simple events >> which only implement the Event interface. I.e. we could get rid of the >> IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent >> interfaces. >> >> We'd still have to keep IDBVersionChangeEvent, but it can inherit >> Event directly. >> >> The request created from IDBFactory.open would return a IDBRequest >> where .transaction and .source is null. We already fire a IDBEvent >> where .source is null (actually, the spec currently doesn't define >> what the source should be I see now). >> >> >> The only major downside with this setup that I can see is that the >> current syntax: >> >> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = >> function(e) { >> alert(e.result); >> } >> >> would turn into the slightly more verbose >> >> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = >> function(e) { >> alert(e.target.result); >> } >> >> (And note that with the error handling that we have discussed, the >> above code snippets are actually plausible (apart from the alert() of >> course)). >> >> The upside that I can see is that we behave more like XMLHttpRequest. >> It seems that people currently follow a coding pattern where they >> place a request and at some later point hand the request to another >> piece of code. At that point the code can either get the result from >> the .result property, or install a onload handler and wait for the >> result if it isn't yet available. >> >> However I only have anecdotal evidence that this is a common coding >> pattern, so not much to go on. >> > > Here's a counter proposal: Let's add .transaction, .source, and .result to > IDBEvent and just specify them to be null when there is no transaction, > source, and/or result. We then remove readyState from IDBResult as it > serves no purpose. > > What I'm proposing would result in an API that's much more similar to what > we have at the moment, but would be a bit different than XHR. It is > definitely good to have similar patterns for developers to follow, but I > feel as thought the model of IndexedDB is already pretty different from XHR. > For example, method calls are supplied parameters and return an IDBRequest > object vs you using new to create the XHR object and then making method > calls to set it up and then making a method call to start it. In fact, if > you think about it, there's really not that much XHR and IndexedDB have in > common except that they use event handlers. > > As for your proposal, let me think about it for a bit and forward it on to > some people I know who are playing with IndexedDB already. > > J >
Re: [IndexedDB] Events and requests
On Tue, Nov 9, 2010 at 11:35 AM, Jonas Sicking wrote: > Hi All, > > One of the things we briefly discussed at the summit was that we > should make IDBErrorEvents have a .transaction. This since we are > allowing you to place new requests from within error handlers, but we > currently provide no way to get from an error handler to any useful > objects. Instead developers will have to use closures to get to the > transaction or other object stores. > > Another thing that is somewhat strange is that we only make the result > available through the success event. There is no way after that to get > it from the request. So instead we use special event interfaces with > supply access to source, transaction and result. > > Compare this to how XMLHttpRequests work. Here the result and error > code is available on the request object itself. The 'load' event, > which is equivalent to our 'success' event didn't supply any > information until we recently added progress event support. But still > it only supplies information about the progress, not the actual value > itself. > > One thing we could do is to move > > .source > .transaction > .result > .error > > to IDBRequest. Then make "success" and "error" events be simple events > which only implement the Event interface. I.e. we could get rid of the > IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent > interfaces. > > We'd still have to keep IDBVersionChangeEvent, but it can inherit > Event directly. > > The request created from IDBFactory.open would return a IDBRequest > where .transaction and .source is null. We already fire a IDBEvent > where .source is null (actually, the spec currently doesn't define > what the source should be I see now). > > > The only major downside with this setup that I can see is that the > current syntax: > > db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = > function(e) { > alert(e.result); > } > > would turn into the slightly more verbose > > db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = > function(e) { > alert(e.target.result); > } > > (And note that with the error handling that we have discussed, the > above code snippets are actually plausible (apart from the alert() of > course)). > > The upside that I can see is that we behave more like XMLHttpRequest. > It seems that people currently follow a coding pattern where they > place a request and at some later point hand the request to another > piece of code. At that point the code can either get the result from > the .result property, or install a onload handler and wait for the > result if it isn't yet available. > > However I only have anecdotal evidence that this is a common coding > pattern, so not much to go on. > Here's a counter proposal: Let's add .transaction, .source, and .result to IDBEvent and just specify them to be null when there is no transaction, source, and/or result. We then remove readyState from IDBResult as it serves no purpose. What I'm proposing would result in an API that's much more similar to what we have at the moment, but would be a bit different than XHR. It is definitely good to have similar patterns for developers to follow, but I feel as thought the model of IndexedDB is already pretty different from XHR. For example, method calls are supplied parameters and return an IDBRequest object vs you using new to create the XHR object and then making method calls to set it up and then making a method call to start it. In fact, if you think about it, there's really not that much XHR and IndexedDB have in common except that they use event handlers. As for your proposal, let me think about it for a bit and forward it on to some people I know who are playing with IndexedDB already. J
Re: [IndexedDB] Events and requests
On Wed, Nov 10, 2010 at 10:38 AM, Shawn Wilsher wrote: > On 11/9/2010 12:35 AM, Jonas Sicking wrote: >> >> One thing we could do is to move >> >> .source >> .transaction >> .result >> .error >> >> to IDBRequest. Then make "success" and "error" events be simple events >> which only implement the Event interface. I.e. we could get rid of the >> IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent >> interfaces. >> >> We'd still have to keep IDBVersionChangeEvent, but it can inherit >> Event directly. >> >> The request created from IDBFactory.open would return a IDBRequest >> where .transaction and .source is null. We already fire a IDBEvent >> where .source is null (actually, the spec currently doesn't define >> what the source should be I see now). > > This seems fine to me. Cool. >> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = >> function(e) { >> alert(e.result); >> } >> >> would turn into the slightly more verbose >> >> db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = >> function(e) { >> alert(e.target.result); >> } > > The only difference is e.result vs e.target.result, right? I'm not sure we > should worry about that little bit (and consumers can always use a local > variable for that if it bothers them). Yes, that's the only difference. / Jonas
Re: [IndexedDB] Events and requests
On 11/9/2010 12:35 AM, Jonas Sicking wrote: One thing we could do is to move .source .transaction .result .error to IDBRequest. Then make "success" and "error" events be simple events which only implement the Event interface. I.e. we could get rid of the IDBEvent, IDBSuccessEvent, IDBTransactionEvent and IDBErrorEvent interfaces. We'd still have to keep IDBVersionChangeEvent, but it can inherit Event directly. The request created from IDBFactory.open would return a IDBRequest where .transaction and .source is null. We already fire a IDBEvent where .source is null (actually, the spec currently doesn't define what the source should be I see now). This seems fine to me. db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = function(e) { alert(e.result); } would turn into the slightly more verbose db.transaction(["foo"]).objectStore("foo").get(mykey).onsuccess = function(e) { alert(e.target.result); } The only difference is e.result vs e.target.result, right? I'm not sure we should worry about that little bit (and consumers can always use a local variable for that if it bothers them). Cheers, Shawn smime.p7s Description: S/MIME Cryptographic Signature