JSAN: the JavaScript Archive Network [jay-san] (becaue CJSAN is unpronouncable and nevermind that the jsan.* domains are all taken).
The goal: JavaScript modules for browsers with as minimal a build/install system as possible.
The trick: Minimize the need for an @INC or build system by using the browser's existing capabilities.
include():
jsan.js gives you an include() function similar to what Torgo's bootstrap.js is doing, it just relies on the browser's own "script" tag. This include function does what you'd expect and a little more. It looks in some sensible local locations for the file, the URL the HTML file is in (./js/foo.js) and the document root (/js/foo.js). The exact locations searched for could be configurable in something like /js/jsan/inc.js. This is your basic include functionality.
use(): Now the fun begins. Notice how its /js/jsan/use.js?
use() is a little different than include(). Initially its similar to include("js/bar/use.js") and works the same way. Now you have "modules" in the sense of "a pile of related JavaScript files in one directory with a central load point and an INC path". But the INC path goes a little further. What if you don't have 'bar' installed? Then it tries http://www.jsan.org/use/bar/use.js.
[evil grin]
remote libraries: If I want to distribute something which depends on other modules you don't have to install those dependencies to use it! My code says "use('something')" and it gets loaded from the net if necessary. If you want to install the dependencies locally, you can. You don't even need to install anything, you can just reference JSAN directly. Fantastic for rapid prototyping.
It even can use the browser's cache to your advantage. If JSAN becomes popular and a lot of sites start using JSAN modules pulled directly from JSAN the browser's cache means those files are only downloaded once for all the sites which use it. If the browser has a JavaScript JIT then even better!
To avoid jsan.org being a central point of failure, even with mirrors and round-robin DNS, a set of mirrors would be built into /js/jsan/inc.js in case jsan.org failed. And if you don't trust jsan.org you can always just pull the files onto your local server.
versioning: Ovid's the one who figured all this out. Local versioning is a little problematic, but remote versioning is a snap. Watch.
That's shorthand for use("wibble", "> 13") like Perl does. So what happens? Let's start with remote versioning, that's easier. Its very simple. It just loads "http://jsan.org/use/bar?version=13" and lets JSAN deliver you the right file. This kicks the verisoning logic out of JavaScript and onto the JSAN server which is better equiped to do it, its not even worth discussion at this point how jsan.org implements that. Then you can have whatever complex versioning spec you like including things like "== 13" (version 13 and only 13) and "13..20" (versions 13 through 20).
Versioning on the local filesystem is a bit harder, and you'll see why an integer versioning system is used. Going with an only.pm installation style where modules get installed as module-version/ so wibble-13/. How do you find the latest version of something when you can't ls? You also don't want to have to load a module just to find out its the wrong version, you want to continue down the INC path.
Here's the best I've got at the moment. When you install a JSAN module it goes into a module-version/ directory. It also writes/adds to module/manifest.js which is just a list of what versions of the module are installed. Essentially a hard-coded ls. use() can then employ that list to figure out if the right version is installed or if it has to look further up the INC path.
The problem with that is it makes installing a JSAN module more than simply unpacking a tarball or zip file. I'd rather not have a build system at all, introduces cross-platform scripting nightmares.
One thought is that, largely, this versioning stuff is YAGNI particularly having multiple installed versions of the same module and modules which need a particular version. So perhaps each module would have a simple version.js file which jsan can load and examine to get the version without having to load the whole module. Then you can just install as module/ (ie. no version in the directory name) and go. Those few who really want multiple versions installed can do the module-version/ and module/manifest.js scheme which requires extra build/install magic.
I've done some tests with this last year, and couldn't resolve the timing issues. At least in IE the script src is loaded asynchronously and you end up calling functions which aren't loaded yet most of the time.
However, the XMLHTTPRequest object has the option to load data synchronously, so you can actually wait untill the data is loaded. The problem is that it isn't meant to load javascript files, but with some eval() magic it does work.
I've put a first version up at http://helene.muze.nl/download/jsan.zip/.
Re:Remote scripting won't work
sungo on 2005-06-11T17:19:58
perhaps jsan.js can be signed. then jsan could potentially load remote content.
http://www.mozilla.org/projects/security/components/jssec.html
JavaScript Archive Network
JSAN JavaScript Code Importing System