Re: Indexed DB + Promises

2015-12-09 Thread Joshua Bell
On Mon, Oct 5, 2015 at 3:27 PM, Joshua Bell  wrote:

> Thanks for all the feedback so far. I've captured concrete suggestions in
> the issue tracker -
> https://github.com/inexorabletash/indexeddb-promises/issues
>
>
>
> On Wed, Sep 30, 2015 at 11:10 AM, Tab Atkins Jr. 
> wrote:
>
>> On Wed, Sep 30, 2015 at 11:07 AM, Kyle Huey  wrote:
>> > On Wed, Sep 30, 2015 at 10:50 AM, Tab Atkins Jr. 
>> wrote:
>> >> On Tue, Sep 29, 2015 at 10:51 AM, Domenic Denicola 
>> wrote:
>> >>> I guess part of the question is, does this add enough value, or will
>> authors still prefer wrapper libraries, which can afford to throw away
>> backward compatibility in order to avoid these ergonomic problems? From
>> that perspective, the addition of waitUntil or a similar primitive to allow
>> better control over transaction lifecycle is crucial, since it will enable
>> better wrapper libraries. But the .promise and .complete properties end up
>> feeling like halfway measures, compared to the usability gains a wrapper
>> can achieve. Maybe they are still worthwhile though, despite their flaws.
>> You probably have a better sense of what authors have been asking for here
>> than I do.
>> >>
>> >> Remember that the *entire point* of IDB was to provide a "low-level"
>> >> set of functionality, and then to add a sugar layer on top once
>> >> authors had explored the space a bit and shown what would be most
>> >> useful.
>> >>
>> >> I'd prefer we kept with that approach, and defined a consistent,
>> >> easy-to-use sugar layer that's just built with IDB primitives
>> >> underneath, rather than trying to upgrade the IDB primitives into more
>> >> usable forms that end up being inconsistent or difficult to use.
>> >
>> > At a bare minimum we need to actually specify how transaction
>> > lifetimes interact with tasks, microtasks, etc.  Especially since the
>> > behavior differs between Gecko and Blink (or did, the last time I
>> > checked).
>>
>
> Yeah - "When control is returned to the event loop" isn't precise enough.
> It's an open issue in the 2nd Ed. and I welcome suggestions for tightening
> it up. Note that Jake Archibald, at least, was happy with the Blink
> behavior, after chewing on it for a bit. But it still seems far too subtle
> to me, and someone who writes blog posts explaining tasks vs. microtasks is
> probably not the average consumer of the API. :)
>
>
>> >
>> > waitUntil() alone is a pretty large change to IDB semantics. Somebody
>> > mentioned earlier that you can get this behavior today which is true,
>> > but it requires you to continually issue "keep-alive" read requests to
>> > the transaction, so it's fairly obvious you aren't using it as
>> > intended.
>>
>> Yeah, any necessary extensions to the underlying "bare" IDB semantics
>> that need to be made to support the sugar layer are of course
>> appropriate; they indicate an impedance mismatch that we need to
>> address for usability.
>>
>
> Agreed.  So... I'm looking for additional feedback that the proposal
> addresses this mismatch, with both waitUntil() on transactions (kudos to
> Alex Russell) and the promise accessors on transactions/requests and minor
> cursor tweaks which difficult to get correct today.
>
>
Dusting this off. Any additional feedback? If we gain implementation
experience and handle the details tracked at
https://github.com/inexorabletash/indexeddb-promises/issues does this
approach seem like viable path forward for other implementers?


Re: Indexed DB + Promises

2015-10-06 Thread Jake Archibald
On Mon, 5 Oct 2015 at 23:31 Joshua Bell  wrote:

> Yeah - "When control is returned to the event loop" isn't precise enough.
> It's an open issue in the 2nd Ed. and I welcome suggestions for tightening
> it up. Note that Jake Archibald, at least, was happy with the Blink
> behavior, after chewing on it for a bit. But it still seems far too subtle
> to me, and someone who writes blog posts explaining tasks vs. microtasks is
> probably not the average consumer of the API. :)
>

Step 8 of https://w3c.github.io/IndexedDB/#dom-idbdatabase-transaction can
queue a microtask to unset the active flag. It would mean:

var tx = db.transaction(…);

Promise.resolve().then(_ => {
  // transaction is now closed
});

…but if you want to keep the transaction open longer, that's what waitUntil
is for.

As for https://w3c.github.io/IndexedDB/#fire-a-success-event - this seems
fine as long as microtasks fire before step 4, which they should.


Re: Indexed DB + Promises

2015-10-05 Thread Joshua Bell
Thanks for all the feedback so far. I've captured concrete suggestions in
the issue tracker -
https://github.com/inexorabletash/indexeddb-promises/issues



On Wed, Sep 30, 2015 at 11:10 AM, Tab Atkins Jr. 
wrote:

