w3c / IndexedDB

Indexed Database API
https://w3c.github.io/IndexedDB/
Other
241 stars 62 forks source link

Issues with key and keyPath usage #308

Open annevk opened 4 years ago

annevk commented 4 years ago

In particular key should not return an ECMAScript value in prose and keyPath shouldn't return a new array each time.

Originally from @bzbarsky in https://github.com/heycam/webidl/issues/823#issuecomment-554862858:

Now there are definitely some specs that seem to think that any means "an ES value". The IDBCursor.prototype.key getter certainly seems to think that...

On the other hand, the IDBObjectStore.prototype.keyPath getter does the expected thing and treats any as a union of IDL values; in this case it assigns either a DOMString of a sequence<DOMString> to it... but of course that's actually wrong, because it should be returning the same thing each time in the sequence case, so the spec steps there are kinda wrong and you have to ignore them and do something else. :(

bzbarsky commented 4 years ago

keyPath is weird in that on the one hand it says it returns an any which is set to a sequence<DOMString> in some cases, and on the other hand it says that if objects are returned those objects need to be stable. Those two normative requirements are incompatible, unfortunately. What's probably needed here is defining an actual processing model, including an explicit cached object-typed value that is cleared as needed, etc.

inexorabletash commented 4 years ago

Re: keyPath:

Re: key

Yeah, keys are happy fun times. Perhaps ideally, we'd have a typedef (unrestricted double or DOMString or Date or BufferSource or sequence<IDBKey>) IDBKey but I don't think circular definitions are allowed and again sequences as attributes aren't allowed by WebIDL syntax. I'd be more than happy to defer all of this and this to WebIDL but there's stuff it can't handle, and past discussions have leaned away from adding support for things only a single spec needs. Anywho...

HTML uses any for "an ES value" (e.g. postMessage()). Is the intent to change that? What's the preferred way to spec an escape hatch for arbitrary ES values that will be further processed in prose? I agree the WebIDL definition seemingly disagrees with that usage.

Note that IDBCursor's key is the "easy" case. IDBRequest's result can be a key (per above), or a value (arbitrary deserialized ES object), or an unsigned long long (from count()), or an IDBDatabase (from open()).

Suggestions (PRs, sketches of prose, napkin scribbles, etc) welcome! And as usual, apologies if I misinterpreted the feedback. Help on improving the spec is always appreciated.

bzbarsky commented 4 years ago

but sequence<>s are not permitted for attributes IIRC.

Right, because they produce a new object each time. So you can't currently, in IDL, express "it's a sequence but cached somehow". That said this is a case where something like https://github.com/heycam/webidl/issues/212 would help, because then you could describe the caching in the IDL.

I'm not sure why we haven't applied [SameObject] here.

Apart from the IDL spec only allowing [SameObject] on object types and this not being an object type?

it can lift the definition from [SameObject]

[SameObject] is currently purely documentation in IDL. It does not affect the processing model; it's the responsibility of the spec author to do that. Again, https://github.com/heycam/webidl/issues/212 may change that if it ever gets any responses from other browser implementors...

So at the moment something special is in fact needed in the processing model, until and unless https://github.com/heycam/webidl/issues/212 is resolved by adding some way of declaring that in IDL.

any does not mean "an ES value" in IDL. It means "an IDL value that can losslessly represent any ES value". The two are still conceptually distinct, especially when you sart to think about WebAssembly bindings. In the case of postMessage you're right that it's skipping a "convert this IDL value to an ES value" step, which is instead left implied. This isn't great, imo. Similarly, the keypath bits are skipping "convert this ES value to an IDL value" steps when storing various things inside an any.

It doesn't help that at least some browsers actually represent any as ES values in their implementations, which makes it hard for engineers working on those browsers to see a distinction...

Maybe this is all ok as long as it's clear what the conversions involved are; this just came up because someone was being confused about what any "is", due to people taking these shortcuts in specs....