JAKE ARCHIBALD: Hello. This is me. This is Jake. I'll be talking about
IndexedDB and web standards in a few minutes with
my good colleague Surma. SURMA: Hello. I'm Surma. Hello. - So we are good to go. Good to go? JAKE ARCHIBALD: Do
I need face powder? Am I shiny? I sometimes get shiny. [MUSIC PLAYING] So. SURMA: So. JAKE ARCHIBALD: So I'm
going to try and do something a little bit
different this time. SURMA: I can tell. We have a laptop here. We don't have a
laptop here, usually. What's happening? JAKE ARCHIBALD: We've
got a laptop here. Now, do you remember the
YouTube series "Supercharged?" SURMA: Ooh. I'm not very familiar with it. JAKE ARCHIBALD: Right. Well, I thought I would
try and do that, basically, but on "HTTP 203." SURMA: So after I said this
is the end of "Supercharged," you're now like,
I'll bring it back! LOL. JAKE ARCHIBALD:
Bringing it back, yes. SURMA: All right. Let's do it. Let's do it. JAKE ARCHIBALD:
There's a little twist. SURMA: Oh, OK. JAKE ARCHIBALD: And instead
of coding something, like, you're building something,
I'm going to edit a web spec-- SURMA: Oh! JAKE ARCHIBALD:
--because it's something that I only really learned
to do the past few years. It's not something
a lot of people do. And I found a feature
that I wanted to add. It's relatively small. SURMA: OK. JAKE ARCHIBALD: So I thought
we'll go for the whole end to end-- SURMA: Let's do it,
because I've never-- JAKE ARCHIBALD: Right. SURMA: --done
actual spec editing. The only thing I've done
is I contributed links to the stream spec, so you
can click links and make it more navigational. And I can read the odd
spec every now and then, but I've never actually went
through the normative sections or anything. So that's-- all right. I'm going to have questions. JAKE ARCHIBALD: OK. SURMA: I'm going to
throw them at you. JAKE ARCHIBALD: That's good. That's good. Yes. So I'm going to start with
trying to describe the problem. The problem is IndexedDB. Now, there a lot of-- SURMA: I was-- JAKE ARCHIBALD: --problems-- SURMA: Yes. JAKE ARCHIBALD:
--with IndexedDB. SURMA: This is a bad start. JAKE ARCHIBALD:
Yeah, and we're going to talk about one
specific problem. SURMA: Are we fixing IndexedDB? Is it going to be better? JAKE ARCHIBALD: Very,
very slightly better in a very small way. SURMA: Better than worse. So, OK. JAKE ARCHIBALD: So
when you do IndexedDB-- this is me trying
to remember the API. SURMA: The actual API not your
nice, promised warp on top. JAKE: Yeah, this
is raw IndexedDB. You get a request object. And there's on success. I really love
autocomplete [INAUDIBLE].. It absolutely saves me. Right. We got our own success. This is going to give us
a database, which is-- .results. Yes, I'm remembering the API. SURMA: Because why
would it be a parameter to the on-success function? JAKE: Of course, not. IndexedDB is a horrible API. SURMA: It's a fractal
of weird design, really. JAKE: Yes. So the way you
work with IndexedDB is you create a transaction. So I'm going to go transaction. And you give it the name. SURMA: I mean, we can't
assume that people know what IndexedDB is. It's a database on
the client side, and you can have
multiple storages. And you can put things
into the storages. And you have transactions
that we've shown here. It's a pretty, in a sense,
a pretty powerful API-- JAKE: Yes. SURMA: --once you
have wrapped your head around the kind of weird API
that got shipped in the end. JAKE: Yes, and there's a
very specific part of it that I run into, a
problem that I run into, and it's with cursors. SURMA: All right, so you
create a transaction. The transaction is on
a specific store, which can have multiple entries. Imagine a SQL database
with your tables and rows. A table would be a
store and in that store can be multiple entries
as in rows in a SQL database. JAKE: Yes. SURMA: So you have to limit your
transaction to a set of stores, I think. In this case, it's just one,
but it could be multiple. JAKE: Exactly. Exactly. So I'm going to go
on success here. And this how you open a cursor. SURMA: And a cursor is
basically a little data. So it allows you to traverse
all the entries in a store. JAKE: Yes. SURMA: So much I
do know about IDB. JAKE: So I've done that now. So this is this
whole boilerplate. SURMA: So quick and easy. JAKE: It's a really
easy episode to explain. This is basically the start. SURMA: Boilerplate. JAKE: So I I've been
creating a little wrapper library around IndexedDB. SURMA: For a awhile now. JAKE: For a while now. Yeah, it's been
released for a while. I'm working on the next version. SURMA: The next major version,
with breaking changes, I guess, and everything. It's called IDB? JAKE: It is called IDB. That was available in NPM. Great. I'll take it. SURMA: Because, I guess,
we should be clear. IDB is your library. This API is called IndexedDB. JAKE: Yes, I made
it very easy to-- [INTERPOSING VOICES] SURMA: It's very common
to call IndexedDB IDB. But technically-- JAKE: Which is why I thought,
I'll take that namespace and try and make it
sound all official. SURMA: Great. Well done. JAKE: So what I
was trying to do is create an API, where, given
a normal IndexedDB object, you can pass it into my API. And it will enhance it
with all of the extra stuff and make it easier to use. And the problem I ran
into is with cursors. So once you've got
a cursor, the cursor will give you the key and
the value of this one entry-- SURMA: Of the row that it's
currently at in the storage. JAKE: Yes. And when you want to
go to the next row, you do cursor.continue. And now, this doesn't
return anything. What it does is it causes
the request for the cursor to fire its success event again. SURMA: Right. So this is basically
a hidden way of calling this
function recursive. JAKE: Yes. It's a weird way of doing that. If the cursor is
null, you're done. SURMA: Then you reached the
end of your object store. JAKE: Exactly. SURMA: OK. JAKE: So I faced a
problem with this, because if someone just
passes me the cursor object, I have the means to-- SURMA: When you say, me, you
mean, you as the author of IDB? JAKE: Yes, the library. Or if you pass a cursor
to another piece of code, if we keep it generic, you
could then call continue. SURMA: And you're screwed. JAKE: Yeah, you've got no way
of hearing that that works or that fails, because you would
also need to have the request. SURMA: Yes, you need to be
in control of the on success handler. JAKE: Yes, and I noticed
that in IndexedDB, there's often routes back,
like the chain of this-- SURMA: The hierarchy. JAKE: The hierarchy. So from the store, you can
get to the transaction. You can get to the database. SURMA: DB. JAKE: I think it's DB. Yes, you get to the database. But there is no link
between the cursor and-- SURMA: The request. JAKE: --the request. So I want to say, wouldn't
it be nice if there was-- SURMA: The request. JAKE: The request. There we go. SURMA: And then I, as a library,
could temporarily override on success, do the continue
bits, do my work, and then-- JAKE: I could pass you a cursor,
and you could use that cursor. SURMA: That's great. That seems like a very
reasonable thing to have, Jake. Ship it. JAKE: Well, that's what
we're going to try and do. SURMA: That's what
we're doing today? JAKE: Yes, it is. SURMA: That's exciting. JAKE: So I thought,
how do I start this? SURMA: Yeah, well,
how do you start? Because now, you want to have
this on the web platform. I mean, you could
probably polyfill it by just attaching random
things to the cursor. But that wouldn't be standard. You want to make it a standard. So we have to look
into the spec, I guess. JAKE: Yeah, I would
say, what my library is doing is it depends
on being the thing which opens the cursor. Because then it has
the original request, and then it can maintain
that link itself. But if you just pass the
cursor, yeah, you're screwed. So if I was going to do some
work on a spec, what I would do is go to MDN. SURMA: Interesting. JAKE: I've got muscle memory
from when I searched MDN or NPM at the start of everything. I get the two mixed
up all the time. But this case, I
do want IndexedDB. SURMA: Yes. It's called IndexedDB,
not IndexDB. JAKE: I call it
IndexDB all the time. SURMA: So do I,
but I'm not saying, technically, you're wrong. JAKE: I'm technically wrong
about many, many things. I'm sure many of them
are going to come to light in this episode. SURMA: So yeah, I think, MDN has
always a very good browser port table and links to the
specs, which I value a lot. JAKE: Yes, and if you want to
find which spec something is defined in, MDN is the best
way, I think, to get into that. SURMA: But see, we
already have two specs. We have IndexedDB API and
IndexedDB API, version 2.0. JAKE: Yes, it's
useful, isn't it? SURMA: I'm guessing a cursor--
so basically, I would expect it to be in the version 1. Rather that's true is
a different question, but that would be
my gut feeling. JAKE: If you've got two
choices between two specs-- let's open them both. We'll have a look
at the URLs here. So this is the URL
for one of them. SURMA: But even that
one says 2.0 here. JAKE: Yes, that's because
2.0 has now shipped. We're now on to 3.0. SURMA: But the
links in MDN-- you should fix the links in MDN. JAKE: Someone should update MDN. If the link to a
spec has TR, there's a good chance you're looking
at the out-of-date one. SURMA: Yes, those
are the snapshots, which I've learned in Houdini. Those are the snapshots. This is a version we have
now officially-- this is the center that
has this version. And I've been told
what you should do. You look at this spec, and
you find the editor's draft. And that's what you look at. JAKE: And there will be a link. SURMA: Usually,
there will be a link. JAKE: The joke is,
TR stands for trash. SURMA: Oh, harsh. JAKE: And that's
not always true. Because sometimes, that is
literally the latest version of a spec, but if there is-- SURMA: To be fair,
it's only been recently I feel that
everything turned into more like a rolling release
approach rather than working from major version
to major version. JAKE: Yes. SURMA: All right, so if we have
the red bar on the left side, it means, we are on
an editor's draft and this will most likely
be the most recent spec. JAKE: Yes, exactly. SURMA: But doesn't
that mean that there could be stuff in there
that isn't even in browsers? JAKE: That is true. But for this use case, we
want the latest version, because the thing we
are wanting to create might already be created. SURMA: True. Oh, so we're looking
at the latest version to see if it's already created. If not, then our stuff
should be something that is added to the latest version. So that's why we're
working on this one. JAKE: Yes. So if I was looking
for something that I want to be
exposed to JavaScript, I'm looking in the spec
for the API section. Here it is here. SURMA: Yes. There is a section called API,
which gives you the typical web IDL thing. So you have an almost
TypeScript-like definition of the different things. JAKE: Yeah, so here it is. This is one for cursor. This predates TypeScript
by many, many years. SURMA: Sure. It has types. That's why I
mentioned TypeScript. JAKE: Yes, exactly. I mean, it would be
interesting to see, if we started writing
specs now from scratch, would we use TypeScripts? Is that enough? There's some extra little bits
of annotation around here, but it is doing the same job. It's defining the types
of all of these things. SURMA: But if that
is the section, what is the section above? Because I was looking
at the sidebar. And so, oh, 2.10, that's cursor. That's where we go, right? Why didn't you go there? JAKE: So specs tend to be
split into two sections. One is the constructs
or the concepts. Different specs call
it different thing. And this is just describing how
the feature works, irregardless of JavaScript. So [INAUDIBLE] JavaScript. We look at a database. The database has a name. The database has a version. This is just the talking
about the structure. It doesn't mean those things
are exposed to JavaScript. SURMA: So this helps
you write code? This potentially
helps or probably helps implementers understand
the nuances and details? JAKE: Yeah. Yeah, this is describing
how the system works. And then we would see,
down in IDB database, this is describing the
JavaScript interface, we'll see-- SURMA: Oh, look, a
name and a version. JAKE: It does have a
name and a version, but this needs to be
explicitly set up. So when you click on Name there,
it says the name attribute. You must return the name
of the connected database. We click that. It will then link
up to the concept. SURMA: So this is where
we connect the IDL stuff to the definitions
and the constructs area? JAKE: Yeah. So this stuff at the top
here, this lives in C++ land. It can live on another, thread. All of that sort
of stuff is fine. SURMA: That's probably
more relevant to implement. It's not really relevant
to me as a web developer. JAKE: Yes, I would say so. If you're looking to see what
a thing's capable of or what the API is-- straight
into the API section. And we can see the cursor here. SURMA: I feel much more
at home with his view already, because it looks a
little bit like JavaScript. I get this. JAKE: Yes. So you can see here, this
function called advance. SURMA: Oh, we have
advance and continue now. JAKE: Advance and continue. SURMA: What's the difference? JAKE: So advance takes a number. So I'm saying, skip five items. SURMA: So it's like calling
continue five times. JAKE: You can't call
continue five times. You can only call one of these
advancing functions once. Can you tell I've been working
with IndexedDB recently? I've had to get the
spec in my head. SURMA: I guess, I
wouldn't have called continue, then on success,
I call continue again. Do that five times, and then
that would be equivalent. JAKE: That would be
fine, but it tends-- SURMA: It's also annoying. JAKE: Yes, it sees it as
a bug if you try and tell it to do too--
because if you said, advance five and advance
two, it sees that as, like, which do you mean rather
than adding the two together. SURMA: So we do
see on the cursor that there is no request. JAKE: Right, which is
what we expected to find. We knew it wasn't implemented. So what do we do? SURMA: Do we just add
read-only attribute request and [INAUDIBLE]? JAKE: Not yet. SURMA: Oh, OK. JAKE: Because the next thing
is to propose the feature. SURMA: Oh. I mean, you can't just
decide this on your own. JAKE: I mean, you could. You're not going to get
anywhere with it, though. So you're going to
be very disappointed. So at the top of
the spec, there's a link here for issue
tracking, GitHub. It's mostly GitHub nowadays. SURMA: It is mostly
GitHub nowadays. JAKE: So I'm going
to go into here. SURMA: Oh, look at this. There's a cursor request issue
opened by Jake Archibald. JAKE: Yes, there is this. I've set this up
in advance a bit. In fact, when I
started doing this, I wasn't thinking about
making it an episode. But what I did was I went in
and said, this is a bit weird. Why isn't there
a cursor.request? It's essentially what I said. SURMA: Well, link this
in the description, because some people might want
to look at how you phrased it and how the discussion went. JAKE: Yes, exactly. This is what I
wrote just basically requesting the feature. SURMA: And do note, it's not
like a long form, formal tone proposal. Just like, I have this idea. What do people think? It's still a very
human approach, even though we are working
in spec world right now. JAKE: Yeah, I'm
describing the problem. I do suggest a solution, but
I describe the problem first. And that's a common problem I
see in some feature discussion. Someone comes and
goes, I want this. And the next question is, why? SURMA: But why? JAKE: So I start with the why,
and here's my proposal, in case the person who knows more
than me about this stuff can come and say,
here's a better way to solve your problem,
or here's a better solution to the problem. They don't have to wait
for the back and forth. And it turns out-- this is Josh Bell, who does
the implementation in Chrome, also does the spec work. SURMA: So he's a Googler. JAKE: He's a Googler. And he's saying, yeah,
that sounds all right-- oh, this doesn't
usually happen-- and sort of agrees
with the use case. He asks other spec
folks to chime in. And then we've got Ali from
Microsoft, Andrew from Mozilla, and Brady from Apple
saying, it's fine. This has never happened
before, not this quickly. SURMA: That is very,
very frictionless. JAKE: Yes, and I think
it's because it's such a small feature, and it
fits in with IndexedDB so well. And the implement
is like, they have a feeling it's really easy
for them to implement. SURMA: Yeah, I mean,
it feels like the thing that, under the hood,
should be very easy to do. I'm speaking as someone
whose never shipped anything in the browser
myself, but literally just exposing something
that already exists. And it's probably,
in turn, already tied to the request anyway. JAKE: Exactly. Exactly. And so that's what I thought. I thought, well, why not? Because it just feels
like a small change. Let's do it now. So that's the intro
to this episode. SURMA: Cue the intro. [HUMS A TUNE] JAKE: Are we going to put a
remix of the title sequence of "Supercharged" on there. SURMA: Oh, yes. Can we do that? Can we put comic Surma? [LAUGHTER] [MUSIC PLAYING] JAKE: So we're going to do this. SURMA: We're going to do this. Where do we start? JAKE: So there's
two things you need to land for a spec change-- spec change and tests. SURMA: Tests. JAKE: The tests
are very important. And I am going to
do the tests first. SURMA: Oh, you're going
test-driven development. JAKE: And I don't
always do this, but all the times
I've done it, it's been incredibly successful. So I don't know why I
don't do it more often. SURMA: So we have this thing
called web-platform-tests, which you can get
into by wpt.fyi. JAKE: Well, I would say, you
can get into it from the spec as well. It's right on top there. SURMA: Oh, there's a link. JAKE: A link to the test suite. SURMA: It links
web-platform-test, which is the repository. It has literally the entire
web-platform-tests, every API. It's supposed to have
a test suite in here. JAKE: Yes, absolutely. So this is all the
IndexedDB ones. SURMA: That's a lot of tests. JAKE: There is a lot of tests. SURMA: Oh, wow. JAKE: From many years ago,
some of them two years ago, to five days ago. That's cool. SURMA: Five years ago. JAKE: Five years ago. Excellent. Any advance in five years ago? SURMA: Doubtful. So there is a lot of files. JAKE: Yes. And so writing tests
is a really good way to contribute to
the web platform, because the tests
are in JavaScript. So you don't need to
understand the specification stuff in order to contribute. You just write a
test to describe how the feature you want works. SURMA: I have contributed
some tests myself. And while it is a bit odd,
because it's, obviously, kind of organically-grown
system over time, you just look at
some other tests. And you will get the hang of it
quite quickly and how it works. JAKE: And that is exactly
what we're going to do. So the repo, yeah, it
covers all of the-- it's a lot of scrolling-- all of the stuff you need to
set up something like this. SURMA: It is really
well-documented. I had no problem setting it
up the first time I wanted to. It just worked pretty
much straight away. So well done to them. JAKE: Yeah, so you
would check it out, fork it, and then follow
these instructions. Because there are some things
you need to add to your host file, yeah that sort of stuff. So what I'm going to do is-- I don't need to fork
my platform tests, because I actually have
commit rights to that. SURMA: Oh! JAKE: I know. Check me out. So let's go to-- and this is me
trying to remember. There we go. Brilliant. Web-platform-tests,
and this is what we're going to start editing. So I'm going to go to wpt serve. This is all documented. SURMA: Yeah, this
starts the test server. JAKE: Look at all that. It makes total sense. It starts to test
several many ports. This is one I'm going to use. This is the normal
unencrypted one. SURMA: Yeah, we
have multiple ports and multiple [INAUDIBLE]
names in this repository, because sometimes,
you need to do tests for cross-origin things. JAKE: Across things,
cross-scheme things, like HTP to HTPS,
that sort of stuff. SURMA: The server has
to write all of that. That's why that might have
looked a bit overwhelming. JAKE: Yes. So I'm going to pick
up one of these. SURMA: All right, now, in
the IndexedDB test folder, if you open any of the HTML
files, as far as I know, the tests will run, and
you'll see the results. Cool. JAKE: There we go. Look at that. SURMA: How did you
decide which file-- is this just to show the
results or show which file you're going to edit? JAKE: No. Different specs write
the tests differently. I picked a file called
IDBcursor-source. I would assume-- I
say I'm assuming. I know because I looked
at it in advance. These are the tests
for cursor.source. So from the cursor
objects, you can go to the source,
which gives you back the store or the index. SURMA: So you get cursor, you
can get the store, but not the request. So the request is
like the missing link. JAKE: Yeah, exactly. SURMA: Interesting. JAKE: So we've got that. So we're going to edit this. SURMA: So how afraid should I
be of picking the wrong file? If I want to [INAUDIBLE]
I'm not sure which HTML file I should add my test to. JAKE: I mean, not that afraid. SURMA: In the review, people
are going to be like, good test. Just move it to
this file please. JAKE: And then that's going to
be a very small [INAUDIBLE].. SURMA: The people
usually, in my experience, are really friendly. JAKE: Yeah, they are,
actually, and super-grateful for having people work on this
stuff, because it's dead handy. So let's go for
web-platform-tests. Break out the VS Code. Here we go. So yeah, we want to write
tests for the feature. Now one of the
benefits of doing tests first is, implementers
who are super-keen can start implementing
based on your tests while you're
working on the spec. This actually happened with
the abortable fetch stuff. SURMA: Interesting. JAKE: So this is why it's a
really good place to start. SURMA: So that
means it's not even frowned upon to open
a PR for my new tests, even if the spec change
hasn't landed yet? JAKE: Correct, and you
can have those reviews going in parallel. So here it is. This is the source for the
test we were just looking at. SURMA: So let's dissect
this a little bit. So we have the test harness,
test harness report, which is-- test harness,
we can ignore that for now. JAKE: That's the
framework for the tests. SURMA: It's literally
a harness for the test. JAKE: The equivalent of mocha
and chai, that sort of thing. SURMA: Support is probably
literally that-- support functions, I guess. JAKE: Yes, specifically
for the IndexedDB stuff. SURMA: Right, because
it's in this folder. It's not the global
support file. It's in the index. JAKE: Yeah, and that's how
I knew that just by the path there that it's local. SURMA: And the rest is test
functions, it seems like. JAKE: It is test functions. There's a cursor source test. And it seems like this
is generated tests, because they're calling
this function twice. It's passing in a function. I would say this is a very
complicated written test. It's difficult to follow. But one of the
important things for me here is seeing this,
that IndexedDB test. SURMA: So it's a special
IndexedDB test function. JAKE: Yeah, and I
know this is not part of the framework of the
web-platform-test framework. So one of the things
you can get from right at the bottom of the read
me for web-platform-tests is how to write
and review tests. SURMA: Well, that seems helpful. JAKE: I don't know why that
link is right at the bottom, but it is. So we go into Writing Tests. Test harness is one of the
includes that we had in there, and it will give you the
documentation for the test harness. And this is going to tell
you how to call tests, like you do that. SURMA: So I've
seen these before. You have, like you
said, a test function. So I was surprised to
see that IndexedDB has, apparently, their own
version of the test function. JAKE: Yes. Yes. So we can see here,
there's async tests. There's ways of doing all
of this sort of stuff. And then towards
the bottom, you get all of the lists of
different asserts. Here they are-- so
assert an array-- SURMA: So this would be
the mocha-chai thing. JAKE: Yeah, so this is chai. The rest of it was mocha, if
that's how you look at it. SURMA: "Mock-a?" Who knows? JAKE: "Mock-a," mocha. I don't know. So IndexedDB test
is not in there. This is something special. SURMA: So that would
probably be in the support-- [INTERPOSING VOICES] JAKE: Probably. And how much easier
has [INAUDIBLE] script modules made our lives? It would be so easy to find
where that was coming from. SURMA: Especially with
TypeScripts, and then VS code. We just press F12. JAKE: Yes. So I'm just going to
do index, and it's going to give me that file, and
then we can have a look at it. And it was IndexedDB test. Oh, there we go. So here it is. SURMA: So it gives us
async tests under the hood, as we can see straight away. JAKE: Exactly. SURMA: Do we care
about the details? You provide an upgrade function,
an open function, descriptions, and options. JAKE: Yes. Upgrade function,
this is something IndexedDB has a way of setting
its schema for a database. Open function is, once
it's open, once it's-- SURMA: The success handler,
basically, more or less, I guess. JAKE: Exactly. Exactly. And then just the
name of the test. SURMA: So I'm guessing
they wrapped it. So it makes sure it
cleans up after you, deletes all the
stray objects stored that might have been created. JAKE: Deletes in
advance the tests that-- makes sure it froze if it
can't delete the database, if it can't open the database. SURMA: Of course, it
turns out, IndexedDB is persistent to disk. So if we didn't clean
up after ourselves, we might blow up the disk usage. JAKE: Yes, and it
gets really messy, especially if you get the
tests overlapping each other. Yeah, so this handles all
of that, which is nice. So let's go back
to cursor source. Brilliant. So we can see here
that yes, there's going to be a couple of
callbacks to the first one there. This is where it's
setting up the database. SURMA: That's the
upgrade function. This is, I think, if
I remember correctly, the upgrade function, which is
called, they said at the start, it's the only function where
you can create objects stores. JAKE: Yes, create object
stores, create indexes. You can add stuff to
the store, but you can do that elsewhere as well. But yes, it's the only place
where you can actually modify the structure of the database. And then the next
stuff's coming in. SURMA: This where we actually
write the test, I assume. JAKE: Yeah. And we see here, it's being
passed t, which, I know, is the test object, because
that will appear here-- t.stepfunction. Web-platform-tests tests
have promise tests, which are so much
easier to deal with. Because you write
an async function, and it's just sequential. IndexedDB is more-- SURMA: Doesn't have promises. JAKE: Doesn't have promises. SURMA: Hence, your library. JAKE: Hence, the library. So we're dealing with
this step function, which is you declaring, I'm giving you
a callback that must be called. This is definitely-- SURMA: That meaning, if a
callback doesn't get called, the test will fail? JAKE: Actually, maybe not. Because a certain reach
is not going to happen. Do you know what? I'm not sure. For every callback, you have
to wrap it in step function. This is why I normally
do promise tests. So we're going to
cargo-cult this a little bit and write the test for
the feature we want. Can I duplicate in this? SURMA: You can if
you copy-paste. JAKE: Oh, copy-paste, of course. Brilliant. There we go. So I'm going to call all this. SURMA: So you're
creating a new file. JAKE: Yeah. SURMA: Will that automatically
run just by existing? JAKE: Yes. When browsers run all
of these tests at once, it just crawls
through the system. SURMA: Crawl? JAKE: Yeah. And we're going to have
IDB cursor request. I'll probably changed this bit-- @chromium.org. Have I spelled that right? Yes. That's about right. Excellent. And get rid of that. SURMA: You don't have any
cool letters in your name. JAKE: I know. It makes it easier to type on
a British keyboard, though. So we're going to write
these tests, then. SURMA: Delete the old ones. JAKE: Delete the old ones. Yeah, I guess, we don't
really need anything else. I kind of wasted everyone's
time copying and pasting that. Because we're going to
start with pretty much this. So actually, what I will do is
we'll keep this around so we can double-check-- SURMA: For reference. JAKE: --how to do stuff. It's not something
I've done a lot of. IndexedDB test, and then we've
got free functions coming up. So this first one is going
to be setting up a database. So let's do that. Takes a test object
in the DB, I think. Is that what it did? SURMA: Yeah. JAKE: All right. Do you know what? This looks pretty good to me. I'm just going to take it. Why not? SURMA: We don't even
need an index, do we? JAKE: We don't need an index. SURMA: We do need data. JAKE: We do need data. I will take add-data
and entire-data. And just to prove that
I didn't steal it-- SURMA: Modern JavaScript. JAKE: It's modern now. SURMA: I was about to ask,
because you used an error function. You used const. What JavaScript is
usually acceptable? JAKE: It comes down to-- SURMA: Because there
was a time, where led and const or r functions were
in some browsers but not others. JAKE: Absolutely. And so the idea is,
you want these tests to run easily in the browsers
you want them implemented in. So I wrote some service worker
tests, and I used broadcast channel to do communication. And it was kind of like, if you
want Safari to get this right, you need to stop using
broadcast channel. I was just using it as a
way to pass messages around. It wasn't technical
to the test, but it was making it fail in Safari. So here, this is only going
to be adopted by new browsers. SURMA: We're talking
about the new feature. So it's not something that we're
targeting at i11, for example. JAKE: Exactly. SURMA: We can look at the
most recent versions of all the standard browsers, and if
they have a certain feature, it's cool to use it in the test. Is that basically fair to say? JAKE: It is absolutely
fair to say. So what am I going to do now? So where does this come from? Oh, OK, so they're
passing this function in as a way of
creating a cursor. So I don't know. I'll steal that code
as well, I reckon. So let's do that and
format that all nicely. So we've got a database. We're created a transaction. Create an object store. We're not using an index. That's going to be a
request for our cursor. Cool. SURMA: Sounds good. JAKE: So in our
request, .onsuccess. And this is where we
need to bring in that-- SURMA: The step function. JAKE: The step function. And because I have
zero memory, I'm always going to look
up the step function. It really annoys me that
it's underscore-based. It's not JavaScript. SURMA: I saw a lot of-- they're called snakecase. JAKE: Yes. SURMA: It is, in
a way, JavaScript. I know you [INAUDIBLE] I think. I think, in terms of
[INAUDIBLE],, has mostly settled on camelcase. JAKE: Camelcase. I think, a lot of this
framework is Python-based. So I think it may be
his inherited from that. SURMA: It's still readable. So it's not too big
a deal, I think. JAKE: And I think I could just
pass a function into there. Right. That's fine. And so we're kind of at a
point now, I've got my cursor. And this is one of the
reasons why we needed to add data into this store. Because if we didn't do that,
we wouldn't get a cursor. SURMA: We wouldn't get a
cursor, because there's nothing in there. JAKE: Exactly. So I'm going to req.result. SURMA: So currently, you
don't have a description of what this test is testing. JAKE: Oh, that's a good point. SURMA: Where would that show? JAKE: It is the third argument. So here, I will write-- well, let's take
some inspiration from how the other
ones are written. SURMA: They are not. JAKE: Brilliant. Excellent. SURMA: There's a test name here. JAKE: So where's it
getting that from? Oh, it's the first argument. Oh, I see. So they're taking
document-- wow. SURMA: You're going
to steal that? JAKE: Yeah, why not? Because I should. It's pointed out there's
a bit I've forgotten here. This so hacky. SURMA: So document.title. JAKE: That's it. SURMA: That's our test. JAKE: That's our test. Brilliant. So now, I need to write
some tests for this feature. SURMA: I'm hoping someone
says in the review that this is not a good
title for the test, because it's just IDB cursor-- actually, it is a good-- JAKE: No, no, it's
got .requests. SURMA: Yeah, that's
actually a decent title. JAKE: To me-- and this is a
totally off-topic [INAUDIBLE] when people write
this, to me, this looks like a static
property of the class. SURMA: Oh, that debate. Because start request is not
on the IDB cursor constructor. It's on an instance
of IDB cursor. JAKE: I've seen some people
do this, or you could do-- SURMA: Oh, no! No. JAKE: I mean, that's-- well, whatever. Fine. SURMA: Technically correct. JAKE: Technically correct,
I think, you'll find. So I've got the cursor. And now, I want to
write some asserts. I'm going to do assert equals. There we go. So it's the actual value,
the expected value, and the description. SURMA: All right. The code seems doable. JAKE: Because what I want is-- equal. I guess, is there
a strict equal? I would usually go
for a strict equal. SURMA: I'm guessing
you'll want to just check for existence, right,
or for not null? JAKE: Yeah. Well, I think it might
be strict by default. SURMA: I would hope so. JAKE: It's not in chai. This is the thing. I've been writing
chai this morning. SURMA: Strictly true. JAKE: Strictly true,
but down here-- SURMA: Relies on triple equals. JAKE: Oh, it relies
on triple equals. Well done. So it uses strictly
there, and then uses-- SURMA: What kind
of documentation? JAKE: Brilliant. Excellent. It's actually really good docs. So assert equals. I want cursor-- see,
I can't spell cursor-- .request. And I want that to equal-- SURMA: The rec. JAKE: The rec. SURMA: Cursor has request. [SNICKERING] JAKE: I can't type anything. SURMA: How do you
get stuff done? JAKE: Well, I don't. That's what happens. So we've actually tested
quite a lot in this one line. Because we've not only tested
that cursor.request exists. We've kind of tested its type. SURMA: And the correct value. JAKE: And the correct value. SURMA: This is all
you're asking for. You just want the .request
to exist and be the value of the original request. JAKE: Yes. But this test also
tells implementers that it's not a
new request object. It represents the same
underlying request. It is literally the
same JavaScript object. It's going to be
equals, equals, equals. SURMA: So that's
actually interesting. Is that something that you
care about as a developer? If you just want to have
access to the request with all the data it provides,
do you actually care about it being the
exact same instance? JAKE: I think you do. Because there's
not a lot of time, you'll be doing equals,
equals, equals or something. But you might be
using weak maps. SURMA: Good point. JAKE: And so you want
the representation of the same thing to be
exactly the same thing. SURMA: Yes, you want
the quality to hold. JAKE: Yep. SURMA: That makes sense. JAKE: And what I will also do
is, I'm going to steal from-- let's see. What else have they got here? So they're testing instances. We don't need to do that. That's already taken care of. The stringified objects,
that's already taken care of. Because it's equal to requests-- SURMA: You already have request. JAKE: Yeah. That's somewhere else. But this, we're going to steal. Because I want to make sure
that, like the other things, that cursor.request is
going to be read-only. SURMA: All right, so
that's actually different-- so you don't pass
in cust to request, but the name of the property. Because, I'm guessing, it
gets the property descriptor and checks for the
read-only file. JAKE: Yeah, and I guess,
it will try and set to it maybe as well. I'm not actually sure what
the implementation is. But that, essentially,
tests the two things that will make it similar
to the other bits, but the thing that we want. And I think that's it. SURMA: So now, we can run
the test and see it fail. JAKE: Now, we can run
the test and see it fail. So I should just
be able to request. SURMA: And it failed. JAKE: It failed. SURMA: Equals is not defined. That's not the error
I was expecting. JAKE: No, it is not the
one I was expecting. So it's equals or-- SURMA: I would-- yes. JAKE: Yeah, look at that. SURMA: The one time
you don't copy-paste. JAKE: I know. I'm such a copy-paster. SURMA: So it should still fail. JAKE: Expected
objects got undefined. SURMA: Hurrah. We have uncovered that
this test is failing. JAKE: If you wanted
to stop here-- and you have helped
massively with web standards. The feature you want
that you've been told, yeah, great, writing
the test for it is a solid solid effort, right? It's more than most people do. And you haven't had to-- SURMA: That is actually a
really good point, in the sense, if you're not comfortable
engaging necessarily with spec language
and all the patterns and stuff that comes with that,
this is a very approachable way to how can you drive features
that you personally might want. JAKE: Exactly. It's really difficult
writing tests for things that don't exist,
because you don't really know how-- does your test actually work? I mean, we spotted something. But maybe you would
do something like-- I don't know-- what if we
did cursor.request equals? We'll just do that. Oh, right. So it's got onto the next
test, but it's showing us that it's not read-only. So we at least know that
it passed that first test. So we can kind of prove-- SURMA: So that's why the
test is actually important. JAKE: It's actually important. So we know we've got somewhere. We know we've got a solid test. SURMA: All right, so
what you would do now? You would commit this,
PR it, and then we'll move on to the spec? JAKE: Yeah. I will do them in tandem, and
we'll do the PRs at the end. But yes, if you wanted to
stop here, you could do that. You could have
people check it over. SURMA: As you said, this would
already help browser developers to implement this feature. JAKE: Exactly. But we're going to
radio this back. SURMA: Oh, boy. Oh, boy. JAKE: So we're going to have
a think about what we actually need to change. We've already talked about
the structure of the spec it's in, so the two parts. So we would need
to create a link between the cursor
and the request, and then find a way
of exposing that. SURMA: I guess, we would check
first if, under the hood, the cursor doesn't already have
a link defined to the request, right? JAKE: Exactly. And in the same way that if
you call cursor.continue, it works somehow. SURMA: And then uses
the request, right? JAKE: Yes. So it must have some
kind of connection to the request under the
hood, and we will see here. SURMA: The cursor has a request. JAKE: Yes, which is the request
used to open the cursor. SURMA: Great definition. JAKE: It's there. It was just never
exposed to JavaScript. SURMA: Interesting. So I guess, what you
just did, you just skim read the bold
things, I guess, right? That is the kind of eye you
develop if the more time you spend in specs,
where you're able to look at this flood of words
and don't actually have to read every paragraph. JAKE: Well, the way I
actually discovered that is I went into object store. I went into open cursor. I started sort of reading how
does open cursor actually work. Because this is where
you get the request. SURMA: So that this is the
fifth section called Algorithms, I guess? JAKE: Yes, which is just
sort of where the two things are matched together. SURMA: So it's not quite code. It's prose in a
step-by-step fashion. But that is basically what the
implementers then turn into C++ code most of the time. JAKE: Yeah, and [INAUDIBLE],,
that sort of thing. SURMA: True. What's actually
running under the hood? JAKE: And this is where I
saw step eight, which was, set cursors request to request. SURMA: That's ironic. JAKE: There it is. And linking back to it,
a cursor has a request. That's-- SURMA: It's there. That tells that the
implementers already have this in their code. A cursor has a request. So that would tell
me, from what you've told me so far, that the only
thing that's actually needed is to put something
into the API bit. JAKE: To link those
things together. SURMA: Yeah. JAKE: Pretty much. Well, let's dive into it. So at this point, you would
go to GitHub clone spec. Then you got a copy of it. SURMA: What does a spec
look like in code, Jake? JAKE: Well, let's have a look. Is it IndexedDB? SURMA: It is. JAKE: Look what I did some
work with intersection. It was over at some point. I can't remember
that, but fair enough. Let's sort out the way item
likes to resize things. There we go. That's fine. So if we have a look
at what's here-- SURMA: That's a lot. JAKE: There's a load of stuff. The actual spec-- SURMA: It is an HTML file. JAKE: But that's not it. That's generated. SURMA: That's the
compiled output, isn't it? Because the source is a
language called bikeshed. JAKE: Bikeshed. And this is this
file here, index.bs. It's very funny. Bikeshed-- and it's
a special format kind of based on markdown. It has markdown properties. SURMA: Show it to me. JAKE: Let's dive in. Let's dive in. So here we go. SURMA: More window resizing. JAKE: More window resizing. SURMA: Oh, look, the
tabs already open. JAKE: The tabs already open. It's almost as if I've been
looking at this already. So this is it. SURMA: Wait. Let's go to the top. Let's start at the top. JAKE: We don't have time to
go through the whole thing. SURMA: No, but what
do you get greeted with when you open this file? JAKE: When you open this file. SURMA: Oh, look, it's HTML. JAKE: Yeah, you
can put HTML in it. It is like markdown
in that respect. You can see the list of editors. This is just a metadeta section
that bikeshed understands. SURMA: Is this what will be
translated into the section we saw at the start
of the spec, where they're linked together a bit? JAKE: Yes. SURMA: So this is
actually something that will also be parsed. It's not just a
generic pre-section. Yep it is actually being parsed
and turned into the links that you see at the
start of the spec. JAKE: Exactly. So there's more
metadata, some styles, because it is just HTML. They've got some custom styles
here, for whatever reason. And then we're starting
to get into markdown, so markdown heading. I like this little comment
thing they've done there. You don't need to do
that, but it looks nice. Also, oh, soft wrapping-- I dislike it. SURMA: I do, too. JAKE: I can turn
wrapping on this. Why do I have to do-- and also, what column
is this wrapped up? It's entirely arbitrary. Why is that-- SURMA: This one runs over. JAKE: I suppose that's code. But you can see-- SURMA: That looks familiar. JAKE: Familiar markdown if
you've used GitHub before. Anyway, that's a
different topic. If you're editing a spec,
the best thing to do is to just sort of figure
out what styles they use, and just copy them. SURMA: Go with the flow. Don't stand out. Make it a consistent
as much as you can. Don't go about
fixing other stuff, because it will make your
dif or your PR much harder to look through. The thing that you
add, make it seem like it's part of the spec. JAKE: And some
specs use more HTML. Some use more of these
bikeshed shortcuts. There's quite a few shortcuts
going on here, which I prefer, than writing out HTML by hand. I should say that,
if you want to-- SURMA: I was going to ask. If you wanted to know
what kind of shortcuts there are for bikeshed-- JAKE: Yes, so if you
wanted to get bikeshed, wanted to use bikeshed-- SURMA: From our
colleague, Tab Atkins. JAKE: From Tab Atkins. It's not the only
spec-compiling thing available. There's ReSpec as well. I don't really know
a lot about ReSpec. So I've not done a lot of work
on those standards before. But there is documentation. The documentation is also
being generated with bikeshed. Very good. SURMA: Ah, very recursive. JAKE: And so it looks
like a living standard, and it details all
of these shortcuts. SURMA: And to install
it as well, which you might be interested in. JAKE: Yes, I would say that
there's also a web service. You just give it
a bikeshed file. It gives you HTML back. SURMA: Handy, very, very handy. JAKE: Very, very handy. So let's sort of dive into how
we were going to tackle this. SURMA: All right, where
do you want to go first? Are we going into
the API section? JAKE: I would go
to the API section. SURMA: Let's go to
the API section. How do you go there? Because this is a big document. JAKE: It's a big document. And you know what I do? I look for some texts
[INAUDIBLE] the thing just to see if-- SURMA: I mean, our IDL should be
fairly precise to find, right? JAKE: Yes. SURMA: I mean, or the word
interface, which, I think-- JAKE: So let's
maybe look for this. Interface is going
to be everywhere. SURMA: I meant the entire thing. JAKE: Oh, the entire thing. But whether that would
be in tags or not-- SURMA: Oh, no, that looks good. JAKE: So this is OK. We've only got a few of these. There it is. SURMA: IDB cursor,
interface IDB cursor-- this is where we want to be. JAKE: This is where
we want to be. And we want to add
a new thing here. Read-only attribute. Now the way Web IDL-- what it
calls an attribute-- and this really confused me
for a long time. I thought it meant
HTML attribute, because that's where I
was seeing it in specs. What it means is getter. If you want to look
at Web IDL, of course, there's a spec for this. SURMA: So wait a sec. Couldn't we just remove
the read-only only define the getter? JAKE: You could. Now the reason Web IDL
tends to be quite detailed is browsers actually use
it for code generation. SURMA: Right. JAKE: So there tends to be
quite a lot of information embedded in this stuff. So browsers will
actually parse this. It will parse this bit in
Node to expose that stuff. And it will, essentially,
generate a lot of code. And the developer just has to
sort of fill in the innards. SURMA: You're talking about
the browser developer? JAKE: The browser
developer, exactly. So what do we want to do here? So the first bit is
the return type, which is going to be IDBrequest. SURMA: Which you looked
up some time beforehand that there is also the
interface IDBrequest. JAKE: Yes. From using IDB, I
know, it's that. And let's call it request,
because that makes sense. And there we go. Let's see if it compiles. SURMA: Are we done? JAKE: We're not done. Oh, boy. Because I've installed bikeshed,
I can do a bikeshed watch. Let's do that, and off it goes. It has a think about some stuff. Done. Great. Excellent. SURMA: And now, I guess, the
HTML alpha has been updated. JAKE: Yeah, and bikeshed,
it checks a lot of stuff. So we have actually
got a warning here. It says, there's a definition
that's not referenced locally. If I remove that edit
we made, that error is still going to come up. So I would always say,
run first before editing. And if there's errors, they're
the ones you can ignore. Because they're not your fault. SURMA: That's good. Because I can't tell what this-- JAKE: So what it means, what's
actually happening here is-- SURMA: Oh, equivalent. JAKE: Equivalent. So this is just a web
server that I started up. SURMA: Because bikeshed
doesn't do that for you? It maybe can, but you
did do it just now. JAKE: API can't do it. Because it's just an HTML
file, it works anyway. I always run-- SURMA: You can
just open the file. You don't even need a website. JAKE: You probably could. But I always run a web
server on my death folder. SURMA: Oh, I'm a real developer. JAKE: I've got it set
to happen at start up, because I always need
one at some point, and it's normally
in that folder. So what were we looking up? It was this weird
equivalence thing. So we can see this in
bold definition here-- as long as the end result is
equivalent-- but nothing's actually referencing it,
and it's not exported. So it's flagging up and going,
you've got this thing here that you're not using. Why? Which is kind of cool. SURMA: That's helpful. JAKE: But you know what? Not our problem. SURMA: Not our problem. We didn't write it. JAKE: Let's have a look
at the cursor API stuff. SURMA: (IN SINGSONG
VOICE) Dun-dun-dun. JAKE: Oh, my god. Look at that. SURMA: But it's bold
and not clickable, Jake. JAKE: Yeah, it's not clickable. SURMA: The other
one's different. JAKE: It's the only
reference to this thing, because we've not
reference that elsewhere. We've been looking at
source being something similar to what we've got. SURMA: Pretty much, yeah. So where does it link? JAKE: And so this just
happens below this block. It's saying here, the
source attribute's getter-- so once again, prose-- must return the
source of this cursor. And these are all linked
up, and you can sort of see what it is, which is the
index of the object store. SURMA: Which is [INAUDIBLE]. It will never return
null or throw. All right, cool. JAKE: Yeah, it's interesting. So everyone every spec
author has their own sort of style and quirks. I would say, "this attribute
never returns null" is something I would
put in the notes. The fact that it never returns
null is defined elsewhere. That's kind of just
like a code comment, which I would put in a note. Because it's not
essential information. It's helpful, but-- SURMA: Neither of these
approaches are wrong. You can do it this way. You can do it your way. Both seem to be working fine
because this is in a spec. JAKE: One thing that is not
how I would write a spec, but I see a lot in
spec land is actually something I used to do,
and I was told off for it. It says, "this returns
the source of the cursor." But the source
points to this thing up in the constructs land. And the spec
doesn't describe how to turn that into a
JavaScript object, which should be explicit, really. When I started doing
this, Boris Zbarsky, who's one of the huge
minds at Mozilla, said, well, how do
I convert to this. It's like, well,
isn't it obvious? It's like, yeah, but what
have you got for your IFrames on your page? Should I create the
object in the IFrame. I was like like, no,
that would be stupid. You need to write this down. And also, if you access
the getter twice, does it give you a
new object each time? I'm like, oh, I see. And so the idea is that
stuff should be spec. So someone could follow
this spec to the letter and return a different
object every time that represents the
same underlying thing. SURMA: Yeah, leaving
room for interpretation is something that leads
to inter-op issues, which is something we've been
trying to avoid really hard. JAKE: Exactly. But we're going to just
follow what they do. The good news is,
the whole thing around object equivalence,
we have covered in the tests. SURMA: True. So even if there is
room for interpretation, the text version of
the spec, the tests can remove that ambiguity. JAKE: Absolutely. Do you know what? See, I like me
some copy-pasting, so I'm going to sort of
move this down to here. Let's go for it. So this is bikeshed syntax. It's a definition. It's an attribute in
terms of IDL-speak. It's for IDB cursor. So this is saying, this
thing that we're defining is a child of IDB cursor. SURMA: And that's how it
actually knows where to link. JAKE: Yep, and that's
referencing that there. So the getters must return the-- and so this is bikeshed's
syntax for creating a reference. And you can reference things,
not just in this spec. You can reference things
outside of this spec. SURMA: Oh, you can [INAUDIBLE]. I mean, I've seen it
a couple of times, where one spec will
link to another. JAKE: Yes, and this
is because bikeshed has this big database of stuff. I could put here, returns the-- I don't know--
let's call it a URL. So these double-curly
braces means I'm referencing an interface. So if I did that, and we
should see this rebuilding. What's it telling us now? Multiple possible URLs. So what I'm going to ask it is-- I'm going to put a
slash there to say, I want the top level
URL not the URL that belongs to something else. It might be that
that still breaks. No, that seems fine. We've got multiple attribute
definitions because of our copy and pasting. SURMA: Which is fatal,
but it's still compiled. JAKE: It's still compiled. Bikeshed is great for
this sort of thing. SURMA: Very lenient. JAKE: It just gets the job done. So now, we would see down here. We got the source
appearing again. Must return the URL,
because I put that in there. SURMA: And it links to the
URL spec in the what WG. JAKE: And it links to
the URL in the what WG. SURMA: That's handy. Not that we need it right
now, but it's good to know. JAKE: No, I just-- because the change we actually
need to make is super-boring. SURMA: It's so simple, isn't it? JAKE: So the request
attribute getter must return the-- let's get
rid of that URL-- the source request
of this cursor. SURMA: You want to
remove the rest? Whatever. You are going to
remove the rest. JAKE: And now, let's
see that build. Da da da. SURMA: No fatal errors. Well done, us. JAKE: No additional errors
from ones we had before. SURMA: Very important
to point that out. JAKE: And so we can see
now that our IDB request-- SURMA: It's now linked. JAKE: It's now linked. And it says, "the request's
attribute getter must return the request of this cursor." Request links up to the thing. SURMA: That is A-mazing. JAKE: That's it. SURMA: So now, we commit
these two things-- our tests and our spec changes. Open the PR. JAKE: Yeah, so that's
what I would do. Let's create a branch, right. Let's call it-- SURMA: I know you have
commit rights to master. JAKE: I don't, actually,
not on IndexedDB. SURMA: Oh, true. This is IndexedDB. JAKE: This is IndexedDB So
let's call it cursor request. Excellent. Now I like Git GUIs. SURMA: You go for it. JAKE: I use my GUIs
for everything. SURMA: You be you. But can you zoom in? No, you cannot. JAKE: Oh. SURMA: Nope. JAKE: I tell you what. I can do this. There we go. And this is why I
like the Git GUI, because it's nice visual
showing me my changes. There's nothing
corrupt in there. SURMA: It is a
very small change. JAKE: It's a very small
change, which is good. I like this kind of overview,
in general, when I'm coding. Because the amount
of times I've caught console logs,
debugger statements, misspellings-- it's
my little code review. And I'm like, yes, I'll have
that and yes, I'll have that. I'm not going to
commit the HTML. It's telling me it's a new file. SURMA: That means that's
a get ignore or something? JAKE: Yeah or maybe it
should be in a get ignore. I'm going to ignore it. I'm going to go,
add cursor.request. And I will push those changes. Yeah, so that's pushed. But one thing that I
realized while actually editing the spec is we've
got two types of cursor. There's IDB cursor. And further down, there
is ID cursor with value. SURMA: Oh, as an
extended interface. JAKE: As an extended
interface, because you can get a cursor for
just the keys of a store and not including
the value as well. And this tends to be what
I do when I edit specs. I'll do the tests. I'll do the spec. And then I'll find something
that makes me think, hang on. Are my tests correct. And I'm a bit worried in
this case, because when we were doing the tests, SURMA: We are assuming
it has a value. JAKE: Well, no, we're
doing object store, and object store is
a cursor with value. SURMA: That's what I meant. So having a cursor with value-- JAKE: Yes, exactly. SURMA: So our spec
change actually defines on a cursor with the
potential without a value. JAKE: Well, yes,
the parent class. And that's where
we want it to be. So this is the point where
I go, eh, do you know what? I'm going to put openKeycursor. SURMA: Which is the IDB cursor,
the one without a value. JAKE: Exactly. Exactly that. Yeah, just to make sure it's
on the parent class rather than just that one subclass. SURMA: Is this something
that probably would have been caught by the code reviewer? Because these views will happen
in separate repositories, right? JAKE: Yeah. Usually, when you do spec work
like this, you make a commit. You do that. And people come back and go,
oh, I found this edge case. Do you want to
patch that up, make sure that they can't happen. That might happen
with this as well. SURMA: It's not necessarily
like a fatal mistake if we would have shipped it
without the OpenKeyCursor, with the OpenCursor instead? JAKE: Exactly. Exactly. SURMA: So I was just
trying to figure it out, because I would personally
be very afraid of if I don't notice this. I'm not even good enough
for web-platform-tests. JAKE: Right. I mean, people will help. Go and have a look at
any of my spec PRs. There's, like, 50
comments of discussion. I don't know if there's
going to be for this one, because it's, like,
a two-line change. SURMA: I would be impressed. JAKE: But hey, I'm
literally writing this now, so people could go and
have a look at the PR and see if that
is what happened. So yeah. I'll say, cursor request. And yeah, so this is me
committing the test now with my Git GUI. It's beachballing It's fine. Yeah, web-platform-tests
is huge. It has, like, 100
branches, because a lot of the browsers default
upstream from their own test stuff into it. But I'm looking at that. That's fine. It's got the right stuff in. SURMA: So in case we
do want a new file, because we created it. JAKE: Yep, so cursor.request,
I'm happy with that. And push that up to-- SURMA: We're done. JAKE: And we are done. SURMA: So now, we'll open PRs,
and we'll wait for the feedback from the other
browser vendors on it. JAKE: Exactly. And so hopefully, by the
time this episode goes out, people are just going to
have said, it's totally fine. There's no mistakes. You haven't done anything wrong. And this feature can just
be shipped very easily in browsers. SURMA: A-mazing. Thank you. JAKE: Right, let's, uh-- oh, look at that. Look at that resizing
being totally unhelpful. Tell you what. I'm not going to do that. SURMA: Tab. JAKE: I'm going to
create another window. Yeah, create another tab. Is that going to
resize badly as well? Yeah, it is. Of course, it is. Why not? Right, let's go like that. SURMA: (IN SINGSONG VOICE)
Something for the edit. JAKE: Something for the-- [LAUGHS]