> On Wed, Sep 30, 2015 at 11:07 AM, Kyle Huey  wrote:
> > On Wed, Sep 30, 2015 at 10:50 AM, Tab Atkins Jr. 
> wrote:
> >> On Tue, Sep 29, 2015 at 10:51 AM, Domenic Denicola 
> wrote:
> >>> I guess part of the question is, does this add enough value, or will
> authors still prefer wrapper libraries, which can afford to throw away
> backward compatibility in order to avoid these ergonomic problems? From
> that perspective, the addition of waitUntil or a similar primitive to allow
> better control over transaction lifecycle is crucial, since it will enable
> better wrapper libraries. But the .promise and .complete properties end up
> feeling like halfway measures, compared to the usability gains a wrapper
> can achieve. Maybe they are still worthwhile though, despite their flaws.
> You probably have a better sense of what authors have been asking for here
> than I do.
> >>
> >> Remember that the *entire point* of IDB was to provide a "low-level"
> >> set of functionality, and then to add a sugar layer on top once
> >> authors had explored the space a bit and shown what would be most
> >> useful.
> >>
> >> I'd prefer we kept with that approach, and defined a consistent,
> >> easy-to-use sugar layer that's just built with IDB primitives
> >> underneath, rather than trying to upgrade the IDB primitives into more
> >> usable forms that end up being inconsistent or difficult to use.
> >
> > At a bare minimum we need to actually specify how transaction
> > lifetimes interact with tasks, microtasks, etc.  Especially since the
> > behavior differs between Gecko and Blink (or did, the last time I
> > checked).
>

Yeah - "When control is returned to the event loop" isn't precise enough.
It's an open issue in the 2nd Ed. and I welcome suggestions for tightening
it up. Note that Jake Archibald, at least, was happy with the Blink
behavior, after chewing on it for a bit. But it still seems far too subtle
to me, and someone who writes blog posts explaining tasks vs. microtasks is
probably not the average consumer of the API. :)


> >
> > waitUntil() alone is a pretty large change to IDB semantics. Somebody
> > mentioned earlier that you can get this behavior today which is true,
> > but it requires you to continually issue "keep-alive" read requests to
> > the transaction, so it's fairly obvious you aren't using it as
> > intended.
>
> Yeah, any necessary extensions to the underlying "bare" IDB semantics
> that need to be made to support the sugar layer are of course
> appropriate; they indicate an impedance mismatch that we need to
> address for usability.
>

Agreed.  So... I'm looking for additional feedback that the proposal
addresses this mismatch, with both waitUntil() on transactions (kudos to
Alex Russell) and the promise accessors on transactions/requests and minor
cursor tweaks which difficult to get correct today.


Re: Indexed DB + Promises

2015-09-30 Thread Tab Atkins Jr.
On Wed, Sep 30, 2015 at 11:07 AM, Kyle Huey  wrote:
> On Wed, Sep 30, 2015 at 10:50 AM, Tab Atkins Jr.  wrote:
>> On Tue, Sep 29, 2015 at 10:51 AM, Domenic Denicola  wrote:
>>> I guess part of the question is, does this add enough value, or will 
>>> authors still prefer wrapper libraries, which can afford to throw away 
>>> backward compatibility in order to avoid these ergonomic problems? From 
>>> that perspective, the addition of waitUntil or a similar primitive to allow 
>>> better control over transaction lifecycle is crucial, since it will enable 
>>> better wrapper libraries. But the .promise and .complete properties end up 
>>> feeling like halfway measures, compared to the usability gains a wrapper 
>>> can achieve. Maybe they are still worthwhile though, despite their flaws. 
>>> You probably have a better sense of what authors have been asking for here 
>>> than I do.
>>
>> Remember that the *entire point* of IDB was to provide a "low-level"
>> set of functionality, and then to add a sugar layer on top once
>> authors had explored the space a bit and shown what would be most
>> useful.
>>
>> I'd prefer we kept with that approach, and defined a consistent,
>> easy-to-use sugar layer that's just built with IDB primitives
>> underneath, rather than trying to upgrade the IDB primitives into more
>> usable forms that end up being inconsistent or difficult to use.
>
> At a bare minimum we need to actually specify how transaction
> lifetimes interact with tasks, microtasks, etc.  Especially since the
> behavior differs between Gecko and Blink (or did, the last time I
> checked).
>
> waitUntil() alone is a pretty large change to IDB semantics. Somebody
> mentioned earlier that you can get this behavior today which is true,
> but it requires you to continually issue "keep-alive" read requests to
> the transaction, so it's fairly obvious you aren't using it as
> intended.

Yeah, any necessary extensions to the underlying "bare" IDB semantics
that need to be made to support the sugar layer are of course
appropriate; they indicate an impedance mismatch that we need to
address for usability.

~TJ



Re: Indexed DB + Promises

