00:06
<SamB>
why does everyone know zooko, anyway
04:43
SamB
does tend to agree that trying to apply monads in a system without anything at all resembling HM-typing results in a great deal of incomprehension ...
05:23
<SamB>
now, nested promises, those I can understand readily
05:34
<hayato>
smaug____: Good point. I guess no one. AFAIK, there hasn't been much attention on that from developers. We should go though all usage of 'in a Document'.
05:36
<hayato>
smaug____: does get-current-doc mean owerDocument property?
05:36
<SamB>
krit: HTMLElement isn't renamed to Element yet?
09:42
<tobie_>
JakeA: sorry for the confusion between the FetchStore and FetchStores APIs.
09:42
<JakeA>
tobie_: No worries, sorry for the terse reply. It was 2am & I'd been woken by a thunderstorm
09:42
<tobie_>
np: I'm getting a hang of what bothers me with the current API.
09:43
<tobie_>
And have a suggestion to make.
09:43
<Ms2ger>
mathiasbynens, the js tests in wpt live there because test262 never used to accept contributions
09:43
<jgraham>
JakeA: You too, huh
09:44
<tobie_>
Ms2ger: I think that's finally getting fixed now.
09:44
<JakeA>
jgraham: yeah, it was kind amazing to watch though
09:44
<JakeA>
kinda*
09:44
<tobie_>
JakeA: here's the APIs of FS and FSs side by side, for comparison: https://gist.github.com/tobie/ecc0768343f15870ae37
09:45
<tobie_>
FSs only operates on stores except for match.
09:45
<Ms2ger>
I still think we should merge test262 into wpt, but I'm not going to spend time arguing with tc39
09:45
<tobie_>
Ms2ger: I agree with both of these comments.
09:45
<JakeA>
tobie_: Yeah, it's a convenience method, but really handy in practice
09:45
<tobie_>
JakeA: Have you considered moving it to the service worker instead?
09:45
<Ms2ger>
If only I was at Google, then I had someone to litigate for me at standard bodies :)
09:46
<JakeA>
tobie_: It's useful for anything that uses FetchStores
09:47
<tobie_>
JakeA: that's a good point.
09:47
<tobie_>
JakeA: are there plans to extend FetchStores beyond service workers, though?
09:47
<JakeA>
tobie_: Eg, if you're wanting to update some page content from the cache then go to the network for fresh content (or race the two), being able to do fetchStores.match('/api.json').then(r => r.body.response).then(updatePage) is useful
09:47
<jgraham>
Ms2ger: What about Attorney Anne? ;)
09:48
<JakeA>
tobie_: I want it on the window object from the start
09:48
<Ms2ger>
Is Attorney Anne back from vacation yet?
09:48
<jgraham>
No. It is still July
09:48
<Ms2ger>
SamB, HTMLElement != Element
09:49
<JakeA>
tobie_: TabAtkins: Having a debate et un on the reject vs resolve(undefined) thing https://github.com/slightlyoff/ServiceWorker/issues/374
09:49
<tobie_>
JakeA: mmm. Shouldn't you just do fetch('/api.json').then(r => r.body.response).then(updatePage) in that case and let the SW handle the caching?
09:50
<JakeA>
Should be fetchStores.match('/api.json').then(r => r.body.asJSON()).then(updatePage) - sorry am le tired
09:51
<JakeA>
tobie_: Nah, you want the page to make two requests. One to the network via the serviceworker & one just from the cache
09:51
<JakeA>
tobie_: You could do both via the serviceworker, using headers or a querystring to make sure the sw gets the content from the correct place
09:51
<JakeA>
tobie_: But it's simpler for the page just to access the cache
09:52
<JakeA>
tobie_: the in-page code would look like https://gist.github.com/jakearchibald/766e0bffb87c87baeba3
09:57
<tobie_>
JakeA: The use case is display cached content immediately if available, update when fresh content comes in, right?
09:58
<JakeA>
tobie_: yep, which is the super A+ offline-first way to do things (Twitter native app does the same)
09:59
<tobie_>
JakeA: thankfully, Twitter knows better and just indicates fresh content is available.
10:00
<tobie_>
JakeA: the auto-replace with fresh content found elsewhere is terrible UX.
10:00
<JakeA>
tobie_: Well, it adds the new content but updates the scroll position so you're looking at the old content still, which is great
10:00
<JakeA>
tobie_: yeah, there's a few places you can get away with it, but generally it's bad. The G+ app used to do it.
10:01
<JakeA>
Actually, I think Facebook does that
10:01
<JakeA>
still
10:01
<tobie_>
JakeA: no comments.
10:01
<tobie_>
:D
10:01
<JakeA>
:D
10:02
<tobie_>
JakeA: OK, I think you're making a convincing argument that FetchStores belongs in window.
10:02
<tobie_>
(in window too).
10:04
<JakeA>
tobie_: It's unique to the origin too, like localStorage etc. If it stays in the sw people think it's unique to the sw
10:05
<tobie_>
that doesn't bother me that much.
10:08
<tobie_>
JakeA: OK, so my proposal to move .match() on the SW itself doesn't work. :/
10:09
<JakeA>
tobie_: What's the problem with .match on the FetchStores? It's just "give me a match from any store". Would matchAny help?
10:14
<tobie_>
JakeA: so the benefits of using just .match is that it Just Works whether you're using FSs or FS.
10:15
<tobie_>
(also its short, which people tend to prefer).
10:16
<tobie_>
The downsides, however, is it blurs the lines between FSs and FS.
10:17
<tobie_>
So as a consumer of those APIs I'm left wondering why FSs doesn't have matchAll.
10:18
<tobie_>
JakeA: Similar issue as to having FSs.get without having a FSs.set BTW.
10:19
<JakeA>
tobie_: It could have a matchAll
10:19
<JakeA>
tobie_: If you allow .set you can have the same store existing in fetchStores under multiple names, which is messy
10:20
<tobie_>
you could have that throw, no?
10:22
<JakeA>
tobie_: Yep, or just make it not-possible as in the current design
10:22
<tobie_>
So yeah, I think renaming FSs.match to FSs.matchRequest / FSs.matchAny / something that clearly marks it as a convenience method that operates directly on the requests rather than on the stores would make the whole API a lot clearer if a tad more verbose.
10:23
<JakeA>
tobie_: the create/get pattern is used in databases
10:23
<tobie_>
it's more commonly create/find
10:23
<tobie_>
no?
10:24
<JakeA>
tobie_: in IDB it's create/get, in mysql it's create/use
10:25
<tobie_>
oh boy, if we use IDB as an example we're doomed.
10:26
<JakeA>
I know, but just because idb is bad doesn't mean every pattern they exhibit is wrong
10:26
<tobie_>
I know. :)
10:26
<tobie_>
I'm used to seing get/set get/post/put/delete create/find create/select but create/get, not so much, tbh
10:27
<Ms2ger>
Everything's bad, so just throw consistency out of the window
10:27
<tobie_>
Ms2ger: honest question, what's better, consistency with a crap API or inconsistency with a Possibly better one?
10:27
<JakeA>
Anne suggested var store = new FetchStore("name"); fetchStores.add(store);
10:28
<JakeA>
fetchStores.get("name")
10:28
<JakeA>
Where fetchStores.add would throw if it already contains a store with a given name
10:28
<JakeA>
That would make Domenic happier I think.
10:29
<tobie_>
Sounds like it from his comments on the issue.
10:31
<JakeA>
I prefer fetchStores.create('name').then(store => store.add(urls))
10:31
<JakeA>
vs var store('name'); Promise.all([store.add(urls), fetchStores.add(store)]);
10:31
<JakeA>
ffs
10:31
<JakeA>
var store = new FetchStore('name'); Promise.all([store.add(urls), fetchStores.add(store)]);
10:37
<tobie_>
Yup. I can see that causing lots of issues down the line.
10:38
<tobie_>
A whole bunch of examples I saw actually forget to wait for the store to be saved to disk before moving on to the next thing.
10:44
<tobie_>
JakeA: I guess this doesn work because fetchStores.add takes multiple stores, right? fetchStores.add(new FetchStore("foo")).then(store => store.add(urls))
10:46
<JakeA>
tobie_: If .add resolves with the added store, that works
10:47
<tobie_>
Well, unless .add accepts multiple arguments, in which case... :( fetchStores.add(new FetchStore("foo")).then(stores => stores[0].add(urls))
10:48
<JakeA>
tobie_: Yeah, I don't like the "multiple args resolve to array" pattern. I'd rather be like Promise.all and take an array & resolve to an array
10:48
<JakeA>
tobie_: Which is why I changed store.add to take an array
10:48
<tobie_>
Man, I wish JS had a way to abstract collections and single items somehow
10:50
<tobie_>
JakeA: both patterns are terrible, tbh.
10:51
<tobie_>
like arr.push.apply(arr, [1, 2, 3]);
10:52
<tobie_>
Or when it works the other way round: arr.push([1]);
10:54
<tobie_>
What happens if you do fetchStores.add(store) it throws? or internally converts to fetchStores.add([store])
11:52
<JakeA>
tobie_: Here's the problem, it'll be fetchStores.add(store), but fetchStore.add([url, request, anotherRequest])
11:52
<JakeA>
tobie_: Another good reason to stay with .create IMO
11:52
<tobie_>
oh, boy.
13:13
<Domenic>
.create as sugar for construct + add is I think my preference
13:14
<Domenic>
JakeA: tobie_: ^
13:15
<JakeA>
Domenic: that could work
13:15
<Domenic>
(Still reading scrollback)
13:16
<tobie_>
JakeA brought up the fetchStores.add(item) but store.add(iterable) issue
13:17
<Domenic>
Ah yeah, seems annoying
13:18
<Domenic>
Also on reject vs. undefined, my only strong opinion was on a method names get. One named match I haven't thought too hard bit for now could go either way
13:18
<Domenic>
augh iPad typing ftl
13:19
<Domenic>
I would expect from Set that add takes a single argument
13:19
<Domenic>
but that might be false consistency
13:19
<JakeA>
Domenic: yeah, I spent the train journey in mocking up code using reject vs undefined. I'm favouring reject.
13:19
<Domenic>
in which case a name like put might be better? I dunno this is clearly a tough call.
13:20
<Domenic>
when I get in to work I promise to reply to all issues after actually thinking about them hard
13:20
<tobie_>
yeah, or push?
13:20
<Domenic>
push would take varargs, not iterable
13:20
<JakeA>
Domenic: store.add([url, request, otherRequest]) is an atomic operation, depending on fetching all those resources. It feels like that should reject on failure too.
13:21
<tobie_>
right that was for fetchStores.
13:21
<JakeA>
Domenic: But if you want to resolve with an array, that gets ugly
13:21
<Domenic>
JakeA: that definitely seems reasonable
13:21
<Domenic>
modulo naming
13:21
<Domenic>
resolving with an array is fine in ES6
13:22
<Domenic>
.then(([a, b, c]) => …)
13:22
<JakeA>
Think I still prefer "cache" based names for all this :(
13:22
<Domenic>
FFs I hope iOS 8 custom keyboards let you add a bunch of programmer punctuation to the main screen
13:23
<tobie_>
add does so much stuff, no wonder it's hard to name.
13:23
<tobie_>
store.add that is.
13:23
<Domenic>
I much prefer that style of atomicity to something complicated like IDB's transactions though
13:24
<JakeA>
tobie_: Although cache.add(["/whatever.json", "/style.css"]) feels intuitive to me, but maybe I'm in too deep
13:24
<tobie_>
well, it's really fetchAndStore
13:25
<JakeA>
true
13:25
<tobie_>
store.fetch? store.prefetch?
13:26
<tobie_>
note I would love to see if people would get more upset over fetchAndStore than brand-color
13:26
<JakeA>
"add '/style.css' to this cache" makes sense to me
13:27
<tobie_>
It took me quite a while to figure out what exactly store.add was doing by just looking at the code.
13:27
<tobie_>
Feels a bit like appcache magic to me.
13:28
<tobie_>
if you see what I mean.
13:28
<Domenic>
Is it sugar for two composable reactions (fetch and add)?
13:29
<Domenic>
If so the complexity seems ok
13:29
<Domenic>
S/reactions/operations
13:29
<tobie_>
yeah, throw in a Promise.all and it is.
13:30
<JakeA>
The bit we don't have a lower-level for is the atomic put
13:31
<JakeA>
store.put(request, response) - allowing you to add custom responses & requests
13:31
<JakeA>
Could guarantee that calls to .put within the same task are atomic, but that's getting close to idb-land
13:31
<Domenic>
Noooooo bad bad
13:32
<JakeA>
agreed
13:32
<Domenic>
addRequest, with add as sugar that takes more than one URL, request, whatever?
13:33
<tobie_>
Got to run. Will catch up on the conversation later.
13:34
<JakeA>
Domenic: it's not just sugar if nothing else handles the atomic commit
13:34
<Domenic>
addRequests then?
13:39
<JakeA>
I think we need a version of .put that takes many request & response combos. But ugh.
13:40
<JakeA>
Then we could explain .add on top of that using fetch & Promise.all
13:40
<JakeA>
Actually no
13:41
<JakeA>
because we don't have a way to do a series of deletes + puts atomically, but .add does
13:41
<JakeA>
Will let it bounce round my read over the weekend
14:37
<Domenic>
maybe something more truly low-level, e.g. .atomic({ add: [...], delete: [...] })
14:39
<TabAtkins>
+1 on making the name somehow more descriptive of the "all or nothing" semantics. I didn't get that out of .add() at all.
18:56
<Ms2ger>
gsnedders, https://i.imgur.com/6k0l9zo.jpg
19:01
<gsnedders>
Ms2ger: hah
19:02
<wilhelm>
Internet Explorer keeps Scotland safe?
20:20
<Hixie>
how big should i be making the multipage spec slices?
20:20
<Hixie>
is a megabyte ok?
20:22
<SamB>
Hixie: well, about how big do they run now?
20:25
<Hixie>
the old splitter ranged them from 15k to 650k.
20:26
<Hixie>
but imho had too many
20:26
<Hixie>
the new splitter splits them into sections from 30k to 900k, plus one outlier at 3MB.
20:27
<gsnedders>
how large is it if you just do one per top-level section?
20:29
<Domenic>
Does this mean all multipage links are going to break? :(
20:29
<gsnedders>
they all have magic that redirects based on the fragment anyway
20:29
<gsnedders>
because it's never been stable
20:30
<Domenic>
oh did not know. that's good then.
20:30
<gsnedders>
this is why you can do something really naive like http://whatwg.org/C#parsing without caring what section it lies in
20:31
<Domenic>
It would be cool to use replaceState to show a semi-canonical multipage permalink URL in the URL bar at all times
20:31
<Domenic>
like /C#fragment seems pretty good to me
20:31
<Domenic>
Change it as you scroll
20:33
<Hixie>
gsnedders: the new splitter is doing one per top-level section right now
20:34
<Hixie>
Domenic: file a bug, put "tools" in teh status whiteboard :-)
20:34
<gsnedders>
Hixie: seems more reasonable to me
20:34
<Hixie>
gsnedders: yeah, except for the 3MB one
20:34
<Hixie>
which is all the elements
20:35
<Hixie>
i guess i'll split that one up further
20:35
<Hixie>
Domenic: the multipage stuff is going to be a lot more stable because i'm hard-coding where the splits occur, and the filenames to use, in the source file itself
20:36
<Domenic>
Hixie: well, that does help.
20:48
<smaug____>
when one does var w = someotherwindow.WebSocket(); what is the entry settings object?
20:53
<Hixie>
The entry settings object is the most-recently added script settings object in the stack of script settings objects that is labeled as a candidate entry settings object.
20:54
<Hixie>
i.e. doesn't matter which Window the constructor is invoked on
20:55
<smaug____>
Hixie: right, so it is from the context of w
20:57
<Hixie>
not necessarily
20:57
<Hixie>
if w is in a function in yetanotherwindow
20:58
<Hixie>
but the script execution started in window0
20:58
<Hixie>
it would be window0, if i'm not mistaken
20:58
<Hixie>
otherwise it would be the incumbent settings object
20:58
<Hixie>
not the entry settings object
21:25
<tobie_>
Domenic, JakeA: think we should really have a straightforward way to prime the FS in case of cache miss, e.g.: https://gist.github.com/tobie/83674a1b83e1d4d3da21
21:27
<tobie_>
Basically `add` that fetches caches and returns the response object but for a unique resource (so you don't have to deal with getting an array back).
21:38
<tobie_>
Opened https://github.com/slightlyoff/ServiceWorker/issues/376 with the above.
23:39
<Hixie>
i'm about to replace the multipage copy of the spec with my version
23:39
<Hixie>
so let me know if anything breaks
23:41
<Hixie>
(i haven't yet done the cross-page dfn refs)