invisible-college / statebus

All aboard the STATEBUS!!!
117 stars 5 forks source link

ability to override default js locations; new default locations for coffeescript compiler and statebus #14

Closed tkriplean closed 8 years ago

tkriplean commented 8 years ago

There are a few interconnected changes for loading external javascripts in this pull request:

1) A statebus application can override the default location of any required library using window.scripts_to_load. One application of this functionality is to set the version of statebus.js that is loaded to a local file that you’re developing on. This aids statebus development when you’re making changes to statebus in concert with an application you’re developing. This also facilitates offline development because you can download required scripts ahead of time and point to them in your app.

2) The application can specify additional external scripts to load. For example, d3. This is pretty easy for an application to handle itself, but I’ve had a couple people already ask me how they could load external scripts to a statebus application. Because statebus_client already loads a number of javascript, I figured it would be nice to just unify the ability to override default javascript location with the ability to specify additional application-specific javascripts to load in window.scripts_to_load. The app developer then doesn't have to copy/paste the code to write some required scripts into the document.

3) I changed the default location of statebus.js from a random dropbox link to https://rawgit.com/invisible-college/statebus/master/statebus.js. This will by default serve the statebus.js file that is in our github. When we push changes to github, this file will serve the new version within a couple minutes. rawgit only caches for a short period.

4) I updated coffee-script compiler from 1.8 to 1.10 (the file is actually 20% smaller). And I put it on our considerit cloudfront cdn. So instead of serving from dropbox, it is serving from there. Karthik will be happy ;-)

Here is an example application configuration that uses some of this functionality:

<snip>

<script>
  // The statebus server we will connect to. Read by statebus_client.
  statebus_server = 'http://localhost:9375'

  // External scripts that statebus_client will load. You can also 
  // override default locations for scripts here. 
  scripts_to_load = {
    d3: 'd3.quadtree.js',
    md5: 'md5.js',
  }
  // I'm gonna use a local version of statebus.js I'm deving on
  scripts_to_load.statebus = 'considerit-data-importer/node_modules/statebus/statebus.js'
  statebus_client = "considerit-data-importer/node_modules/statebus/client.js"

  document.write( '<script src="' + statebus_client + '" charset="utf-8"><\/script>')

</script>

Note that statebus applications should probably stop using the dropbox statebus_client.js link and use https://rawgit.com/invisible-college/statebus/master/client.js instead.

tkriplean commented 8 years ago

One thing I wasn't sure about was the "full_featured" variable and whether that makes window.scripts_to_load a poor idea. See the diff.

karth295 commented 8 years ago

I like the fact that the starter app explicitly defines save/fetch to be the default behavior, rather than it being magical. I'm also not a huge fan of things like user and connection being magical keys.

It would be cool if user and connection were mixins that you add to your bus, so that it's clear where those are coming from.

+1 no dropbox!

tkriplean commented 8 years ago

I accidentally committed the sample statebus app into this pull request...it is now committed in master. This pull request is about the external scripts stuff :-)

toomim commented 8 years ago

Note that statebus applications should probably stop using the dropbox statebus_client.js link and use https://rawgit.com/invisible-college/statebus/master/client.js instead.

I think they should actually use https://stateb.us/client.js. We just need to upload release files to it. I think we want to allow multiple different release versions of statebus to be used at a time, and not just force everyone onto master. We don't want to break everyone's apps when we change master.

toomim commented 8 years ago

If you add extra files to git like a demo app, we should also put it into a .npmignore (or the equivalent) so that it doesn't get pushed into the npm package, now that they are the same thing.

tkriplean commented 8 years ago

I think they should actually use https://stateb.us/client.js. We just need to upload release files to it. I think we want to allow multiple different release versions of statebus to be used at a time, and not just force everyone onto master. We don't want to break everyone's apps when we change master.

That makes sense. But I think we can do that better with rawgit. If we use rawgit for tagged versions, we don't have to bother releasing things to stateb.us. One less server to login to. We just add the tag in our git repo and point to it.

If don't default to the master branch, then we can use rawgit's cdn for serving the files, instead of the non-caching rawgit.com:

https://cdn.rawgit.com/invisible-college/statebus/3.1/client.js

tkriplean commented 8 years ago

If you add extra files to git like a demo app, we should also put it into a .npmignore (or the equivalent) so that it doesn't get pushed into the npm package, now that they are the same thing.

I was thinking it might actually be better to make the sample app a separate repo that people could clone and get working. Thoughts?

toomim commented 8 years ago

I think this code will crash with Uncaught ReferenceError if scripts_to_load has not been customized by the programmer. The proposed code should probably say window.scripts_to_load instead of just scripts_to_load.

toomim commented 8 years ago

You're proposing making this a general script-loading feature, but I don't think we want to take that on. Loading scripts involves getting them loaded in the right order to satisfy dependencies between scripts and other code. That's a complexity that statebus should not bother implementing. And it's not saving the programmer any real effort over adding a normal <script> tag.

So I don't think this should act like a general script loading mechanism. Really I think you just want to specify alternative local versions of some statebus dependencies. So let's look at why you want to do this. Instead of creating a new API that we'll have to maintain, perhaps we want to understand and solve the specific problem at hand.

The two reasons you gave are (1) hacking without internet access and (2) hacking statebus itself. These are actually both satisfied by the same feature: loading statebus code locally instead of over the internet. So how about having all statebus dependencies in the github repo, and then in the user's html file they can load them locally with <script src="file:///__path/statebus/client.js"> instead of <script src="https://stateb.us/client.js">, and then client.js can check to see whether it's been loaded locally or remotely and load its dependencies in the same way automatically?

By solving that specific problem, we create less work for the programmer and fewer APIs for us to maintain.

And in the future, we still need to find a better way to load code. I want to get code on statebus.

toomim commented 8 years ago

I think Karthik doesn't like dropbox just because his work's firewall blocks dropbox.com.

toomim commented 8 years ago

This url is long and hard to remember: https://cdn.rawgit.com/invisible-college/statebus/3.1/client.js We can make it short and memorable: https://stateb.us/client.js?3.1

Then when you make a new singlefile statebus app, you can type the whole thing by memory. That's a pretty big deal. We can still make it reference git automatically.

tkriplean commented 8 years ago

I think Karthik doesn't like dropbox just because his work's firewall blocks dropbox.com.

I also don't like dropbox because it goes down frequently. And is slow.

tkriplean commented 8 years ago

So how about having all statebus dependencies in the github repo, and then in the user's html file they can load them locally with <script src="file:///__path/statebus/client.js"> instead of <script src="https://stateb.us/client.js">, and then client.js can check to see whether it's been loaded locally or remotely and load its dependencies in the same way automatically?

Are you saying that client.js automatically loads the statebus.js file that is located in the same directory as itself? I like that.

tkriplean commented 8 years ago

Ok, what do you think of this? I removed the external script loading and detected the location of statebus.js automatically in client.js.

toomim commented 8 years ago

That looks awesome! It's so few lines. :) We'll want to do the other libs this way too. We should add them to this repo. (I don't think we need to bother with .npmignore anymore btw.)