2015-09-30 Thread Kyle Huey
On Wed, Sep 30, 2015 at 10:50 AM, Tab Atkins Jr.  wrote:
> On Tue, Sep 29, 2015 at 10:51 AM, Domenic Denicola  wrote:
>> I guess part of the question is, does this add enough value, or will authors 
>> still prefer wrapper libraries, which can afford to throw away backward 
>> compatibility in order to avoid these ergonomic problems? From that 
>> perspective, the addition of waitUntil or a similar primitive to allow 
>> better control over transaction lifecycle is crucial, since it will enable 
>> better wrapper libraries. But the .promise and .complete properties end up 
>> feeling like halfway measures, compared to the usability gains a wrapper can 
>> achieve. Maybe they are still worthwhile though, despite their flaws. You 
>> probably have a better sense of what authors have been asking for here than 
>> I do.
>
> Remember that the *entire point* of IDB was to provide a "low-level"
> set of functionality, and then to add a sugar layer on top once
> authors had explored the space a bit and shown what would be most
> useful.
>
> I'd prefer we kept with that approach, and defined a consistent,
> easy-to-use sugar layer that's just built with IDB primitives
> underneath, rather than trying to upgrade the IDB primitives into more
> usable forms that end up being inconsistent or difficult to use.
>
> ~TJ
>

At a bare minimum we need to actually specify how transaction
lifetimes interact with tasks, microtasks, etc.  Especially since the
behavior differs between Gecko and Blink (or did, the last time I
checked).

waitUntil() alone is a pretty large change to IDB semantics. Somebody
mentioned earlier that you can get this behavior today which is true,
but it requires you to continually issue "keep-alive" read requests to
the transaction, so it's fairly obvious you aren't using it as
intended.

- Kyle



Re: Indexed DB + Promises

2015-09-30 Thread Tab Atkins Jr.
On Tue, Sep 29, 2015 at 10:51 AM, Domenic Denicola  wrote:
> I guess part of the question is, does this add enough value, or will authors 
> still prefer wrapper libraries, which can afford to throw away backward 
> compatibility in order to avoid these ergonomic problems? From that 
> perspective, the addition of waitUntil or a similar primitive to allow better 
> control over transaction lifecycle is crucial, since it will enable better 
> wrapper libraries. But the .promise and .complete properties end up feeling 
> like halfway measures, compared to the usability gains a wrapper can achieve. 
> Maybe they are still worthwhile though, despite their flaws. You probably 
> have a better sense of what authors have been asking for here than I do.

Remember that the *entire point* of IDB was to provide a "low-level"
set of functionality, and then to add a sugar layer on top once
authors had explored the space a bit and shown what would be most
useful.

I'd prefer we kept with that approach, and defined a consistent,
easy-to-use sugar layer that's just built with IDB primitives
underneath, rather than trying to upgrade the IDB primitives into more
usable forms that end up being inconsistent or difficult to use.

~TJ



Re: Indexed DB + Promises

2015-09-30 Thread Ben Kelly
On Wed, Sep 30, 2015 at 3:13 AM, David Rajchenbach-Teller <
dtel...@mozilla.com> wrote:

> Joshua, I am trying to understand how your proposal relates to
> microtasks. Does the extension of lifetime mean that a transaction is
> alive 1/ until the end of the event (including pending microtasks) or 2/
> that it can be kept alive across several events?
>

Wouldn't it have to be 2/ here?  What in the proposal prevents code from
doing this?

  tx.waitUntil(new Promise(function(resolve) {
setTimeout(resolve, 5000);
  }));

That seems like a good thing to me, though.  It would be nice not to
require code to perform work synchronously on the main thread in order to
have a large transaction.  This tx.waitUntil() now lets code yield the main
thread for large transactions.  If I understand it correctly...

Ben


Re: Indexed DB + Promises

2015-09-30 Thread Jake Archibald
IDB already aborts the transaction if errors are thrown in callbacks.
Additionally, in the promise proposal, if the promise passed to .waitUntil
rejects, the transaction aborts. Does this address your concerns?

On Wed, 30 Sep 2015, 08:26 Conrad Irwin  wrote:

