IRC Log Viewer » #firebreath » 2015-03-10

IRC Nick Time (GMT-7) Message
dcherman 09:03 any idea what will be required for FireWyrmJS at this point? can't help out with the C++ portion at all, but i can see if i can find some time to work on the frontend portion.
taxilian 09:03 writing good unit tests to match the spec would be awesome
writing good unit tests to match the spec would be awesome
and the basic implementation
can't talk right now, but can later
can't talk right now, but can later
taxilian 11:03 dcherman: if you want to discuss the FireWyrmJS needs (which are becoming very important very quickly) I'm around now and will be for awhile
dcherman 14:03 taxilian: hey, sorry - hard to split focus at work sometimes as i'm sure you know
taxilian 14:03 I understand completely
dcherman 14:03 where's the spec defined? i can take a look when i have time and see what i can write up
taxilian 14:03 https://github.com/firebreath/FireBreath/blob/refactor/src/FireWyrm/FireWyrm.h
and we've already started the project here: https://github.com/gradecam/firewyrm-js
it's not very far along, but some foundation is there
it's not very far along, but some foundation is there
basically what we need to do is have an object that is created with a WyrmHole (which is the transport mechanism) which will act as the adapter to provide an interface to a consumer
for example: var plugin = FWjs.create('application/x-someplugin')
actually it would be var pluginDfd
which should be a promise to the root object
to get the root object it should connect through the wyrmhole (TBD how that is set), send a New command and get the spawn id, then send the Enum command for object id 0
it should then construct an object with a getter for each member defined
it should then construct an object with a getter for each member defined
tell me when you're with me again and I'll go on =]
dcherman 14:03 so application/x-plugin is the WyrmHole plugin definition? so it could be backed by whatever ( NPAPI, PNaCl, etc.. )
so it's pretty much RPC
taxilian 14:03 FireBreath plugins currently have a mimetype; I've decided to keep that because you can use it to support multiple plugins in one binary
dcherman 14:03 and you're doing something remotely like "new MyPluginThing()" and returning a handle/identifier back to the frontend?
taxilian 14:03 my goal is to have a loader that can be installed and will load any FireBreath 2 plugin
my goal is to have a loader that can be installed and will load any FireBreath 2 plugin
kinda
are you familiar with Promises?
jQuery Deferred object, Promises/A+ spec, ...?
dcherman 14:03 i do training lectures on them, so i hope so =P
taxilian 14:03 excellent
http://slides.com/taxilian/promises#/ is from my presentation on them last year... doing another this year
so in FB2 everything is asynchronous; all methods or property getters return a promise
what is actually happening is a call is sent over the RPC mechanism (wyrmhole) to the plugin and translated back into the FireBreath plugin's JSAPI object
and I have created Deferred<T> and Promise<T> objects in C++ (pause for gasp of horror)
dcherman 14:03 i thought c++ got promises at some point? not gonna pretend to know since i've written exactly one component ever
just have seen code snippets in IRC at work
just have seen code snippets in IRC at work
taxilian 14:03 well, it kinda does
but they don't do what we need
well, it kinda does
these are single threaded, truly async
these are single threaded, truly async
and work pretty much exactly like Promises/A+ promises
I even wrote my own Promises/A+ compliant implementation that passes all the tests... harder than you'd think =] I wasn't quite happy with any of the others I found. this one is smaller than any of them for one thing
I even wrote my own Promises/A+ compliant implementation that passes all the tests... harder than you'd think =] I wasn't quite happy with any of the others I found. this one is smaller than any of them for one thing
it lives in FireBreath source code and is used in the NPAPI and ActiveX versions
in the case of FireWyrmJS, though, we're just going to create an object that matches the interface of the native plugin as close as possible
to start with we'll just support scripting
dcherman 14:03 ya i saw that, was going to make a minor PR to it but haven't gotten around to it
ya i saw that, was going to make a minor PR to it but haven't gotten around to it
taxilian 14:03 that spec shows the messages that are passed so you can get an idea of what you're working with
whats that?
dcherman 14:03 just a couple lines of cleanup - two functions definitions aren't needed, slightly less code
taxilian 14:03 ahh
dcherman 14:03 not actually fixing anything which is why i was pretty much meh
taxilian 14:03 yeah, didn't claim it's perfect =]
yeah, didn't claim it's perfect =]
dcherman 14:03 since most people don't like those kind of PRs
taxilian 14:03 I'm not too worried about the details at this point; I'd probably accept it, but not super concerned
if two lines were the only criticisms you found that's not bad :-P
I was kinda shocked how much I had to add to meet weird little idiosyncrasies of the unit tests; for example, ".then" can only be called once on a value returned from a handler or passed into resolve. You can't check if (o.then) { o.then(....) }
I was kinda shocked how much I had to add to meet weird little idiosyncrasies of the unit tests; for example, ".then" can only be called once on a value returned from a handler or passed into resolve. You can't check if (o.then) { o.then(....) }
you have to save it in case .then is a getter...
dcherman 14:03 they have a test case that for? i'd have imagined that the getter should be idemptotent
but maybe enough people do that to warrant optimizing that case
taxilian 14:03 yep
there are somewhere close to 900 unit tests
it was nuts
it was nuts
dcherman 14:03 what's the browser support on FB 2.0 going to look like out of curiosity? just skimming the code and noticed WeakMap being used
taxilian 14:03 I'm not sure we actually need to use WeakMap, but we will need to use Ecmascript getters/setters
currently the browser we're most concerned about is Chrome to get Native Messaging; other browsers can just use the NPAPI version
the basic goal is that older browsers will use NPAPI or ActiveX, any browser that drops support for those we'll be able to find a transport such as Native Messaging which we can use with FireWyrm
the basic goal is that older browsers will use NPAPI or ActiveX, any browser that drops support for those we'll be able to find a transport such as Native Messaging which we can use with FireWyrm
does that answer your question?
does that answer your question?
dcherman 14:03 sorta - in all of those cases, whatever JS is written would need to run on all of those platforms
unless you're planning on forking it
taxilian 14:03 key thing you're missing here is that FireWyrmJS isn't needed except when using the plugin through FireWyrm
there are three plugin types now: NPAPI, ActiveX, and FireWyrm
there are three plugin types now: NPAPI, ActiveX, and FireWyrm
so on NPAPI you wouldn't even need FireWyrmJS
so on NPAPI you wouldn't even need FireWyrmJS
only FireBreathPromise and a few other small helpers
dcherman 14:03 i'm just imagining a site that supports IE8+ needing to fork their code conditionally since IE8 doesn't support ES5 getters/setters
i'm just imagining a site that supports IE8+ needing to fork their code conditionally since IE8 doesn't support ES5 getters/setters
but at this point, i'd imagine that the majority of your users aren't on browsers that old and/or terrible
but at this point, i'd imagine that the majority of your users aren't on browsers that old and/or terrible
taxilian 14:03 hmm; I see what you mean. it could throw a JS error when you load the page
There are a few ways you could deal with that, but that is an issue I hadn't considered. seems solvable, though
don't actually have to fork your page, though, just have a conditionally loaded JS file
dcherman 14:03 you'd still end up with if ( typeof FireWyrm !== 'undefined ) { // FW path } else { // NPAPI Path }
you'd still end up with if ( typeof FireWyrm !== 'undefined ) { // FW path } else { // NPAPI Path }
but maybe that's just the price they pay for supporting IE8 and below
but maybe that's just the price they pay for supporting IE8 and below
taxilian 14:03 it's actually going to be a bit more complicated than that
determining how to instantiate the plugin will require determining if the browser supports plugins or not; on FireFox we'll still want to use NPAPI at least for now
but that's the price you have to pay to get a unified plugin codebase and to keep 98% of your javascript agnostic
the 2% that won't be is the logic that loads the plugin
the 2% that won't be is the logic that loads the plugin
dcherman 14:03 sure - in firefox though, you could still use the FireWyrm abstraction since it fully supports everything you'd need
i mean userland code would need to be forked in older browsers
taxilian 14:03 you could; it wouldn't likely buy you anything, though
the interface for FireWyrm ideally will be the same as the NPAPI interface would be
dcherman 14:03 is the NPAPI interface going to be returning Promises in 2.0? so essentially no more synchronous behaviours
taxilian 14:03 yep
yep
I've spent the last 3 weeks making that work
and it works now
that will be the biggest adjustment for most people; FireBreath 2.0 is entirely asynchronous
even in C++ if you call to the page it returns a FB::Promise<variant>
even in C++ if you call to the page it returns a FB::Promise<variant>
dcherman 14:03 but anyway, you're likely to want to use FW regardless so that your app can support multiple major browsers
taxilian 14:03 however, because it's asynchronous throughout it is possible to support Native Messaging, which is asynchronous, or js-ctypes which is synchronous, or Nacl which is async, or npapi or activex which are synchronous, or some form of AJAX (assuming you made a node connector or something for the plugin) to a server, or....
true. FW is needed for any of the new types, and you'll have to conditionally exclude it on IE8 somehow
I'm not overly concerned about IE8 support though
but it should be only the inclusion issue and the instantiation that will differ; everything else should be able to be the same code
given the puzzle Chrome dropped on us with "we're dropping NPAPI" I think that's actually a pretty decent level of code reuse still
dcherman 14:03 ya, i wouldn't be concerned about IE8 personally. it's a decade old browser; if people need to support it, extra work should be expected
taxilian 14:03 agreed =]
dcherman 14:03 but anyway i wanted to tease that out of you since one of the first things i'll do when i have time is hook this up to saucelabs and get the test suite running in all supported browsers
taxilian 14:03 awesome
dcherman 14:03 obv at the moment it'll fail in nearly all of them except Firefox since no one has implemented WeakMap besides them
taxilian 14:03 while we're doing this, we kinda want to make FireWyrmJS so it can be used for other things as well... you could actually do remote calls between two browsers given some sort of websocket proxy =]
dcherman 14:03 technically chrome did, but it's behind a flag still i think
technically chrome did, but it's behind a flag still i think
taxilian 14:03 well, as I said I'm not actually sure WeakMap is needed
dcherman 14:03 yep
taxilian 14:03 so the reason it might be needed is that you can pass objects through as well
only by reference, but that means you need to hold on to some data about the object so you can get back to it
only by reference, but that means you need to hold on to some data about the object so you can get back to it
thing is I dont' think weakmap is actually needed; my coworker was thinking it was but when we were talking about it I think we decided he was overthinking something
he's planning to expand the test suite out this week to completion with the written spec
so keep me posted on what you are working on so you and he don't duplicate work
dcherman 15:03 there shouldn't be any overlap; initially before doing any real work, i'm planning on just setting up some build process stuff
linting, testing via saucelabs, etc...
taxilian 15:03 cool
I am really happy to have another set of eyes on this stuff; this is all too important for just one person to do everything and so far that's what we've had...
though I fortunately have a company behind me and coworkers to bounce ideas off of
but some things I think should be done for the framework and community but aren't really needed for work, and with the time constraints it's harder to justify those =]
dcherman 15:03 yep - you're way ahead of where i work though ( at the moment ). i'm still pushing for open source contributions where it makes sense
at the moment, there's not much of that
at the moment, there's not much of that
taxilian 15:03 I was actually hired here because they were using FireBreath for the core plugin
so that helped =]
so that helped =]
dcherman 15:03 anyway ya - i'll try to take a look at this sometime during the next few days. i'm sure once i dive into the actual code a bit i'll probably have some questions about the spec and stuff
fwiw even if you do determine that WeakMap is needed, you can accomplish what you're trying to do with a Symbol which is much more polyfillable
taxilian 15:03 Symbol?
dcherman 15:03 ya - looks like you're just trying to associate an ID with an object without publicly exposing it. Symbols can help with that ( although they aren't *truly* private )
ya - looks like you're just trying to associate an ID with an object without publicly exposing it. Symbols can help with that ( although they aren't *truly* private )
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
taxilian 15:03 actually the main intent is to associate data with an object without creating a reference to the object that would keep the object from being garbage collected
dcherman 15:03 it's already leaking since the object is never cleared from `objectIdMap`, but i'm sure this is still a WIP
taxilian 15:03 that's the point of a WeakMap; it doesn't hold a reference to the object, so if the object is cleared it clears it from the weakmap as well
what *I* want is the opposite; a map that I can store an object in indexed by a value that I can check if the object has been GC'd, but that doesn't exist anywhere
which makes memory management with FWjs more than a bit problematic; we'll have to explicitly release in many cases any object that came from the plugin
which makes memory management with FWjs more than a bit problematic; we'll have to explicitly release in many cases any object that came from the plugin
dcherman 15:03 `objectIdMap` is a normal object, not a WeakMap
`objectIdMap` is a normal object, not a WeakMap
taxilian 15:03 oh, yeah
oh, yeah
dcherman 15:03 what about following suit with postMessage and not allow pass by reference? messages are always serialized/deserialized
taxilian 15:03 I think that's one of the reasons we decided the weakmap was pointless
I think that's one of the reasons we decided the weakmap was pointless
sorry I don't have the code in front of me right now =]
dcherman 15:03 that's fine, i actually can't look right now anyway =P helping someone that's sitting with me and i gotta go in a few
taxilian 15:03 pass by reference is a must-have for a number of reasons, including the need for callbacks
however I am going to have event support in it (ha, I knew I forgot something in that spec) which should help
however I am going to have event support in it (ha, I knew I forgot something in that spec) which should help
however I am going to have event support in it (ha, I knew I forgot something in that spec) which should help
and objects go both ways; objects from the page into C++ actually aren't that hard to manage, but from C++ to the page are harder because they will have to be released
otherwise we have no way of knowing if they are still needed
it's all ... um... fun