02:02
<zewt>
oh jesus
02:02
<zewt>
now nvidia's page is doing clipboard hijacking
02:02
<zewt>
browsers just need to drop copy events and mask copies from pages, it's too abused
06:09
<annevk>
wanderview: reopened that bug
06:10
<annevk>
wanderview: "st" goes to the spec here, Hixie's idea of subdomains for everything works kind of awesome in that respect
06:47
<zcorpan>
flash update is downloaded from fpdownload.macromedia.com ... :-)
07:26
<annevk>
zewt: not providing pages those tools will have them insist on keeping Flash around :-(
09:53
<annevk>
wanderview: put the revised version up on https://wiki.whatwg.org/wiki/Storage and included some examples of how it can be used with IDB and Cache
11:09
<annevk>
Clearly I still fail at GitHub. I downloaded xml5_draft with the GitHub client and created a branch I intended to use for a pull request (also available as option in the client these days), but now it claims I have no permission... I'm guessing that means I didn't actually have permission to create the branch, but the pull request should work I think... At least, the repository seems to allow them.
11:10
<jgraham>
If you don't have permission to access the upstream you have to create a branch in your fork and make the PR from that
11:13
<annevk>
But would the PR button then create a PR on my fork or the original one?
11:13
<annevk>
The UI could do all that for me though if it knows I don't have permission... But I guess we're not quite there yet.
11:14
<jgraham>
Against the original one
11:15
<zcorpan>
trying to spec a DOMMatrixInit where you can use either .a or .m11 but throw if they are both present with different values, becomes a bit messy. maybe i should only support .m11 for the dictionary?
11:16
<zcorpan>
https://gist.github.com/anonymous/a8931b3ebac8a418ca23
11:17
<zcorpan>
to fix https://lists.w3.org/Archives/Public/public-fx/2015JanMar/0119.html
11:21
<annevk>
zcorpan: that email talks about exposing a-f and m11-m44, but more interesting is what internal slots it has I think
11:22
<annevk>
zcorpan: but I guess you might still want to initialize from a-f since it's more convenient
11:22
<zcorpan>
annevk: internal slots is m11-m44
11:22
<zcorpan>
annevk: yeah, that my thinking too
11:23
<zcorpan>
just needs more work for the impl
11:23
<annevk>
zcorpan: https://dom.spec.whatwg.org/#dom-mutationobserver-observe does a bunch of defaulting and throwing as well...
11:24
<annevk>
zcorpan: initialization of an object is not where impl cost is though
11:24
<annevk>
zcorpan: it's somewhat meticulous work, but not exactly hard
11:24
<zcorpan>
annevk: thx
13:15
<zewt>
annevk: and i flashblock by default ... not sure i buy the logic that we should give sites the tools to be obnoxious so they use our thing to be obnoxious instead of flash, heh
13:17
<annevk>
zewt: a lot of the sites that use it do it because users actually want that functionality as I understand it
13:17
<annevk>
zewt: I agree that UAs should offer the ability to block clipboard access
13:18
<zewt>
if I select text and copy it, it should copy what i told it to and not add freaking ads to the end
13:19
<zewt>
even browser vendors don't always seem to understand that (address bar copying in firefox is a nightmare)
13:19
<annevk>
No disagreement there. I'm thinking about YouTube click-to-copy a link, and similar features elsewhere
13:20
<zewt>
the main annoying case is that pages can intercept when I copy selected text
13:22
<zewt>
(which I know is hard to completely prevent, but it's been made easier rather than harder lately iirc)
13:22
<annevk>
I think Firefox offers options to disable that kind of prevention entirely
13:24
<zewt>
i see dom.event.clipboardevents.enabled, but that seems like too big of a hammer
13:42
<annevk>
SimonSapin: what does https://github.com/servo/rust-url/blob/master/src/format.rs#L65 mean?
13:43
<SimonSapin>
annevk: it’s https://url.spec.whatwg.org/#url-serializing with the "exclude fragment flag"
13:44
<annevk>
SimonSapin: ah okay
13:44
<annevk>
SimonSapin: I thought it was talking about URLs which can't have a fragment
13:44
<annevk>
(which don't exist)
13:44
<SimonSapin>
ok
13:47
<annevk>
SimonSapin: if a Rust function lacks an explicit return, is the last line returned?
13:47
<annevk>
SimonSapin: well, last expression looks like
13:47
<SimonSapin>
the last expression, if it doesn’t end with ;
13:47
<SimonSapin>
`if` and `match` are expressions
13:48
<annevk>
Because if it ends with ; I guess the last expression is empty?
13:48
<SimonSapin>
right
13:49
<SimonSapin>
; can be viewed as a separator rather than a terminator
13:49
<annevk>
I'm trying to figure out how to best approach this parser rewrite in a way that also allows me to tackle the issue of handling URLs such as test://relative/something better...
13:49
<SimonSapin>
and the empty expression has type (), the empty tuple aka unit type
13:49
<annevk>
But perhaps rewriting it as functional first and then tackling that would be better
13:50
<SimonSapin>
annevk: that sounds mostly orthogonal
13:50
<SimonSapin>
as in, test://relative/something involves figuring out the data model, independently of the algorithm style
13:50
<annevk>
SimonSapin: maybe, would be nice to have all the facts upfront :-)
13:51
<SimonSapin>
changing fewer things at a time may also be easier both to do and to review
13:53
<annevk>
Yeah, that's certainly true
13:59
<annevk>
SimonSapin: such an interop drama that data model
13:59
<annevk>
SimonSapin: Chrome does resolve x against test://test/test "correctly", but reports a pathname of "//test/x"
14:00
<annevk>
Safari splits it out in host and path
15:45
<wanderview>
annevk: should we maintain the "simple v1" option next to this more complex option?
15:46
<annevk>
wanderview: v1 would be to do less, but nothing that is incompatible I guess
15:46
<annevk>
wanderview: afaict we can ship most of the methods independently
15:46
<wanderview>
annevk: hmm... ok... I guess I just don't want the simple proposal to get caught up in bikeshedding the bigger proposal
15:47
<annevk>
wanderview: what would you consider a reasonable v1? I could add a "Rollout" section that discusses this
15:47
<annevk>
wanderview: v1: these methods; v2: the rest
15:48
<annevk>
wanderview: or do you think we need to present it differently?
15:48
<wanderview>
annevk: I think that would be reasonable... what you had for v1 before?
15:48
<annevk>
wanderview: so everything but boxes?
15:49
<wanderview>
annevk: yea, I think so
15:53
<annevk>
wanderview: https://wiki.whatwg.org/wiki/Storage#Rollout
17:04
<wanderview>
Domenic: annevk: does this address the concerns from yesterday? https://github.com/yutakahirano/fetch-with-streams/issues/30#issuecomment-90647469
17:05
<wanderview>
I think it effectively lets fetch steal the body from the original Request as it does today
17:09
<annevk>
wanderview: you probably want to propose it without the shorthand syntax, or does that enable something that is lost on me?
17:10
<wanderview>
annevk: you mean without Request.pipeTo()? That is what enables Domenic's approach to see the consumer WritableStream directly
17:10
<wanderview>
its a rename of what we were calling setWriter()
17:12
<wanderview>
annevk: Domenic: I guess the thing I don't know how to handle with the WritableStream revealer function is a tee() or clone() done by fetch in order to handle redirects
17:14
<Domenic>
I haven't had time to read much before heading to lunch but I'll just say that largely the point of separating stream and reader was so we could have this tiered high level/low level access. Building in a third tier seems quite bad from that perspective. Everything body-related should be on the res.body stream.
17:15
<Domenic>
Alternately we could give up on separating the "response" and "response body" concepts and make Response subclass Readable(Byte)Stream
17:16
<wanderview>
Domenic: but... you're explicitly asking for something to bypass a body ReadableStream so you can see the consumer WritableStream directly...
17:16
<Domenic>
But anyway more after lunch
17:16
<wanderview>
Domenic: we don't have to call it pipeTo()... I just thought that accurately described the semantics we talked about yesterday... provide a WritableStream sink and begin pushing data there
17:16
<wanderview>
bye
17:25
<jgraham>
Anyone remember jsbell's GH handle?
17:25
<jgraham>
Oh found it
17:26
<jgraham>
In related news: https://critic.hoppipolla.co.uk/r/4569
17:26
<jgraham>
wanderview: ^
17:28
<wanderview>
jgraham: awesome!
17:34
<annevk>
wanderview: I guess I'll bow out until you guys find something
17:34
<annevk>
I think I share tyoshino's ideas
18:22
<wanderview>
annevk: I'm not sure where my idea conflicts with his... other than trying to do his "operations" ReadableStream idea... but I'm not sure how a wrapper really helps us here
18:25
<annevk>
I wonder where JakeA is
18:25
<annevk>
wanderview: dunno
18:26
<annevk>
wanderview: what do you think of the formalizing of boxes I did? Was that what you had in mind?
18:26
<annevk>
wanderview: I also added the examples you asked for how it would work with IDB and Cache
18:30
<wanderview>
annevk: oh... I started to look at that and then got side-tracked... just a sec
18:33
<wanderview>
annevk: hmm... would it be too magical if the name of a Cache or IDB matches a box name... then it is a box?
18:33
<wanderview>
I guess that would prevent multiple Cache object and IDBs in a single box
18:34
<wanderview>
annevk: did you consider an API like StorageBox.add(caches.open("myCache")) ?
18:35
<wanderview>
or StorageBox.add(indexedDB.open("myDB"))
18:36
<wanderview>
I guess it depends on if we want to be able to move a DB or Cache into a box or not... and if we want to support that from an implementation side
19:19
<TabAtkins>
Domenic: There's a `bikeshed debug --print-exports` command that lists exported vs non-exported terms. Note that only "dfn" type definition are unexported by default - all the rest automatically export unless you explicitly tell them not to.
19:25
<Domenic>
TabAtkins: do you think it would be useful to have the index section mark exported items somehow?
19:25
<Domenic>
maybe it already adds a class and we just need to style it...
19:26
<TabAtkins>
Domenic: That's not useful information for a spec reader, so no. I've wanted to expose that more naturally for bikeshed users, but haven't given it enough thought to figure it out.
19:27
<Domenic>
It seems useful information for anyone writing a spec based on yours
19:34
<annevk>
wanderview: the name matching seems too magical, .add() seems somewhat nice
19:34
<annevk>
wanderview: although it requires overloading of sorts on the boxes rather than the other APIs supporting boxes...
19:35
<Domenic>
wanderview: now that i read your thing it feels like it's just renaming .setWriter to .pipeTo, so I am less scared.
19:35
<annevk>
wanderview: but yeah, should probably tweak that
19:35
<annevk>
TabAtkins: any closer to a DOM PR?
19:35
<annevk>
TabAtkins: btw, if it could become a single commit in the end that'd be great
19:35
<TabAtkins>
annevk: I'm like 1 hour of work away. I was just on vacation without internet for a week.
19:35
<annevk>
TabAtkins: that'd avoid spamming Twitter a bunch
19:35
<TabAtkins>
And yeah, no problem squishing the commits.
19:36
<annevk>
TabAtkins: ah hope you had a blast
19:36
<TabAtkins>
I did!
19:36
<TabAtkins>
BOARD GAME CRUISE THROUGH THE CARIBBEAN
19:37
<annevk>
That's a thing? Haha nice
19:37
<jamesr___>
TabAtkins: i forgot to ask - did you play puerto rico?
19:38
<TabAtkins>
jamesr___: No, it wasn't brought on board I think.
19:38
<terinjokes>
i'm now interested in knowing what board games were played
19:42
<TabAtkins>
terinjokes: Tons. There were about 300 on board, chosen by the ~150 people registered for the con. (It was a normal cruise ship, so the other 5k people on board were just normal cruise people.)
19:42
<TabAtkins>
I played, let's see...
19:43
<TabAtkins>
Pandemic: The Cure, Patchwork, Roll For The Galaxy, Caverna, Royals, Mysterium, Lords of Waterdeep, Castles of Burgundy, Far Space Foundry, Fleet, Xia, Key Market, Onirim, Abluxxan, and Istanbul.
19:43
<TabAtkins>
(I wrote down all of them.)
19:46
<terinjokes>
wow. i think of those I've only ever played Pandemic
19:47
<TabAtkins>
terinjokes: Note that Pandemic: The Cure is a fast dice-based version of Pandemic.
19:47
<terinjokes>
been wanting to startup my project of doing a new game on some regular-ish time schedule. i should get back to doing that!
19:47
<terinjokes>
ah, then nope
19:47
<TabAtkins>
(Like Roll For The Galaxy is a fast dice-based version of Race For The Galaxy.)
19:48
<TabAtkins>
All of these were new to me, too, which was part of the point of the cruise. ^_^ We were scoping out a bunch of things we were interested in buying.
19:51
<terinjokes>
nice
20:00
<Krinkle>
annevk: Hm.. just ran into a fun issue with serialising our editor DOM to html. Comments.
20:00
<Krinkle>
createComment results in an invalid/unserializable DOM.
20:00
<Krinkle>
https://gist.github.com/Krinkle/1437de41481789ac6c96
20:02
<Krinkle>
We'll probably run html-escape (in addition to special entity scape for '-' so its xml compliant), and then someone decode that on the client side (using either a static map, or by parsing inside a detached <textarea> and retreiving textcontent?)
20:03
<Krinkle>
it's weird to html escape a value before passing to createComment though
20:10
<Domenic>
I'm not terribly surprised... just more in the category of mismatches between createXYZ() and the parser
20:13
<Krinkle>
Domenic: One can basically insert arbitrary HTML in there, including <script>
20:15
<Krinkle>
In our case we're not actually appending to innerHTML, that's a terrible practice
20:15
<Krinkle>
Just doing that for simplicity sake
20:15
<Krinkle>
(and destroys references etc.)
20:19
<Krinkle>
having some sort of text accessor on Comment nodes so that we can safely insert arbitrary user input into comment nodes would be useful.
20:19
<Krinkle>
And we'd have to either break createComment or create an alternate constructor.
20:25
<Ms2ger>
Some DOMs aren't serializable, that's not going to change
20:56
<Krinkle>
Ms2ger: Interesting. Any other cases you have in mind?
21:07
<TabAtkins>
Krinkle|detached: there are several ways to use DOM to create unserializable documents. It's not too strange.
21:07
<TabAtkins>
For example, you can use DOM to insert an <a> child of an <a>, or have lone <tr>s floating around the document.
21:41
<Krinkle>
TabAtkins: <a> inside <a> works fine in parsing though. Especially in XML.
21:41
<Krinkle>
It's not "allowed" but afaik works fine, no?
21:42
<Krinkle>
Ah, interesting. It cuts off
21:42
<TabAtkins>
No, "<a>foo<a>bar</a></a>" parses equivalent to "<a>foo</a><a>bar</a>".
21:42
<TabAtkins>
Yeah.
21:43
<TabAtkins>
XML doesn't have special per-element parsing rules like the HTML parser does.
21:43
<Krinkle>
Our content model ensures that doesn't happen though. We treat anchor links the same way as bold/italic/etc. as annotations instead of elements. Which apply to offsets in text nodes.
21:43
<Krinkle>
The tree is then created based on that.
21:43
<TabAtkins>
Sure, that's reasonable for an editor.
21:44
<TabAtkins>
I was just providing some examples of "the DOM can produce something unserializable".
21:44
<Krinkle>
but we visualise html comments (which some Wiki pages make heavy use of to leave info blurps to other editors) in our editor as <span>.
21:44
<Krinkle>
But ran into this issue where some editors leave comments including "--" in a regular English sentence.
21:44
<Krinkle>
and then subsequently, broke our serialisation :-/
21:45
<TabAtkins>
You can escape all - chars inside of comments, I suppose.
21:45
<TabAtkins>
No, that'll break viewing source.
21:45
<TabAtkins>
Replace them with unicode dashes. ^_^
21:45
<Krinkle>
It needs to round trip :)
21:46
<Krinkle>
downstream reports are https://phabricator.wikimedia.org/T95039 and https://phabricator.wikimedia.org/T95040
21:46
<Krinkle>
It seems we're going to be encoding & - and >
21:46
<TabAtkins>
Replace every -- with an emdash - they can only occur when the user is in your editor, so that's fine, and you can even roundtrip it by translating back. (That'd make actual em-dashes not *quite* roundtrip correctly, but hey, those are rare.)
21:47
<Krinkle>
Not rare if your user is a Wikipedian.
21:47
<Krinkle>
:P
22:38
<wanderview>
Domenic: has the performance impact of always returning a Promise from read() and write() been discussed somewhere?
22:39
<Domenic>
wanderview: yeah. promises are cheap when well-optimized, and certainly cheaper than I/O.
22:40
<wanderview>
Domenic: I guess I'm curious about how one optimizes out the object creation and the required async micro-task cost... it seems those are harder things to optimize out than say the generator object creation
22:41
<Domenic>
wanderview: yeah you don't optimize out object creation, but VMs are good at creating objects. The micro-task cost we discussed and eventually landed on the fact that most reads are going to be async anyway, so the microtask adds no extra overhead.
22:41
<wanderview>
Domenic: I mean.. I'm willing to accept Promise costs periodically... but once every 4096 bytes may be a bit much...
22:41
<wanderview>
Domenic: in the case where you have chunks buffered up... it seems like you would want to be able to get all of them synchronously, though... no?
22:42
<Domenic>
right, that was the original design with while (rs.state === "readable") { rs.read(); }
22:42
<Domenic>
(read() being sync in that case)
22:42
<wanderview>
Domenic: I vaguely remember that... what was the issue that forced the change?
22:43
<Domenic>
wanderview: a combination of wanting rs.readInto(buffer) + non-epoll streams who do their work in a threadpool or similar means you need something like async read(), or setAllocator
22:44
<wanderview>
Domenic: is ReadableByteStream or the new precise-flow-control stuff solving this by letting me say "read up to this much data before resolving"?
22:44
<Domenic>
Unclear how setAllocator would work though given that I/O is IPC though, now that I think about it
22:45
<wanderview>
Domenic: I/O doesn't have to be IPC... you can open a file descriptor in the parent and then dup(2) it to the child process... then file reads are in the child process
22:45
<Domenic>
wanderview: the intent of ReadableByteStream's read(view) is that view.byteLength is at least a hint, although I think we didn't want to make it binding...
22:45
<wanderview>
Domenic: network is probably always in the parent process behind IPC, though (because of http 1.1 channels multiplexed on same socket, etc)
22:45
<Domenic>
wanderview: ah OK, just was thinking of the other day when you were talking about IPC costs...
22:46
<Domenic>
my vision of read(view) was that you'd pass that view pretty directly to read(2)
22:46
<Domenic>
so for socket streams you might get back less than view.byteLength
22:46
<Domenic>
but for file streams, unless you're at end of file, you'll probably get view fully filled
22:47
<Domenic>
IIRC read(2) has an option to not return until the buffer is filled ... but it doesn't work with nonblocking sockets?
22:47
<Domenic>
Ah no, it's recv(2). MSG_WAITALL
22:49
<Domenic>
we could make the implementation concatenate buffers i guess? or let that be an option!? i don't see any reason why it's impossible, I was just going for the more direct mapping
22:50
<Domenic>
it's a latency vs. efficiency thing i guess, which perhaps is best to leave to applications to decide?
22:51
<wanderview>
sorry, on phone
22:51
<Domenic>
np
22:51
<Domenic>
reminds me of this issue https://github.com/whatwg/streams/issues/171
22:54
<Domenic>
It is true in general that browser promise impls are wildly unoptimized. User-land versions regularly achieve 4x performance and 1/4th the memory consumption, and they don't even have access to all the tricks browsers do (like skipping the microtask queue if calling in from C++)
22:54
<wanderview>
Domenic: I wonder if we could do something like .read(numDesiredChunks)
22:55
<wanderview>
and the promise resolves when that many are available
22:55
<Domenic>
wanderview: that seems pretty reasonable. Would kind of want to see data that this was a bottleneck, or a non-performance use case, before doing so.
22:56
<Domenic>
I'll file an issue to track to see if anyone has non-perf use cases
22:56
<wanderview>
Domenic: it seems more appropriate for ReadableByteStream... but might be usable in ReadableStream
22:57
<Domenic>
wanderview: maybe for RBS it's .read(view, { waitUntilFull: true })
22:57
<wanderview>
Domenic: thinking of when you are reading some framed protocol... you probably don't want to get woken up until the next frame is completely there
22:57
<wanderview>
Domenic: I don't think c++ can skip the microtask, can it? I mean.. it seems like it risks accidentally breaking the micro task guarantee in your API
22:59
<Domenic>
wanderview: it's hard to say precisely what I mean here as the area is so complicated. But the main idea is that C++ always enters back into JS from a clean stack, and that's what microtasks guarantee: a clean stack. One way of seeing this is that the very first thing done after transitioning from C++ to JS is to exhaust the microtask queue. So the very
22:59
<Domenic>
first thing that happens on the JS side, after doing resolve_promise_from_cpp(cpp_p, cpp_v), is calling p's onFulfilled handler with v
23:00
<Domenic>
IIUC SpiderMonkey doesn't actually implement a microtask queue and just uses their task queue, so maybe it is not so efficient in SpiderMonkey.
23:02
<wanderview>
Domenic: right... but its still an async runnable even if it skips to the head of the (micro)task queue
23:02
<othermaciej>
the spec says to drain the microtask queue between every regular task queue item
23:02
<othermaciej>
(if I read it correctly)
23:03
<wanderview>
and I guess unwinding and rewinding the stack has noticeable perf impacts when done in too tight a loop
23:03
<othermaciej>
and after completing execution of a <script> element
23:03
<othermaciej>
I don’t believe it says to do anything on entry from C++ to JS
23:04
<othermaciej>
it might be you can do it like that and have no observable behavior difference but it is not obvious how offhand
23:05
<othermaciej>
in particular, you can exit JS to C++ and re-enter JS sometimes without having performed microtasks
23:05
<Domenic>
othermaciej: hmm, maybe i am confused. But that was my interpretation of the spec, modulo the spec not having any "entry from C++ to JS" concept.
23:05
<Domenic>
Oh, that makes sense
23:05
<othermaciej>
this will occur if you have multiple event handlers for the same event, for instance
23:05
<Domenic>
Or just arr.forEach(cb), where hypothetically forEach is implemented in C++.
23:06
<othermaciej>
the spec is closer to saying that microtasks are run on *exit* from JS to C++, except only if you are on a “clean stack”
23:06
<othermaciej>
where “clean” == in the top level event loop or in the html parser
23:06
<othermaciej>
and also it sometimes drains the queue on times you didn’t just exit from JS, in case right when you exited, you did not have a clean stack
23:07
<othermaciej>
that is how I understand it anyway
23:08
<Domenic>
I guess the point I was really trying to make was: in Node.js, if you do `fs.readFile(..., result => resolvePromise(p, result))`, resolvePromise has to actually schedule a microtask to ensure p's handlers are called with a clean stack. So we wait for all the rest of the JS in that event loop turn to run, then unwind the stack, then run the microtask queue,
23:08
<Domenic>
with several (perf-impacting) C++-to-JS transitions. Whereas in browsers, you don't have to pay that cost.
23:09
<Domenic>
JS environments which try to completely control the event queue, like Angular, do similar optimizations
23:10
<Domenic>
where they technically run their promise handlers "sync" but if you're programming correctly-according-to-Angular, it's unobservable.
23:25
<wanderview>
Domenic: are you trying to add an interface contract definition for ReadableStream and WritableStream in this issue? https://github.com/whatwg/streams/issues/312
23:26
<Domenic>
wanderview: that thread has lost me a bit tbh...
23:26
<wanderview>
Domenic: I think it would be really helpful to have definitions of ReadableStream and WritableStream separate from the default implementation adapting JS functions
23:28
<Domenic>
wanderview: all ReadableStream instances must necessarily adapt JS functions (or JS manifestations of C++ functions)... other things obeying the "readable stream contract" might work differently though
23:28
<Domenic>
the necessity is because myFetchReadableStream.read === myFileReadableStream.read, if both variables are ReadableStreams.
23:29
<wanderview>
Domenic: so a DOM created ReadableStream representing some C++ implementation like a file stream has to be created through the ReadableStream Constructor?
23:29
<wanderview>
Domenic: why is myFetchReadableStream.read === myFileReadableStream.read a necessity?
23:29
<Domenic>
wanderview: I mean, it has to obey the observable invariants; if there are tricks you have for getting around that, use them, but...
23:30
<Domenic>
wanderview: if they are both ReadableStreams then they have the same prototype and thus the same method
23:30
<Domenic>
wanderview: if one is a FetchReadableStream and another is a FileReadableStream then yeah they can be different
23:30
<Domenic>
wanderview: analogy---promises
23:30
<Domenic>
wanderview: all C++-created promises are, at least in V8/Blink, created "via the Promise constructor"
23:30
<wanderview>
Domenic: I guess what I am saying is, it would be nice if the spec defined the observable invariants instead of making me try to dig them out of a pile of js
23:31
<Domenic>
even though the promises will be backed by very different behavior
23:31
<Domenic>
yeah, agreed on that. We want that anyway so we can say---or better, programatically test---that ReadableByteStream behaves the same as ReadableStream.
23:31
<Domenic>
the templated tests are a start
23:35
<wanderview>
Domenic: so you are saying you want JS-created ReadableStream objects to have exactly the same prototype as DOM API created ReadableStream objects?
23:36
<Domenic>
wanderview: yeah, exactly, just like Promise.
23:36
<wanderview>
Domenic: pretend I don't know much about Promise :-)
23:37
<Domenic>
hmm, well, then, yes. The underlying source is meant to provide the customization hooks
23:37
<Domenic>
The underlying source could be a JS facade over a C++ object, for sure
23:37
<wanderview>
Domenic: I guess then it would be nice to have a source interface definition... and separate out the js-adapter specifics into a separate implementation of that interface
23:38
<Domenic>
hmm what's a "source interface definition"?
23:38
<wanderview>
Domenic: the underlying source
23:38
<Domenic>
https://streams.spec.whatwg.org/#rs-constructor kind of tries
23:38
<Domenic>
what are js-adapter specifics? there are no implementations of the underlying source interface in the streams spec
23:39
<Domenic>
fetch-with-streams has one
23:39
<wanderview>
Domenic: nm... I don't think what I asked makes sense
23:40
<wanderview>
Domenic: do you anticipate things like ReadableStream.pipeTo() operating on the public ws.write() method? so allowing monkey patching
23:41
<wanderview>
the current text pointing at the ref implementation suggests it does
23:41
<Domenic>
An implementation could always do something like ReadableStream.prototype.read = function () { switch (this@[[hiddenType]]) { case "user-created": return userCreatedImpl(this); case "fetch": return fetchStreamImpl(this); } }; where user-created follows more or less the exact spec algorithm and fetchStreamImpl manages to maintain all its observable invariants
23:41
<Domenic>
but is implemented differently.
23:42
<Domenic>
Then we have to tease out what the observable invariants are. I guess maybe that's what you're asking for.
23:42
<wanderview>
Domenic: I'm asking about monkey-patching .write in this case
23:42
<Domenic>
sorry I was still on the previous subject
23:42
<wanderview>
but I guess .read is the same
23:43
<wanderview>
Domenic: I think the "underlying source" model maps reasonably well to the DOM idiom of having an "inner object"
23:43
<Domenic>
hmm interesting
23:43
<wanderview>
but I guess DOM APIs typically operate explicitly on the inner objects... not on the public APIs
23:43
<Domenic>
Ah interesting
23:43
<wanderview>
so rs.pipe(ws) would do something like "write data to ws's underlying sink" instead of calling ws.write()
23:44
<Domenic>
regarding monkey-patching write and pipeTo... I'm a bit torn on how to handle this. I've probably given up on it using `this.read()` etc.; it can use tamper-proof versions for operating on `this` to reduce complexity. But it seems quite important to allow polymorphic dispatch on the *argument*.
23:44
<wanderview>
Domenic: the polymorphism is achieved in this spec by swapping out the underlying sink, no?
23:44
<Domenic>
That said as we went through in some thread a while ago it's hard to make that work while still allowing unobservable off-main-thread piping
23:45
<Domenic>
wanderview: heh, I guess that is where my argument leads...
23:45
<Domenic>
wanderview: my hope was that you could create structurally similar writable streams that obey the same contract without being exactly WritableStreams
23:45
<wanderview>
Domenic: going to the inner objects is nice for DOM people like me... but I wonder if its not very javascripty
23:45
<Domenic>
Yeah, it's definitely not very JavaScriptey. But neither is off-main-thread piping :P
23:45
<wanderview>
Domenic: that seems at odds with requiring prototypes to be exact matches
23:46
<Domenic>
wanderview: nothing requires the prototypes to be exact matches, I was just saying, if they are, then they need to be the same impl
23:46
<wanderview>
Domenic: if you want pure duck types then I don't think we should require exact prototype matches
23:46
<Domenic>
wanderview: you *could* have separate FetchReadableStream that is written from scratch in its own spec and doesn't reference the stream spec at all, except trying to be duck-compatible.
23:46
<Domenic>
But that seems like a waste of effort.
23:46
<wanderview>
Domenic: like... I think the JS adapter stuff should be in a JSReadableStream that chains from ReadableStream, etc
23:47
<Domenic>
Anyway, my hope might be silly, is where I was going with that.
23:47
<wanderview>
and there is no spec'd concrete implementation of ReadableStream
23:47
<Domenic>
This just feels very silly when you go back to the promise analogy
23:48
<Domenic>
We don't have every promise-returning API on the web platform creating their own version of the Promise class just so they can get different backing behavior
23:48
<wanderview>
Domenic: I don't think we have the optimization concerns with off-main-thread piping, etc, with Promises that we do here...
23:48
<wanderview>
something has to give here :-) I don't think all these requirements are compatible
23:49
<Domenic>
I am leaning toward abandoning duck-compatibility for writable streams
23:49
<wanderview>
Domenic: what about for ReadableStreams?
23:50
<Domenic>
wanderview: unsure, nothing accepts them right now (except their own methods, and JS functions which will operate on a duck level)
23:50
<wanderview>
Domenic: but their own methods will operate directly on underlying source?
23:50
<Domenic>
wanderview: yeah, definitely.
23:51
<wanderview>
Domenic: is there an existing issue for this or shall I write a new one?
23:51
<Domenic>
wanderview: well, I was for a while planning on making pipeTo operate in terms of this.read() and friends, but after doing TeeReadableStream I am leaning away from that.
23:51
<wanderview>
I think it was partially discussed in the transfer issue, but seems it deserves its own issue
23:51
<Domenic>
wanderview: we kind of got sidetracked in the ... web socket issue, was it? into these
23:51
<Domenic>
ah yeah
23:51
<wanderview>
Domenic: I'll write one
23:51
<Domenic>
ok cool
23:52
<Domenic>
Hmm, promises enable duck-compatibility with Promise.resolve casting .then'ables ..... that's a more sound model actually. Also a complicated one that we probably don't need to build in to the platform?
23:53
<Domenic>
It should be pretty straightforward to write a JS function duckReadableStreamToRealReadableStream
23:53
<Domenic>
Then people can use that if they need to
23:54
<wanderview>
Domenic: I do think a ReadableStream wrapper constructor would be nice... making it take a duck typed stream would be reasonably
23:54
<Domenic>
The promise-esque alternative being that we have ReadableStream.cast = duckReadableStreamToRealReadableStream and every ReadableStream-accepting API does ReadableStream.cast first (like all promise-accepting APIs do Promise.resolve first). Really unnecessary.
23:54
<Domenic>
brb cafe closing!!
23:55
wanderview
forgot he was in pacific time zone.