> One of the things I like about the WebSQL API is that the transaction
> aborts if any queries fail or if any callbacks throw errors. This way the
> whole transaction can be handled as a promise easily, which provides nice
> abstraction to the calling code.
>
> It comes at the expense of each individual operation being promisified,
> each operation still takes a callback so that you know for sure when code
> is 'done' handling a result (it's hard to tell when a promise is done
> because .then can be called multiple times and at any time).
>
> I would like to see any work on IndexedDb promises go the same way:
>
> 1. Figure out how to tell if a transaction succeeded or failed.
> 2. Wrap the transaction in a promise, so that code can be structured at a
> high level with promises.
> 3. (Optional) represent each request as a promise, if that's compatible
> with goal 1.
>
> If I remember rightly it's hard to do 1 in general with the current
> non-promise based API, so any change to make the  API more promise
> based should first address that.
>
> Conrad
>
>
>
>
> On Tuesday, September 29, 2015, Jake Archibald 
> wrote:
>
>> I agree with Jonas, I'd like to see IDBRequest and IDBTransaction be
>> thenables. This could be done by having a hidden promise, and having
>> .then/.catch proxy to the same methods on the hidden promise.
>>
>> We just have to get over the throw/reject thing.
>>
>> On Tue, 29 Sep 2015, 23:16 Jonas Sicking  wrote:
>>
>>> On Tue, Sep 29, 2015 at 10:51 AM, Domenic Denicola  wrote:
>>> > This seems ... reasonable, and quite possibly the best we can do. It
>>> has a several notable rough edges:
>>> >
>>> > - The need to remember to use .promise, instead of just having
>>> functions whose return values you can await directly
>>>
>>> One way that we could solve this would be to make IDBRequest a
>>> thenable. I.e. put a .then() function directly on IDBRequest.
>>>
>>> > - The two-stage error paths (exceptions + rejections), necessitating
>>> async/await to make it palatable
>>>
>>> I'd be curious to know if, in the case of IDB, this is a problem in
>>> practice. I do agree that it's good for promise based APIs to only
>>> have one error path, but IDB is pretty conservative about when it
>>> throws.
>>>
>>> Do people actually wrap their IDB calls in try/catch today?
>>>
>>> Certainly throwing at all isn't perfect, but is it a big enough
>>> problem that it warrants using a library?
>>>
>>> > - The waitUntil/IIAFE pattern in the incrementSlowly example, instead
>>> of a more natural `const t = await openTransaction(); try { await
>>> useTransaction(t); } finally { t.close(); }` structure
>>>
>>> I'm actually quite concerned about using a t.close() pattern. It seems
>>> to make it very easy to end up with minor bugs which totally hang an
>>> application because a transaction is left open.
>>>
>>> But maybe developers prefer it strongly enough that they'll use a
>>> library which provides it.
>>>
>>> > I guess part of the question is, does this add enough value, or will
>>> authors still prefer wrapper libraries, which can afford to throw away
>>> backward compatibility in order to avoid these ergonomic problems?
>>>
>>> Yeah, I think this is a very good question. I personally have no idea.
>>>
>>> / Jonas
>>>
>>>


Re: Indexed DB + Promises

2015-09-30 Thread Conrad Irwin
One of the things I like about the WebSQL API is that the transaction
aborts if any queries fail or if any callbacks throw errors. This way the
whole transaction can be handled as a promise easily, which provides nice
abstraction to the calling code.

It comes at the expense of each individual operation being promisified,
each operation still takes a callback so that you know for sure when code
is 'done' handling a result (it's hard to tell when a promise is done
because .then can be called multiple times and at any time).

I would like to see any work on IndexedDb promises go the same way:

1. Figure out how to tell if a transaction succeeded or failed.
2. Wrap the transaction in a promise, so that code can be structured at a
high level with promises.
3. (Optional) represent each request as a promise, if that's compatible
with goal 1.

If I remember rightly it's hard to do 1 in general with the current
non-promise based API, so any change to make the  API more promise
based should first address that.

Conrad




On Tuesday, September 29, 2015, Jake Archibald 
wrote:

> I agree with Jonas, I'd like to see IDBRequest and IDBTransaction be
> thenables. This could be done by having a hidden promise, and having
> .then/.catch proxy to the same methods on the hidden promise.
>
> We just have to get over the throw/reject thing.
>
> On Tue, 29 Sep 2015, 23:16 Jonas Sicking  wrote:
>
>> On Tue, Sep 29, 2015 at 10:51 AM, Domenic Denicola > > wrote:
>> > This seems ... reasonable, and quite possibly the best we can do. It
>> has a several notable rough edges:
>> >
>> > - The need to remember to use .promise, instead of just having
>> functions whose return values you can await directly
>>
>> One way that we could solve this would be to make IDBRequest a
>> thenable. I.e. put a .then() function directly on IDBRequest.
>>
>> > - The two-stage error paths (exceptions + rejections), necessitating
>> async/await to make it palatable
>>
>> I'd be curious to know if, in the case of IDB, this is a problem in
>> practice. I do agree that it's good for promise based APIs to only
>> have one error path, but IDB is pretty conservative about when it
>> throws.
>>
>> Do people actually wrap their IDB calls in try/catch today?
>>
>> Certainly throwing at all isn't perfect, but is it a big enough
>> problem that it warrants using a library?
>>
>> > - The waitUntil/IIAFE pattern in the incrementSlowly example, instead
>> of a more natural `const t = await openTransaction(); try { await
>> useTransaction(t); } finally { t.close(); }` structure
>>
>> I'm actually quite concerned about using a t.close() pattern. It seems
>> to make it very easy to end up with minor bugs which totally hang an
>> application because a transaction is left open.
>>
>> But maybe developers prefer it strongly enough that they'll use a
>> library which provides it.
>>
>> > I guess part of the question is, does this add enough value, or will
>> authors still prefer wrapper libraries, which can afford to throw away
>> backward compatibility in order to avoid these ergonomic problems?
>>
>> Yeah, I think this is a very good question. I personally have no idea.
>>
>> / Jonas
>>
>>


Re: Indexed DB + Promises

2015-09-30 Thread David Rajchenbach-Teller
On 30/09/15 08:12, Jake Archibald wrote:
> I agree with Jonas, I'd like to see IDBRequest and IDBTransaction be
> thenables. This could be done by having a hidden promise, and having
> .then/.catch proxy to the same methods on the hidden promise.
> 
> We just have to get over the throw/reject thing.

I believe that most browsers now have built-in tools to follow uncaught
rejections (or will shortly). If IDBRequest/IDBTransaction become
transparently thenable, we need to be careful that they do not leave
uncaught rejections lying around when the code uses the old, event-based
API.

