Closed tommedema closed 13 years ago
Also, this patch allows lazy loading of NowJS. Eg. if you have a javascript app where only at a certain stage such real time connection is needed, nowjs can be initialized when this stage is entered.
I've only taken a cursory glance but this looks pretty useful. Preserves the "magic" for simple use cases but gives more fine-tuned control for more serious developers.
I'll look at the code some more when I get the time. Thanks, Tom.
Of your 5 points
1 - I assume it was an anonymous function for a reason - why wouldn't you lazy load now if you want to lazy use it? Meaning
$.get("/nowjs/now.js", function() {
now.ready(function() {
});
});
I can see the benefit of having the code already available, I just want to know your answer.
2,3,4 - you can already do that if you load socket.io yourself (either lazily or in the page source), and putting that logic in now I don't think is a good idea (it adds complexity it /may/ be useful to someone but less than 20%, and they can achieve the same goal already). In addition, if there were 2 dependencies your changes would apply to both - would you send a pull request in the future to allow each dependency to be loaded from a different host?
5 - If socket.io has this event, cool.
IMO
AD PS. several small atomic (individual) pull requests would be easier for the project to integrate - you've suggested 3 different things which means they can't merge your pull request automatically/easily if any of those changes are not accepted.
Hi AD,
Thanks for your input.
1a. while this may seem easy using your jQuery abstraction wrapper, it's actually quite a complex task to load a script in Javascript with AJAX in a cross-browser way 1b. in the future, when now.core.disconnect is added, this also allows intermediate disconnection, for example in a staged application, which allows connecting to the server, do some work and disconnect again until another live session is needed in a later state (at which one can call now.core.init again).
2,3,4a. it doesn't really add complexity, since you only need to do this if you are having this need for a more complex initialization (at which point you cannot get around slightly more complexity) - normal users can make it auto-init like it does by default
2,3,4b. that '20%' (I believe it's more by the way) cannot achieve the same goal already, because socket.io cannot be loaded manually as this is hardcoded inside now.js - in fact, this patch does allow you to load socket.io manually
2,3,4c. at the moment there is no support for letting each dependency load from a different host, this patch does not change that. Also, that behavior would be quite rare. If you are doing advanced enough work to have multiple nodes with high availability etc., you'd generally use a CDN, and if not, still access static files from the same place that is optimized for static assets
I guess the reason I didn't make several pull requests was because all these new features (except the event) are dependent of each other. Eg., no dependencies can be set if now.js cannot be initialized manually.
Tom
1a. while this may seem easy using your jQuery abstraction wrapper, it's actually quite a complex task to load a script in Javascript with AJAX in a cross-browser way
You're saying https://github.com/Flotype/now/blob/master/lib/now.js#L418 is complex (I used jquery for brevity)
2,3,4 I'm not talking about userland code - I'm talking about the now.js source (and I think you haven't understood what the recent dependency loading changes mean)
I don't see how lazy-starting now, loading dependencies from a different host and a new socket.io event are related.
AD
Much more complex than now.core.init ;) And again, there is no use in this since now.js does not allow you to initialize socket.io by yourself, until this patch.
Apart from the event they are related, depedencies are loading during initialization. If you cannot initialize now manually, you cannot set these dependencies either. However, much more important than dependencies is the socketOptions parameter.
much more important than dependencies is the socketOptions parameter.
That change is buried among other unrelated changes.
You're right that's not possible right now. But why would you want to change that on a client by client basis (which is what you're permitting) instead of modifying how now serves that file so that the options (defined server side) are embedded in the source (an example).
AD
There's an easy answer to that, many of us do not like the way now is serving this file automatically. There are numerous reasons:
Again I don't see how any of that means now should change how it loads socket.io (in the same way as the ticket description for one of my tickets which suggested this was wrong).
right now you can load socket.io however you want, so long as you do so before loading now. Putting logic in now.js for loading socket.io from somewhere else is imo wrong - userland code does that, and now just takes care of the simplest case (making sure no matter what, that it works).
Hi AD,
I'm afraid that is simply wrong. What now.js does, is load '/socket/socket.io.js' - which will cause socket.io's selfhosting mechanics to trigger. Other than making this request, it will also start a download, waist precious loading time and bandwidth.
If you want to selfhost socket.io, you have to make sure that request is never made, only then can you efficiently host it at a location like '/lib/socket.io.js'.
Anyway, we'll see what "the others" think.
I'm afraid that is simply wrong. What now.js does, is load '/socket/socket.io.js'' - which will cause socket.io's selfhosting mechanics to trigger
now.js only tries to load socket.io at all if it's not already loaded (which was the whole point of #95, already merged to master)
@AD7six: frankly, truthy window.io
is not the 100% sign of socket.io.js loaded, and document.createElement('script')
is not 100% cross-browser script loader (if it were, we wouldn't ever need all bouquet of loaders...)
The autorun closure at the end of now.js can be really annoying, as it completely punts on the way you (as particular developer) do want your init process should run. Things settle if we have means to inhibit auto-running this closure. The idea of the patch is that simple.
@AD7six: frankly, truthy window.io is not the 100% sign of socket.io.js loaded,
Very true, but is it sufficiently correct for now.js' dependency loading logic?
and document.createElement('script') is not 100% cross-browser script loader (if it were, we wouldn't ever need all bouquet of loaders...)
So you're also saying that now.js is not 100% cross-browser compatible since that is exactly how it loads dependencies (even with this patch)?
The autorun closure at the end of now.js can be really annoying, as it completely punts on the way you (as particular developer) do want your init process should run. Things settle if we have means to inhibit auto-running this closure. The idea of the patch is that simple.
I'm personally all for an explicit init method and removing the auto-connect nature of now
AD
As NowJS tries to hide dependency on socket.io (which is imho why autorun is done), window.io
is not reserved as the very special key, and any user (presumably noobs, again, for whom autorun is done ;) ) is free to set/override it. If it happens before now.js is -loaded, we see an issue report :) I admit this is a corner case, but it does exist.
Loading deps robustly means copying code from well-known tested sources: say, jQuery. Inclusion of loader code just bloats now.js file.
Personally, I think that pages which have as the only dependency the now.js script, are rare. Most of us do need DOM sugar (jQuery, say). The fact that the page has to load >1 script already draws autorun be mostly an obstacle than a helper. Because we starting to need now.ready()
, which again must be 100% cross-browser and the wheel turns on...
NowJS's killer feature is in that it employs transparent catchall setters, which are setters and as such not 100% cross-browser so far. The shim for setterless browser is provided.
The original issue is no longer relevant as things have drastically changed since 0.6.1.
CLosing.
This is a fully backwards compatible patch which introduces 5 great improvements (if I may say so myself) to the client-side of now.js, as it is now allowing:
These changes are completely backwards compatible and do not change any current behavior or implementations.
A dev can now manually host socket.io and other dependencies, by manually initializing now.js:
This should not break any current implementations. I would consider the above approach a must for more advanced applications.
The advanced init parameters:
function(host, port, dependencies, socketOptions)
. None of these are required, as unset values will default to the previous implementations.Thus, all that needs to be done to use this more advanced approach is to set
__NOWMANUALINIT = true
before including now.js.To clarify, this still works too:
And everything will go automatic, using the server-generated now library.
Finally, it should be possible to detect a failed connection now (please check):