This can be done, for instance, by making sure that any listener for the
"error" event silently catches rejections.

Cheers,
 David

-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature


Re: Indexed DB + Promises

2015-09-30 Thread David Rajchenbach-Teller
Very good initiative.

Joshua, I am trying to understand how your proposal relates to
microtasks. Does the extension of lifetime mean that a transaction is
alive 1/ until the end of the event (including pending microtasks) or 2/
that it can be kept alive across several events?

Intuitively, I believe that only 1/ makes sense, but this may play
poorly with older implementations of `Promise` which don't use
microtasks – and which may end up injected accidentally in a webpage by
the use of a framework. I understand you reject with a `TypeError` if we
attempt to use such a `Promise` after the end of its the lifetime, which
might be sufficient, but you'll have to make sure that the companion
error message is very clear.

Cheers,
 David

On 28/09/15 19:43, Joshua Bell wrote:
> One of the top requests[1] we've received for future iterations of
> Indexed DB is integration with ES Promises. While this initially seems
> straightforward ("aren't requests just promises?") the devil is in the
> details - events vs. microtasks, exceptions vs. rejections, automatic
> commits, etc.
> 
> After some noodling and some very helpful initial feedback, I've got
> what I think is a minimal proposal for incrementally evolving (i.e. not
> replacing) the Indexed DB API with some promise-friendly affordances,
> written up here:
> 
> https://github.com/inexorabletash/indexeddb-promises
> 
> I'd appreciate feedback from the WebApps community either here or in
> that repo's issue tracker.
> 
> [1] https://www.w3.org/2008/webapps/wiki/IndexedDatabaseFeatures
> 


-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature


Re: Indexed DB + Promises

2015-09-29 Thread Jake Archibald
I agree with Jonas, I'd like to see IDBRequest and IDBTransaction be
thenables. This could be done by having a hidden promise, and having
.then/.catch proxy to the same methods on the hidden promise.

We just have to get over the throw/reject thing.

On Tue, 29 Sep 2015, 23:16 Jonas Sicking  wrote:

> On Tue, Sep 29, 2015 at 10:51 AM, Domenic Denicola  wrote:
> > This seems ... reasonable, and quite possibly the best we can do. It has
> a several notable rough edges:
> >
> > - The need to remember to use .promise, instead of just having functions
> whose return values you can await directly
>
> One way that we could solve this would be to make IDBRequest a
> thenable. I.e. put a .then() function directly on IDBRequest.
>
> > - The two-stage error paths (exceptions + rejections), necessitating
> async/await to make it palatable
>
> I'd be curious to know if, in the case of IDB, this is a problem in
> practice. I do agree that it's good for promise based APIs to only
> have one error path, but IDB is pretty conservative about when it
> throws.
>
> Do people actually wrap their IDB calls in try/catch today?
>
> Certainly throwing at all isn't perfect, but is it a big enough
> problem that it warrants using a library?
>
> > - The waitUntil/IIAFE pattern in the incrementSlowly example, instead of
> a more natural `const t = await openTransaction(); try { await
> useTransaction(t); } finally { t.close(); }` structure
>
> I'm actually quite concerned about using a t.close() pattern. It seems
> to make it very easy to end up with minor bugs which totally hang an
> application because a transaction is left open.
>
> But maybe developers prefer it strongly enough that they'll use a
> library which provides it.
>
> > I guess part of the question is, does this add enough value, or will
> authors still prefer wrapper libraries, which can afford to throw away
> backward compatibility in order to avoid these ergonomic problems?
>
> Yeah, I think this is a very good question. I personally have no idea.
>
> / Jonas
>
>


Re: Indexed DB + Promises

2015-09-29 Thread Jonas Sicking
On Tue, Sep 29, 2015 at 10:51 AM, Domenic Denicola  wrote:
> This seems ... reasonable, and quite possibly the best we can do. It has a 
> several notable rough edges:
>
> - The need to remember to use .promise, instead of just having functions 
> whose return values you can await directly

One way that we could solve this would be to make IDBRequest a
thenable. I.e. put a .then() function directly on IDBRequest.

> - The two-stage error paths (exceptions + rejections), necessitating 
> async/await to make it palatable

I'd be curious to know if, in the case of IDB, this is a problem in
practice. I do agree that it's good for promise based APIs to only
have one error path, but IDB is pretty conservative about when it
throws.

Do people actually wrap their IDB calls in try/catch today?

Certainly throwing at all isn't perfect, but is it a big enough
problem that it warrants using a library?

> - The waitUntil/IIAFE pattern in the incrementSlowly example, instead of a 
> more natural `const t = await openTransaction(); try { await 
> useTransaction(t); } finally { t.close(); }` structure

I'm actually quite concerned about using a t.close() pattern. It seems
to make it very easy to end up with minor bugs which totally hang an
application because a transaction is left open.

But maybe developers prefer it strongly enough that they'll use a
library which provides it.

> I guess part of the question is, does this add enough value, or will authors 
> still prefer wrapper libraries, which can afford to throw away backward 
> compatibility in order to avoid these ergonomic problems?

Yeah, I think this is a very good question. I personally have no idea.

/ Jonas



RE: Indexed DB + Promises

2015-09-29 Thread Domenic Denicola
This seems ... reasonable, and quite possibly the best we can do. It has a 
several notable rough edges:

- The need to remember to use .promise, instead of just having functions whose 
return values you can await directly
- The two-stage error paths (exceptions + rejections), necessitating 
async/await to make it palatable
- The waitUntil/IIAFE pattern in the incrementSlowly example, instead of a more 
natural `const t = await openTransaction(); try { await useTransaction(t); } 
finally { t.close(); }` structure

I guess part of the question is, does this add enough value, or will authors 
still prefer wrapper libraries, which can afford to throw away backward 
compatibility in order to avoid these ergonomic problems? From that 
perspective, the addition of waitUntil or a similar primitive to allow better 
control over transaction lifecycle is crucial, since it will enable better 
wrapper libraries. But the .promise and .complete properties end up feeling 
like halfway measures, compared to the usability gains a wrapper can achieve. 
Maybe they are still worthwhile though, despite their flaws. You probably have 
a better sense of what authors have been asking for here than I do.

Minor usability suggestions:

- Maybe tx.waitUntil could return tx.complete? That would shorten the 
incrementSlowly example a bit.
- .promise is a pretty generic name. For operations, .ready or .complete or 
.done might be nicer. (Although nothing sticks out as perfect.) For cursors, 
I'd suggest something like .next or .nextReady or similar.

From: Joshua Bell [mailto:jsb...@google.com] 
Sent: Monday, September 28, 2015 13:44
To: public-webapps@w3.org
Subject: Indexed DB + Promises

One of the top requests[1] we've received for future iterations of Indexed DB 
is integration with ES Promises. While this initially seems straightforward 
("aren't requests just promises?") the devil is in the details - events vs. 
microtasks, exceptions vs. rejections, automatic commits, etc.

After some noodling and some very helpful initial feedback, I've got what I 
think is a minimal proposal for incrementally evolving (i.e. not replacing) the 
Indexed DB API with some promise-friendly affordances, written up here:

https://github.com/inexorabletash/indexeddb-promises

I'd appreciate feedback from the WebApps community either here or in that 
repo's issue tracker.

[1] https://www.w3.org/2008/webapps/wiki/IndexedDatabaseFeatures



RE: Indexed DB + Promises

2015-09-28 Thread Aaron Powell
I’ve been maintaining an IDB wrapper using Promises for a few years now[1].

Some things I’ve learnt are:

· Sharing transactions are a pain, but can be beneficial

· Cursors would lead to a nicer implementation on generators

· Async looks like a nicer abstraction on top

· Transaction vs Request makes promises challenging

I’m going to take a bit more of a look into Joshua’s implementation when I get 
a few moments as the above is my perspective from my approach so far.

[1] http://github.com/aaronpowell/db.js

From: Marc Fawzi [mailto:marc.fa...@gmail.com]
Sent: Tuesday, 29 September 2015 6:40 AM
To: David Rajchenbach-Teller 
Cc: Joshua Bell ; public-webapps@w3.org
Subject: Re: Indexed DB + Promises

How about using ES7 decorators, like so:

@idb_promise
function () {
  //some code that uses the IDB API in Promise based way
}

and it would add .promise to the IDB APIs



On Mon, Sep 28, 2015 at 1:26 PM, David Rajchenbach-Teller 
mailto:dtel...@mozilla.com>> wrote:
On 28/09/15 22:14, Marc Fawzi wrote:
> <<
> Instead of having .promise to appended to the IDB methods as
> in `store.openCursor(query).promise` why couldn't you configure the IDB
> API to be in Promise returning mode and in that case openCursor(query)
> would return a Promise.
>>>
>
> I meant user configurable, maybe as a global config.

That sounds problematic. What if a codebase is modernized piecewise, and
only some modules have been made Promise-friendly?


--
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



Re: Indexed DB + Promises

2015-09-28 Thread Marc Fawzi
How about using ES7 decorators, like so:

@idb_promise
function () {
  //some code that uses the IDB API in Promise based way
}

and it would add .promise to the IDB APIs



On Mon, Sep 28, 2015 at 1:26 PM, David Rajchenbach-Teller <
dtel...@mozilla.com> wrote:

> On 28/09/15 22:14, Marc Fawzi wrote:
> > <<
> > Instead of having .promise to appended to the IDB methods as
> > in `store.openCursor(query).promise` why couldn't you configure the IDB
> > API to be in Promise returning mode and in that case openCursor(query)
> > would return a Promise.
> >>>
> >
> > I meant user configurable, maybe as a global config.
>
> That sounds problematic. What if a codebase is modernized piecewise, and
> only some modules have been made Promise-friendly?
>
>
> --
> David Rajchenbach-Teller, PhD
>  Performance Team, Mozilla
>
>


Re: Indexed DB + Promises

2015-09-28 Thread David Rajchenbach-Teller
On 28/09/15 22:14, Marc Fawzi wrote:
> <<
> Instead of having .promise to appended to the IDB methods as
> in `store.openCursor(query).promise` why couldn't you configure the IDB
> API to be in Promise returning mode and in that case openCursor(query)
> would return a Promise.
>>>
> 
> I meant user configurable, maybe as a global config.

That sounds problematic. What if a codebase is modernized piecewise, and
only some modules have been made Promise-friendly?


-- 
David Rajchenbach-Teller, PhD
 Performance Team, Mozilla



signature.asc
Description: OpenPGP digital signature


Re: Indexed DB + Promises

2015-09-28 Thread Marc Fawzi
<<
Instead of having .promise to appended to the IDB methods as in
`store.openCursor(query).promise` why couldn't you configure the IDB API to
be in Promise returning mode and in that case openCursor(query) would
return a Promise.
>>

I meant user configurable, maybe as a global config.

On Mon, Sep 28, 2015 at 1:12 PM, Marc Fawzi  wrote:

> Yes, sorry.
>
> < underlying issue of mixing IDB+Promises remains. >>
>
> That's for implementors such as yourself to work through, I had assumed.
>
> I just went over the Readme from the perspective of an IDB user. Here is
> some potentially very naive feedback but i it s so obvious I can't help but
> state it:
>
> Instead of having .promise to appended to the IDB methods as in 
> `store.openCursor(query).promise`
> why couldn't you configure the IDB API to be in Promise returning mode and
> in that case openCursor(query) would return a Promise.
>
> This way the syntax is not polluted with .promise everywhere and there
> would be no chance of forgetting to add .promise or intentionally mixing
> the bare IDB API with the promise returning version in the same code base
> which can be very confusing 
>
> I apologize if this makes no sense. I am a fan of IDB and had used is
> successfully in the past without the Promise stuff. It takes some getting
> used to but the IDB API is powerful AS IS and if you're going to make it
> more approachable while keeping its row power I would probably skip
> ES5/Promise (in terms of usage examples) and focus on async/await usage
> because as you state under Concerns:
>
>-
>
>Methods that return requests still throw rather than reject on invalid
>input, so you must still use try/catch blocks. Fortunately, with ES2016
>async/await syntax, asynchronous errors can also be handled by try/catch
>blocks.
>
> Also, I think with the scenario of potentially infinite
> wait (waitUntil(new Promise())) the only thing I can think of is a timeout
> that is configurable on waitUntil, e.g. waitUntil(new
> Promise()).maxTime(30s)
>
>
>
>
>
>
> On Mon, Sep 28, 2015 at 12:36 PM, Joshua Bell  wrote:
>
>> On Mon, Sep 28, 2015 at 11:42 AM, Marc Fawzi 
>> wrote:
>>
>>> Have you looked at ES7 async/await? I find that pattern makes both
>>> simple as well as very complex (even dynamic) async coordination much
>>> easier to deal with than Promise API. I mean from a developer perspective.
>>>
>>>
>> The linked proposal contains examples written in both "legacy" syntax
>> (marked "ES2015") and in ES7 syntax with async/await (marked "ES2016").
>> Please do read it.
>>
>> As the syntax additions are "just sugar" on top of Promises, the
>> underlying issue of mixing IDB+Promises remains. The proposal attempts to
>> make code using IDB with async/await syntax approachable, while not
>> entirely replacing the existing API.
>>
>>
>>>
>>> Sent from my iPhone
>>>
>>> On Sep 28, 2015, at 10:43 AM, Joshua Bell  wrote:
>>>
>>> One of the top requests[1] we've received for future iterations of
>>> Indexed DB is integration with ES Promises. While this initially seems
>>> straightforward ("aren't requests just promises?") the devil is in the
>>> details - events vs. microtasks, exceptions vs. rejections, automatic
>>> commits, etc.
>>>
>>> After some noodling and some very helpful initial feedback, I've got
>>> what I think is a minimal proposal for incrementally evolving (i.e. not
>>> replacing) the Indexed DB API with some promise-friendly affordances,
>>> written up here:
>>>
>>> https://github.com/inexorabletash/indexeddb-promises
>>>
>>> I'd appreciate feedback from the WebApps community either here or in
>>> that repo's issue tracker.
>>>
>>> [1] https://www.w3.org/2008/webapps/wiki/IndexedDatabaseFeatures
>>>
>>>
>>
>


Re: Indexed DB + Promises

2015-09-28 Thread Marc Fawzi
Yes, sorry.

<>

That's for implementors such as yourself to work through, I had assumed.

I just went over the Readme from the perspective of an IDB user. Here is
some potentially very naive feedback but i it s so obvious I can't help but
state it:

Instead of having .promise to appended to the IDB methods as in
`store.openCursor(query).promise`
why couldn't you configure the IDB API to be in Promise returning mode and
in that case openCursor(query) would return a Promise.

This way the syntax is not polluted with .promise everywhere and there
would be no chance of forgetting to add .promise or intentionally mixing
the bare IDB API with the promise returning version in the same code base
which can be very confusing 

I apologize if this makes no sense. I am a fan of IDB and had used is
successfully in the past without the Promise stuff. It takes some getting
used to but the IDB API is powerful AS IS and if you're going to make it
more approachable while keeping its row power I would probably skip
ES5/Promise (in terms of usage examples) and focus on async/await usage
because as you state under Concerns:

   -

   Methods that return requests still throw rather than reject on invalid
   input, so you must still use try/catch blocks. Fortunately, with ES2016
   async/await syntax, asynchronous errors can also be handled by try/catch
   blocks.

Also, I think with the scenario of potentially infinite wait (waitUntil(new
Promise())) the only thing I can think of is a timeout that is configurable
on waitUntil, e.g. waitUntil(new Promise()).maxTime(30s)






On Mon, Sep 28, 2015 at 12:36 PM, Joshua Bell  wrote:

> On Mon, Sep 28, 2015 at 11:42 AM, Marc Fawzi  wrote:
>
>> Have you looked at ES7 async/await? I find that pattern makes both simple
>> as well as very complex (even dynamic) async coordination much easier to
>> deal with than Promise API. I mean from a developer perspective.
>>
>>
> The linked proposal contains examples written in both "legacy" syntax
> (marked "ES2015") and in ES7 syntax with async/await (marked "ES2016").
> Please do read it.
>
> As the syntax additions are "just sugar" on top of Promises, the
> underlying issue of mixing IDB+Promises remains. The proposal attempts to
> make code using IDB with async/await syntax approachable, while not
> entirely replacing the existing API.
>
>
>>
>> Sent from my iPhone
>>
>> On Sep 28, 2015, at 10:43 AM, Joshua Bell  wrote:
>>
>> One of the top requests[1] we've received for future iterations of
>> Indexed DB is integration with ES Promises. While this initially seems
>> straightforward ("aren't requests just promises?") the devil is in the
>> details - events vs. microtasks, exceptions vs. rejections, automatic
>> commits, etc.
>>
>> After some noodling and some very helpful initial feedback, I've got what
>> I think is a minimal proposal for incrementally evolving (i.e. not
>> replacing) the Indexed DB API with some promise-friendly affordances,
>> written up here:
>>
>> https://github.com/inexorabletash/indexeddb-promises
>>
>> I'd appreciate feedback from the WebApps community either here or in that
>> repo's issue tracker.
>>
>> [1] https://www.w3.org/2008/webapps/wiki/IndexedDatabaseFeatures
>>
>>
>


Re: Indexed DB + Promises

2015-09-28 Thread Joshua Bell
On Mon, Sep 28, 2015 at 11:42 AM, Marc Fawzi  wrote:

> Have you looked at ES7 async/await? I find that pattern makes both simple
> as well as very complex (even dynamic) async coordination much easier to
> deal with than Promise API. I mean from a developer perspective.
>
>
The linked proposal contains examples written in both "legacy" syntax
(marked "ES2015") and in ES7 syntax with async/await (marked "ES2016").
Please do read it.

As the syntax additions are "just sugar" on top of Promises, the underlying
issue of mixing IDB+Promises remains. The proposal attempts to make code
using IDB with async/await syntax approachable, while not entirely
replacing the existing API.


>
> Sent from my iPhone
>
> On Sep 28, 2015, at 10:43 AM, Joshua Bell  wrote:
>
> One of the top requests[1] we've received for future iterations of Indexed
> DB is integration with ES Promises. While this initially seems
> straightforward ("aren't requests just promises?") the devil is in the
> details - events vs. microtasks, exceptions vs. rejections, automatic
> commits, etc.
>
> After some noodling and some very helpful initial feedback, I've got what
> I think is a minimal proposal for incrementally evolving (i.e. not
> replacing) the Indexed DB API with some promise-friendly affordances,
> written up here:
>
> https://github.com/inexorabletash/indexeddb-promises
>
> I'd appreciate feedback from the WebApps community either here or in that
> repo's issue tracker.
>
> [1] https://www.w3.org/2008/webapps/wiki/IndexedDatabaseFeatures
>
>


Re: Indexed DB + Promises

2015-09-28 Thread Marc Fawzi
Have you looked at ES7 async/await? I find that pattern makes both simple as 
well as very complex (even dynamic) async coordination much easier to deal with 
than Promise API. I mean from a developer perspective. 


Sent from my iPhone

> On Sep 28, 2015, at 10:43 AM, Joshua Bell  wrote:
> 
> One of the top requests[1] we've received for future iterations of Indexed DB 
> is integration with ES Promises. While this initially seems straightforward 
> ("aren't requests just promises?") the devil is in the details - events vs. 
> microtasks, exceptions vs. rejections, automatic commits, etc.
> 
> After some noodling and some very helpful initial feedback, I've got what I 
> think is a minimal proposal for incrementally evolving (i.e. not replacing) 
> the Indexed DB API with some promise-friendly affordances, written up here:
> 
> https://github.com/inexorabletash/indexeddb-promises
> 
> I'd appreciate feedback from the WebApps community either here or in that 
> repo's issue tracker.
> 
> [1] https://www.w3.org/2008/webapps/wiki/IndexedDatabaseFeatures
>